Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
402
sdk/app/walkie-talkie/h264_enc_dec.c
Normal file
402
sdk/app/walkie-talkie/h264_enc_dec.c
Normal file
@@ -0,0 +1,402 @@
|
||||
#include "sys_config.h"
|
||||
#include "tx_platform.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal_file.h"
|
||||
#include "lib/net/eloop/eloop.h"
|
||||
#include "video_app/video_app.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "netif/ethernetif.h"
|
||||
#include "utlist.h"
|
||||
#include "jpgdef.h"
|
||||
#include "lib/lcd/lcd.h"
|
||||
#include "lib/common/sysevt.h"
|
||||
#include "syscfg.h"
|
||||
#include "lib/video/dvp/jpeg/jpg.h"
|
||||
#include "walkie_talkie.h"
|
||||
#include "stream_define.h"
|
||||
#include "lib/multimedia/msi.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "lib/umac/ieee80211.h"
|
||||
#include "lib/video/h264/h264_drv.h"
|
||||
#include "scale_msi/scale_msi.h"
|
||||
|
||||
#ifdef SYS_APP_WALKIE_TALKIE
|
||||
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
#define MAX_USER_VIDEO_TX 16
|
||||
extern volatile uint8_t *psram_user_ptr;
|
||||
|
||||
walkie_msg walkmsg;
|
||||
|
||||
extern uint8_t set_vpp_bu1_shrink(uint16_t w, uint16_t shrink_w);
|
||||
extern int change_gen420dev_w_h(uint8_t devid,uint16_t w,uint16_t h);
|
||||
|
||||
static int net_video_msi_action(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2)
|
||||
{
|
||||
int ret = RET_OK;
|
||||
switch (cmd_id)
|
||||
{
|
||||
|
||||
// 暂时没有考虑释放
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
}
|
||||
break;
|
||||
// 接收,判断是否已经压缩了
|
||||
case MSI_CMD_TRANS_FB:
|
||||
{
|
||||
struct framebuff *fb = (struct framebuff *)param1;
|
||||
if(fb->stype != FSTYPE_H264_GEN420_DATA)
|
||||
{
|
||||
ret = RET_ERR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
in_addr_t send_addr = 0;
|
||||
uint8_t apsta_mode = 0; //1:ap 2:sta
|
||||
void h264_enc_dec_thread(){
|
||||
uint8_t * ptr;
|
||||
uint32_t fcnt = 0;
|
||||
uint8_t oldspeed = 0;
|
||||
uint16_t w,h;
|
||||
uint8_t dropcnt = 0;
|
||||
uint8_t runh264 = 1;
|
||||
uint8_t make_h264 = 1;
|
||||
ptr = (uint8_t *)psram_user_ptr;
|
||||
uint32_t time_debug = 0;
|
||||
uint32_t ipaddr;
|
||||
int32 isstaconnect;
|
||||
|
||||
user_protocol_task_increase();
|
||||
|
||||
os_sleep_ms(100);
|
||||
//must open SYS_WIFI_PAIR
|
||||
// sys_wifi_pair_start(sys_cfgs.wifi_mode,1); //run after pair init
|
||||
w = 320;
|
||||
h = 240;
|
||||
while(1){
|
||||
|
||||
if(walkmsg.run_state == 0) {
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
|
||||
if(ieee80211_conf_get_stacnt(WIFI_MODE_STA) == 1){
|
||||
os_printf("STA mode connect\r\n");
|
||||
do{
|
||||
if(walkmsg.run_state == 0) {
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
if(sys_cfgs.wifi_mode == WIFI_MODE_AP)
|
||||
break;
|
||||
ipaddr = lwip_netif_get_ip2("w0").addr;
|
||||
os_sleep_ms(100);
|
||||
}while((ipaddr&0xff000000) == 0x1000000);
|
||||
apsta_mode = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if(ieee80211_conf_get_stacnt(WIFI_MODE_AP) == 1){
|
||||
os_printf("AP mode connect\r\n");
|
||||
apsta_mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
os_sleep_ms(5);
|
||||
}
|
||||
|
||||
|
||||
if(apsta_mode == 2) //STA
|
||||
{
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0) {
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
// ipaddr = lwip_netif_get_ip2("w0");
|
||||
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_STA);
|
||||
|
||||
if(isstaconnect == 0){
|
||||
os_sleep_ms(5);
|
||||
}else{
|
||||
// _os_printf("ipaddr:%x sta:%d\r\n",ipaddr.addr,ieee80211_conf_get_stacnt(WIFI_MODE_STA));
|
||||
break;
|
||||
}
|
||||
}
|
||||
send_addr = NET_IP_ADDR_DEFAULT;
|
||||
user_protocol2(6001,6000);
|
||||
user_protocol3(6003,6002);
|
||||
}
|
||||
else{ //AP
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0) {
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
// ipaddr = lwip_netif_get_ip2("w0");
|
||||
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_AP);
|
||||
|
||||
if(isstaconnect == 0){
|
||||
os_sleep_ms(5);
|
||||
}else{
|
||||
// _os_printf("ipaddr:%x ap:%d\r\n",ipaddr.addr,ieee80211_conf_get_stacnt(WIFI_MODE_AP));
|
||||
break;
|
||||
}
|
||||
}
|
||||
send_addr = DHCPD_START_IP_DEFAULT;
|
||||
user_protocol2(6003,6002);
|
||||
user_protocol3(6001,6000);
|
||||
}
|
||||
|
||||
while(1){
|
||||
|
||||
if(walkmsg.run_state == 0) {
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
|
||||
if(ptr != psram_user_ptr){
|
||||
ptr = (uint8_t *)psram_user_ptr;
|
||||
fcnt++;
|
||||
|
||||
#if 0
|
||||
if(walkmsg.speed == 0){
|
||||
runh264 = 1; //全力跑
|
||||
}else if(walkmsg.speed == 1){
|
||||
runh264 = fcnt%3; //三帧丢一帧
|
||||
if(runh264 != 0){
|
||||
runh264 = 1;
|
||||
}
|
||||
}else if(walkmsg.speed == 2){
|
||||
runh264 = fcnt%2; //减半
|
||||
}else if(walkmsg.speed == 3){
|
||||
runh264 = fcnt%4; //四帧丢三帧
|
||||
if(runh264 == 0){
|
||||
runh264 = 1;
|
||||
}else{
|
||||
runh264 = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if 0
|
||||
if((fcnt%200) == 100){
|
||||
_os_printf("set QVGA.....\r\n");
|
||||
h264_reflash_new_gop(1,1);
|
||||
set_vpp_bu1_shrink(640,320);
|
||||
change_gen420dev_w_h(1,320,240);
|
||||
h264_recfg_bsp(1,200,200);
|
||||
runh264 = 0;
|
||||
dropcnt = 3;
|
||||
w = 320;
|
||||
h = 240;
|
||||
}else if((fcnt%200) == 199){
|
||||
_os_printf("set QQVGA.....\r\n");
|
||||
h264_reflash_new_gop(1,1);
|
||||
set_vpp_bu1_shrink(640,160);
|
||||
change_gen420dev_w_h(1,160,120);
|
||||
h264_recfg_bsp(1,50,50);
|
||||
runh264 = 0;
|
||||
dropcnt = 3;
|
||||
w = 160;
|
||||
h = 120;
|
||||
}
|
||||
|
||||
if(dropcnt != 0){
|
||||
dropcnt--;
|
||||
}else{
|
||||
runh264 = 1;
|
||||
}
|
||||
#else
|
||||
if(oldspeed != walkmsg.speed){
|
||||
if(walkmsg.speed == 0){ //24帧qvga
|
||||
_os_printf("set QVGA1.....\r\n");
|
||||
h264_reflash_new_gop(1,1);
|
||||
set_vpp_bu1_shrink(640,320);
|
||||
change_gen420dev_w_h(1,320,240);
|
||||
h264_recfg_bsp(1,200,200);
|
||||
h264_recfg_rate(1,25);
|
||||
h264_recfg_frm_gop(1,25);
|
||||
h264_recfg_ini_qp(1,26);
|
||||
if(w == 160){
|
||||
dropcnt = 3;
|
||||
}
|
||||
make_h264 = 1;
|
||||
w = 320;
|
||||
h = 240;
|
||||
}else if(walkmsg.speed == 1){ //12帧qvga
|
||||
_os_printf("set QVGA2.....\r\n");
|
||||
h264_reflash_new_gop(1,1);
|
||||
set_vpp_bu1_shrink(640,320);
|
||||
change_gen420dev_w_h(1,320,240);
|
||||
h264_recfg_bsp(1,150,150);
|
||||
h264_recfg_rate(1,12);
|
||||
h264_recfg_frm_gop(1,12);
|
||||
h264_recfg_ini_qp(1,31);
|
||||
if(w == 160){
|
||||
dropcnt = 3;
|
||||
}
|
||||
make_h264 = 2;
|
||||
w = 320;
|
||||
h = 240;
|
||||
}else if(walkmsg.speed == 2){ //12帧qqvga
|
||||
_os_printf("set QQVGA3.....\r\n");
|
||||
h264_reflash_new_gop(1,1);
|
||||
set_vpp_bu1_shrink(640,160);
|
||||
change_gen420dev_w_h(1,160,120);
|
||||
h264_recfg_bsp(1,100,100);
|
||||
h264_recfg_rate(1,12);
|
||||
h264_recfg_frm_gop(1,12);
|
||||
h264_recfg_ini_qp(1,31);
|
||||
if(w == 320){
|
||||
dropcnt = 3;
|
||||
}
|
||||
make_h264 = 2;
|
||||
w = 160;
|
||||
h = 120;
|
||||
}else if(walkmsg.speed == 3){ //6帧qqvga
|
||||
_os_printf("set QQVGA4.....\r\n");
|
||||
h264_reflash_new_gop(1,1);
|
||||
set_vpp_bu1_shrink(640,160);
|
||||
change_gen420dev_w_h(1,160,120);
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,31);
|
||||
if(w == 320){
|
||||
dropcnt = 3;
|
||||
}
|
||||
make_h264 = 4;
|
||||
w = 160;
|
||||
h = 120;
|
||||
}
|
||||
oldspeed = walkmsg.speed;
|
||||
}
|
||||
if(dropcnt){
|
||||
dropcnt--;
|
||||
runh264 = 0;
|
||||
}else{
|
||||
if(fcnt%make_h264 == 0){
|
||||
runh264 = 1;
|
||||
}else{
|
||||
runh264 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if(runh264 == 1){
|
||||
put_h264msg_to_queue(0,w,h,(uint32_t)ptr,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}else{
|
||||
os_sleep_ms(3);
|
||||
|
||||
if((os_jiffies() - time_debug) > 2000){
|
||||
time_debug = os_jiffies();
|
||||
os_printf("\r\nmcs:%x tx_data:%dbyte/s rx_data:%dbyte/s speed:%d txsucc:%d rxsucc:%d txlost:%d rxlost:%d\r\n",walkmsg.mcs,walkmsg.tx_data/2,walkmsg.rx_data/2,walkmsg.speed,walkmsg.frame_tx_success/2,walkmsg.frame_rx_success/2,walkmsg.frame_tx_lost/2,walkmsg.frame_rx_lost/2);
|
||||
walkmsg.tx_data = 0;
|
||||
walkmsg.rx_data = 0;
|
||||
walkmsg.frame_tx_lost = 0;
|
||||
walkmsg.frame_rx_lost = 0;
|
||||
walkmsg.frame_tx_success = 0;
|
||||
walkmsg.frame_rx_success = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void walkie_msg_init(){
|
||||
walkmsg.tx_data = 0;
|
||||
walkmsg.rx_data = 0;
|
||||
walkmsg.speed = 0;
|
||||
walkmsg.frame_tx_lost = 0;
|
||||
walkmsg.frame_rx_lost = 0;
|
||||
walkmsg.frame_tx_success = 0;
|
||||
walkmsg.frame_rx_success = 0;
|
||||
}
|
||||
|
||||
void user_protocol_task_state_init(void)
|
||||
{
|
||||
walkmsg.run_state = 1;
|
||||
walkmsg.run_task = 0;
|
||||
os_mutex_init(&walkmsg.run_state_mutex);
|
||||
}
|
||||
|
||||
void user_protocol_task_increase(void)
|
||||
{
|
||||
os_mutex_lock(&walkmsg.run_state_mutex, osWaitForever);
|
||||
walkmsg.run_task++;
|
||||
os_mutex_unlock(&walkmsg.run_state_mutex);
|
||||
}
|
||||
|
||||
void user_protocol_task_decrease(void)
|
||||
{
|
||||
os_mutex_lock(&walkmsg.run_state_mutex, osWaitForever);
|
||||
walkmsg.run_task--;
|
||||
os_mutex_unlock(&walkmsg.run_state_mutex);
|
||||
}
|
||||
|
||||
void user_protocol()
|
||||
{
|
||||
walkmsg.have_init = 1;
|
||||
struct msi *scale2 = scale2_msi("scale2", NET_W, NET_H, 320, 240, FSTYPE_YUV_P0, 10);
|
||||
if (scale2)
|
||||
{
|
||||
msi_add_output(scale2, NULL, "sim_video");
|
||||
//msi_add_output(scale2, NULL, R_VIDEO_P1);
|
||||
//os_printf("%s %d\r\n",__func__,__LINE__);
|
||||
}
|
||||
walkie_msg_init();
|
||||
// scale2_output_size_local_change(0,0,0,0,160,120);
|
||||
h264wq_queue_init(NET_W,NET_H);
|
||||
user_protocol_task_state_init();
|
||||
os_task_create("h264_enc_dec_thread", h264_enc_dec_thread, NULL, OS_TASK_PRIORITY_HIGH, 0, NULL, 1024);
|
||||
}
|
||||
|
||||
|
||||
void user_protocol_deinit(void)
|
||||
{
|
||||
walkmsg.run_state = 0;
|
||||
user_protocol2_deinit();
|
||||
user_protocol3_deinit();
|
||||
}
|
||||
|
||||
void user_protocol_reinit(void)
|
||||
{
|
||||
if(walkmsg.have_init == 0) {
|
||||
return user_protocol();
|
||||
}
|
||||
walkmsg.run_state = 1;
|
||||
os_task_create("h264_enc_dec_thread", h264_enc_dec_thread, NULL, OS_TASK_PRIORITY_HIGH, 0, NULL, 1024);
|
||||
}
|
||||
|
||||
#endif
|
||||
106
sdk/app/walkie-talkie/walkie_talkie.h
Normal file
106
sdk/app/walkie-talkie/walkie_talkie.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _PHOTO_TRAN_PROTOCOL_
|
||||
#define _PHOTO_TRAN_PROTOCOL_
|
||||
#include "osal/string.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type; //0:连接请求 1:开始图传 2:cfg
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
uint32_t packet_len; //分包长度
|
||||
uint32_t ip_grp; //IP比例,如25,则表示1个I帧,24个P帧
|
||||
uint32_t frame_rate; //帧率
|
||||
uint32_t dev_magic; //设备特征码
|
||||
}connect_cfg_head;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t framenum; //0~255,每帧+1
|
||||
uint8_t cnt; //当前包需要分多少数据包
|
||||
uint8_t pack; //当前包num
|
||||
uint8_t frmtype; //当前是I帧还是P帧
|
||||
}data_head;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t framenum; //当前帧num
|
||||
uint8_t type; //0:当前帧接收完整 1:请求屏/app发送状态msg 2:当前帧数据缺失
|
||||
}status_msg;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t time; //发送完成的时间
|
||||
uint32_t dev_magic; //设备特征码
|
||||
uint8_t framenum; //当前帧num
|
||||
uint8_t status; //0:wait client status 1:sending status to client 2:get client status 3:frame lost
|
||||
uint8_t timeout; //超时多久后发送状态请求
|
||||
uint8_t lost_num; //当前获取状态后,丢包情况
|
||||
uint8_t lost_packet[100]; //如果有丢包,分别是哪些包
|
||||
|
||||
}frame_msg;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *addr;
|
||||
uint32_t len;
|
||||
uint32_t timeinf;
|
||||
uint16_t num;
|
||||
uint16_t type;
|
||||
uint16_t devid;
|
||||
uint16_t framerate;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
}decode_msg;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ipaddr;
|
||||
uint32_t tcpfd;
|
||||
uint32_t udp_status_fd;
|
||||
uint32_t udp_data_fd;
|
||||
uint32_t udp_status_task;
|
||||
void* udp_read_status_ev;
|
||||
uint32_t udp_data_task;
|
||||
uint32_t dev_id;
|
||||
uint32_t frame_rate;
|
||||
uint8_t *psram_photo;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
}dev_map;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t tx_data;
|
||||
int32_t rx_data;
|
||||
uint8_t speed;
|
||||
uint8_t frame_tx_lost;
|
||||
uint8_t frame_tx_success;
|
||||
uint8_t frame_rx_lost;
|
||||
uint8_t frame_rx_success;
|
||||
uint8_t mcs;
|
||||
uint8_t frmtype;
|
||||
uint8_t have_init;
|
||||
uint8_t run_state;
|
||||
uint8_t run_task;
|
||||
struct os_mutex run_state_mutex;
|
||||
}walkie_msg;
|
||||
|
||||
#ifdef SYS_APP_WALKIE_TALKIE
|
||||
extern walkie_msg walkmsg;
|
||||
extern uint8_t apsta_mode;
|
||||
void user_protocol_task_decrease(void);
|
||||
void user_protocol_task_increase(void);
|
||||
void user_protocol2(uint16_t status_port,uint16_t data_port);
|
||||
void user_protocol2_deinit(void);
|
||||
void user_protocol3(uint16_t status_port,uint16_t data_port);
|
||||
void user_protocol3_deinit(void);
|
||||
void user_protocol_deinit(void);
|
||||
void user_protocol_reinit(void);
|
||||
#endif
|
||||
|
||||
#define OPEN_DBG 0
|
||||
#define MODEFORDEV 0 //0:AP 1:STA
|
||||
#define NET_W 320
|
||||
#define NET_H 240
|
||||
|
||||
#endif
|
||||
707
sdk/app/walkie-talkie/walkie_talkie_a.c
Normal file
707
sdk/app/walkie-talkie/walkie_talkie_a.c
Normal file
@@ -0,0 +1,707 @@
|
||||
/***************************************************
|
||||
该demo主要是使用AT命令拍一张照片,前提要将jpeg打开
|
||||
***************************************************/
|
||||
#include "sys_config.h"
|
||||
#include "tx_platform.h"
|
||||
#include "osal/string.h"
|
||||
#include "stream_frame.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal_file.h"
|
||||
#include "video_app/video_app.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "utlist.h"
|
||||
#include "jpgdef.h"
|
||||
#include "lib/lcd/lcd.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "netif/ethernetif.h"
|
||||
#include "lib/common/sysevt.h"
|
||||
#include "syscfg.h"
|
||||
#include <event.h>
|
||||
#include <csi_kernel.h>
|
||||
#include "lib/video/dvp/jpeg/jpg.h"
|
||||
#include "walkie_talkie.h"
|
||||
#include "stream_define.h"
|
||||
#include "lib/multimedia/msi.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "lib/video/h264/h264_drv.h"
|
||||
#include "scale_msi/scale_msi.h"
|
||||
|
||||
#ifdef SYS_APP_WALKIE_TALKIE
|
||||
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
#define MAX_VIDEO_PKT_LEN 1430
|
||||
//#define SENSOR_DEV_NUM 1
|
||||
|
||||
#if OPEN_DBG
|
||||
#define CHILDREN_DBG(fmt, ...) _os_printf(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define CHILDREN_DBG(fmt, ...) //_os_printf(fmt, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
struct os_msgqueue net_h264_msg;
|
||||
|
||||
static int handle_protocol_fd = - 1;
|
||||
static int handle_data_protocol_fd = - 1;
|
||||
|
||||
int handle_protocol_table_fd[10];
|
||||
int handle_data_protocol_table_fd[10];
|
||||
|
||||
|
||||
volatile uint32 server_frame_rate;
|
||||
|
||||
#define DEC_TABLE_NUM 32
|
||||
decode_msg decmsg[DEC_TABLE_NUM];
|
||||
|
||||
|
||||
uint32_t devnum = 0;
|
||||
dev_map devtab[10];
|
||||
frame_msg server_frame[10];
|
||||
|
||||
static uint8_t photo_buf[1440] __attribute__ ((aligned(4)));;
|
||||
uint8 psram_h264_photo[200*1024] __attribute__ ((aligned(4),section(".psram.src")));
|
||||
int frame_for_dec = 0;
|
||||
uint8_t dispnum;
|
||||
uint16_t rx_speed,tx_speed;
|
||||
extern struct msi *scale2_msi(const char *name, uint16_t iw, uint16_t ih, uint16_t ow, uint16_t oh, uint16_t type,uint8_t larger);
|
||||
void net_s_h264_sema_init()
|
||||
{
|
||||
os_msgq_init(&net_h264_msg,1);
|
||||
}
|
||||
|
||||
uint32 net_s_h264_sema_down(int32 tmo_ms, int32 *err)
|
||||
{
|
||||
uint32 retdata;
|
||||
//os_sema_down(&net_h264_sem,tmo_ms);
|
||||
retdata = os_msgq_get2(&net_h264_msg, tmo_ms, err);
|
||||
return retdata;
|
||||
}
|
||||
|
||||
void net_s_h264_sema_up(uint32 clientaddr)
|
||||
{
|
||||
os_msgq_put(&net_h264_msg, clientaddr, osWaitForever);
|
||||
}
|
||||
|
||||
void net_s_h264_sema_deinit(void)
|
||||
{
|
||||
if(net_h264_msg.hdl) {
|
||||
os_msgq_del(&net_h264_msg);
|
||||
}
|
||||
}
|
||||
|
||||
int usr_protocol_create_server(uint16_t port)
|
||||
{
|
||||
int socket_c, err;
|
||||
int32_t time_out = 10;
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_len = sizeof(struct sockaddr_in);
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = htons(INADDR_ANY);
|
||||
|
||||
socket_c = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket_c < 0)
|
||||
{
|
||||
printf("get socket err");
|
||||
return - 1;
|
||||
}
|
||||
|
||||
err = bind(socket_c, (struct sockaddr*) &addr, sizeof(struct sockaddr_in));
|
||||
|
||||
if (err == - 1)
|
||||
{
|
||||
close(socket_c);
|
||||
return - 1;
|
||||
|
||||
}
|
||||
|
||||
setsockopt(socket_c, SOL_SOCKET, SO_RCVTIMEO, &time_out, sizeof(int32_t));
|
||||
|
||||
return socket_c;
|
||||
}
|
||||
|
||||
|
||||
void udp_handle_server_status_write_workqueue(void *ei, void *d){
|
||||
struct sockaddr_in *addrServer;
|
||||
status_msg *msg_head;
|
||||
char buf[12];
|
||||
int len;
|
||||
uint8_t id;
|
||||
uint8_t fd;
|
||||
addrServer = d;
|
||||
//for(itk = 0;itk < 10;itk++){
|
||||
// if(addrServer->sin_addr.s_addr == devtab[itk].ipaddr){
|
||||
id = devtab[0].dev_id;
|
||||
fd = devtab[0].udp_status_fd;
|
||||
// }
|
||||
//}
|
||||
msg_head = (status_msg *)buf;
|
||||
msg_head->framenum = server_frame[id-1].framenum;
|
||||
msg_head->type = 0;
|
||||
//len = sendto(fd, (char*)buf, 2, MSG_DONTWAIT, (struct sockaddr *)d, sizeof(struct sockaddr));
|
||||
len = sendto(handle_protocol_fd, (char*)buf, 2, MSG_DONTWAIT, (struct sockaddr *)d, sizeof(struct sockaddr));
|
||||
}
|
||||
|
||||
static void udp_handle_server_status_read_workqueue(void *ei, uint32_t *status_fd){
|
||||
int retval;
|
||||
int ret;
|
||||
int tos;
|
||||
uint8_t itk;
|
||||
uint8_t handlebuf[64];
|
||||
struct sockaddr remote_addr;
|
||||
struct sockaddr_in *addrServer;
|
||||
status_msg *msg_head;
|
||||
uint8_t id;
|
||||
msg_head = (status_msg *)handlebuf;
|
||||
retval = 16;
|
||||
ret = recvfrom (*status_fd, handlebuf, 24, 0, &remote_addr, (socklen_t*)&retval);
|
||||
if(ret <= 0)
|
||||
return;
|
||||
|
||||
addrServer = (struct sockaddr_in *)&remote_addr;
|
||||
|
||||
// for(itk = 0;itk < 10;itk++){
|
||||
// if(addrServer->sin_addr.s_addr == devtab[itk].ipaddr){
|
||||
// id = devtab[itk].dev_id;
|
||||
// }
|
||||
// }
|
||||
id = 1;
|
||||
if((id == 0)||(id > 3)) //当前设备号不存在,先只支持三台设备
|
||||
{
|
||||
CHILDREN_DBG(" status no this client dev....");
|
||||
return;
|
||||
}
|
||||
|
||||
id = id-1; //设备号是从1开始计算,这里让设备号改成从0开始算
|
||||
//os_printf("client read:%02d type:%d lost_num:%d \r\n",msg_head->framenum,msg_head->type,server_frame[id-1].lost_num);
|
||||
if(server_frame[id].lost_num != 0){
|
||||
CHILDREN_DBG("L(%d %d)",id,server_frame[id].lost_num);
|
||||
}else{
|
||||
CHILDREN_DBG("R%d",id);
|
||||
}
|
||||
|
||||
if(server_frame[id].framenum != msg_head->framenum){
|
||||
CHILDREN_DBG("ag%d",id);
|
||||
return;
|
||||
}
|
||||
|
||||
if(server_frame[id].lost_num != 0){
|
||||
msg_head = (status_msg *)handlebuf;
|
||||
msg_head->framenum = server_frame[id].framenum;
|
||||
msg_head->type = 2;
|
||||
for(itk = 0;itk < server_frame[id].lost_num;itk++){
|
||||
handlebuf[2+itk] = server_frame[id].lost_packet[itk];
|
||||
}
|
||||
}else{
|
||||
msg_head->framenum = server_frame[id].framenum;
|
||||
msg_head->type = 0;
|
||||
}
|
||||
CHILDREN_DBG("S");
|
||||
tos = IPTOS_PREC_NETCONTROL; // 最高优先级
|
||||
setsockopt(*status_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
|
||||
sendto(*status_fd, handlebuf, 2+server_frame[id].lost_num, MSG_DONTWAIT, &remote_addr, sizeof(struct sockaddr));
|
||||
tos = IPTOS_PREC_ROUTINE; // 最低优先级
|
||||
setsockopt(*status_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
|
||||
|
||||
CHILDREN_DBG("RE");
|
||||
}
|
||||
|
||||
|
||||
void udp_handle_server_status_thread(void *d){
|
||||
uint16_t *port;
|
||||
struct sockaddr_in addrServer;
|
||||
in_addr_t cli_addr;
|
||||
int32_t err;
|
||||
memset(&addrServer,0,sizeof(struct sockaddr_in));
|
||||
|
||||
port = d;
|
||||
CHILDREN_DBG("data server:%d\r\n",*port);
|
||||
addrServer.sin_family=AF_INET;
|
||||
addrServer.sin_addr.s_addr= inet_addr("255.255.255.255");//client_addr;//inet_addr("192.168.169.1");
|
||||
addrServer.sin_port=htons(*port);
|
||||
EVT_HDL event_fd = eloop_add_fd( handle_protocol_fd, EVENT_READ, EVENT_F_ENABLED, (void*)udp_handle_server_status_read_workqueue, &handle_protocol_fd );
|
||||
user_protocol_task_increase();
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0)
|
||||
break;
|
||||
cli_addr = net_s_h264_sema_down(10, &err);
|
||||
if(err == RET_OK) {
|
||||
addrServer.sin_addr.s_addr = cli_addr;
|
||||
eloop_add_alarm(os_jiffies(),EVENT_F_ENABLED,udp_handle_server_status_write_workqueue,(void *)&addrServer); //eventloop send
|
||||
}
|
||||
}
|
||||
eloop_remove_event(event_fd);
|
||||
user_protocol_task_decrease();
|
||||
}
|
||||
|
||||
uint8_t mark_lost_pkt(uint8_t pkt,uint8_t *rxbuf){
|
||||
uint8_t get_cnt[100];
|
||||
uint32_t itk;
|
||||
uint8_t pktrx = 0;
|
||||
for(itk = 0;itk < 100;itk++){
|
||||
if(rxbuf[itk] != 0xff){
|
||||
if(pkt == rxbuf[itk]){ //接收到的清空
|
||||
rxbuf[itk] = 0xff;
|
||||
}else{
|
||||
get_cnt[pktrx] = rxbuf[itk]; //多少个pkt还未接收
|
||||
pktrx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(rxbuf,0xff,100);
|
||||
//server_frame.lost_num = pktrx;
|
||||
for(itk = 0;itk < pktrx;itk++){
|
||||
rxbuf[itk] = get_cnt[itk];
|
||||
}
|
||||
|
||||
return pktrx;
|
||||
}
|
||||
|
||||
void scale3_output_size_local_change(uint8_t id,uint8_t show_only,uint16 x,uint16 y,uint16 w,uint16 h);
|
||||
void scale2_output_size_local_change(uint8_t id,uint8_t show_only,uint16 x,uint16 y,uint16 w,uint16 h);
|
||||
|
||||
uint8_t switch_mode = 0;
|
||||
void udp_handle_server_data_thread(uint32_t *d){
|
||||
uint32 timer_ref = 0;
|
||||
uint32 timer_ref2 = 0;
|
||||
int retval;
|
||||
int ret;
|
||||
int len;
|
||||
int itk = 0;
|
||||
|
||||
uint16_t w,h;
|
||||
struct sockaddr_in remote_addr;
|
||||
uint16_t rx_speed_cnt = 0;
|
||||
uint16_t dispnum_cnt = 0;
|
||||
uint8_t push_lcd_success[10];
|
||||
uint16_t framenum[10];
|
||||
uint32_t framelen[10];
|
||||
uint16_t oldframecnt[10];
|
||||
uint8_t id;
|
||||
uint32_t framerate;
|
||||
uint8_t type[10];
|
||||
uint8_t cntnum[10];
|
||||
uint8_t pktnum[10];
|
||||
uint8_t *fbuf;
|
||||
uint32 ie;
|
||||
uint8_t *psarm_room;
|
||||
data_head *frame_hand;
|
||||
retval = 16;
|
||||
// uint32 frame_dec_num = 0;
|
||||
//framenum = 0xffff; //初始化值
|
||||
|
||||
user_protocol_task_increase();
|
||||
|
||||
memset(framenum,0xff,sizeof(framenum));
|
||||
memset(oldframecnt,0,sizeof(oldframecnt));
|
||||
memset(framelen,0,sizeof(framelen));
|
||||
memset(cntnum,0,sizeof(cntnum));
|
||||
memset(pktnum,0,sizeof(pktnum));
|
||||
memset(type,0,sizeof(type));
|
||||
frame_hand = (data_head *)photo_buf;
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0)
|
||||
break;
|
||||
//ret = recvfrom (dev_tbl->udp_data_fd, photo_buf, MAX_VIDEO_PKT_LEN+sizeof(data_head), 0, &remote_addr, (socklen_t*)&retval);
|
||||
ret = recvfrom (handle_data_protocol_fd, photo_buf, MAX_VIDEO_PKT_LEN+sizeof(data_head), 0, (struct sockaddr*)&remote_addr, (socklen_t*)&retval);
|
||||
if(ret <= 0)
|
||||
continue;
|
||||
id = 0;
|
||||
// for(itk = 0;itk < 10;itk++){
|
||||
// if(remote_addr.sin_addr.s_addr == devtab[itk].ipaddr){
|
||||
id = devtab[0].dev_id;
|
||||
psarm_room = devtab[0].psram_photo;
|
||||
framerate = devtab[0].frame_rate;
|
||||
w = devtab[0].w;
|
||||
h = devtab[0].h;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
if((id == 0)||(id > 3)) //当前设备号不存在,先只支持三台设备
|
||||
{
|
||||
CHILDREN_DBG("no this client dev(%d)....",id);
|
||||
continue;
|
||||
}
|
||||
|
||||
id = id-1; //设备号是从1开始计算,这里让设备号改成从0开始算
|
||||
if(ret >0){
|
||||
if((os_jiffies() - timer_ref) > 2000){
|
||||
rx_speed = rx_speed_cnt;
|
||||
rx_speed_cnt = 0;
|
||||
timer_ref = os_jiffies();
|
||||
}
|
||||
rx_speed_cnt += ret;
|
||||
walkmsg.rx_data += ret;
|
||||
}
|
||||
|
||||
if(framenum[id] != frame_hand->framenum){
|
||||
if(framenum[id] != 0xffff){
|
||||
if(cntnum[id] != pktnum[id]){
|
||||
CHILDREN_DBG("lost frame\r\n");
|
||||
}
|
||||
}
|
||||
CHILDREN_DBG("frame:%d type:%d id:%d\r\n",frame_hand->framenum,frame_hand->frmtype,id);
|
||||
|
||||
framenum[id] = frame_hand->framenum;
|
||||
type[id] = frame_hand->frmtype;
|
||||
cntnum[id] = frame_hand->cnt;
|
||||
pktnum[id] = 0;
|
||||
framelen[id] = 0;
|
||||
server_frame[id].framenum = framenum[id];
|
||||
memset(server_frame[id].lost_packet,0xff,100);
|
||||
for(itk = 0;itk < cntnum[id];itk++){
|
||||
server_frame[id].lost_packet[itk] = itk;
|
||||
}
|
||||
pktnum[id]++; //首次进来此帧图像
|
||||
server_frame[id].lost_num = mark_lost_pkt(frame_hand->pack,server_frame[id].lost_packet);
|
||||
}else{
|
||||
for(itk = 0;itk < cntnum[id];itk++){ //后面进来图像均经过这里
|
||||
if(frame_hand->pack == server_frame[id].lost_packet[itk]){ //数据没接收过
|
||||
goto markdata;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
markdata:
|
||||
pktnum[id]++;
|
||||
server_frame[id].lost_num = mark_lost_pkt(frame_hand->pack,server_frame[id].lost_packet);
|
||||
}
|
||||
// printf("@[%d:%d:%d:%d]@",frame_hand->pack,frame_hand->cnt,frame_hand->framenum,ret);
|
||||
|
||||
len = ret - sizeof(data_head);
|
||||
framelen[id] += len;
|
||||
hw_memcpy(psarm_room+frame_hand->pack*MAX_VIDEO_PKT_LEN,photo_buf+sizeof(data_head),len);
|
||||
|
||||
if(pktnum[id] == cntnum[id]){ //数据接收完成
|
||||
psarm_room[framelen[id]] = 0x00;
|
||||
psarm_room[framelen[id]+1] = 0x00;
|
||||
psarm_room[framelen[id]+2] = 0x00;
|
||||
psarm_room[framelen[id]+3] = 0x01;
|
||||
|
||||
|
||||
if((oldframecnt[id]+1) != framenum[id]){ //如果序号不连续
|
||||
if((framenum[id] == 0) && (oldframecnt[id] == 255)){ //序号循环了而已
|
||||
if(type[id] == 1){ //I帧,当前gop可推屏
|
||||
push_lcd_success[id] = 1;
|
||||
}
|
||||
}else{ //真实意义上的丢失了
|
||||
walkmsg.frame_rx_lost++;
|
||||
if(type[id] != 1){ //不是I帧
|
||||
CHILDREN_DBG("error ...................frame code\r\n"); //那当前ID不能再推了
|
||||
push_lcd_success[id] = 0;
|
||||
}else{ //丢帧了,但当前还是I帧,还是可以推的
|
||||
push_lcd_success[id] = 1;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(type[id] == 1){ //I帧,当前gop可推屏
|
||||
push_lcd_success[id] = 1;
|
||||
}
|
||||
walkmsg.frame_rx_success++;
|
||||
}
|
||||
|
||||
if(push_lcd_success[id] == 1){ //可推送gop
|
||||
// sys_dcache_clean_range(psram_h264_photo,framelen+4);
|
||||
// h264_dec_src_264(psram_h264_photo,framelen,640,368);
|
||||
for(itk = 0;itk < DEC_TABLE_NUM;itk++){
|
||||
if(decmsg[itk].addr == NULL){
|
||||
fbuf = av_psram_malloc(framelen[id]+4);
|
||||
hw_memcpy(fbuf,psarm_room,framelen[id]+4);
|
||||
ie = disable_irq();
|
||||
decmsg[itk].addr = fbuf;
|
||||
decmsg[itk].len = framelen[id];
|
||||
decmsg[itk].timeinf = os_jiffies();
|
||||
decmsg[itk].num = framenum[id];
|
||||
decmsg[itk].type = type[id];
|
||||
decmsg[itk].devid= id; //当前完成推送的摄像头ID
|
||||
decmsg[itk].framerate = framerate;
|
||||
decmsg[itk].w = w;
|
||||
decmsg[itk].h = h;
|
||||
frame_for_dec++;
|
||||
CHILDREN_DBG("w:%d h:%d id:%d len:%d\r\n",w,h,id,decmsg[itk].len);
|
||||
enable_irq(ie);
|
||||
//frame_dec_num++;
|
||||
// if(frame_dec_num == 0) {
|
||||
// scale2_output_size_local_change(0,0,0,0,320,240);
|
||||
// scale3_output_size_local_change(0,0,0,0,160,120);
|
||||
// frame_dec_num++;
|
||||
// }
|
||||
// if((frame_dec_num%600) == 200){
|
||||
// _os_printf("%s %d\r\n",__func__,__LINE__);
|
||||
// scale2_output_size_local_change(0,0,0,0,320,240);
|
||||
// scale3_output_size_local_change(0,0,6,6,160,120);
|
||||
// }else if((frame_dec_num%600) == 400){
|
||||
// _os_printf("%s %d\r\n",__func__,__LINE__);
|
||||
// scale2_output_size_local_change(0,0,6,6,160,120);
|
||||
// scale3_output_size_local_change(0,0,0,0,320,240);
|
||||
|
||||
// }else if((frame_dec_num%600) == 500){
|
||||
// //scale2_output_size_local_change(0,0,0,10,160,120);
|
||||
// //scale3_output_size_local_change(0,1,30,0,320,240);
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((os_jiffies() - timer_ref2) > 2000){
|
||||
dispnum = dispnum_cnt;
|
||||
dispnum_cnt = 0;
|
||||
timer_ref2 = os_jiffies();
|
||||
}
|
||||
dispnum_cnt++;
|
||||
oldframecnt[id] = framenum[id];
|
||||
net_s_h264_sema_up(remote_addr.sin_addr.s_addr);
|
||||
}
|
||||
}
|
||||
user_protocol_task_decrease();
|
||||
}
|
||||
|
||||
extern volatile uint8_t scaler2_dev_id;
|
||||
void udp_handle_server_decode_to_lcd_thread(){
|
||||
int itk = 0;
|
||||
uint8_t disp_num;
|
||||
uint8_t decframe[3];
|
||||
uint32_t timeinf[3];
|
||||
uint32_t listaddr;
|
||||
uint8_t *h264dat;
|
||||
struct scale_device *scale_dev;
|
||||
uint32 ie;
|
||||
uint16 oldw,oldh;
|
||||
uint16 w,h;
|
||||
uint8_t flush_video;
|
||||
uint8_t change_pixel = 1;
|
||||
uint16_t framerate[3];
|
||||
uint16_t framecnt[3];
|
||||
uint32_t lasttime[3];
|
||||
uint32_t wanttime[3];
|
||||
lasttime[0]=lasttime[1]=lasttime[2]=0;
|
||||
wanttime[0]=wanttime[1]=wanttime[2]=0;
|
||||
scale_dev = (struct scale_device *)dev_get(HG_SCALE2_DEVID);
|
||||
|
||||
static uint32_t last_update_time = 0;
|
||||
static uint32_t total_disp_num = 0;
|
||||
|
||||
user_protocol_task_increase();
|
||||
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0)
|
||||
break;
|
||||
|
||||
timeinf[0]=timeinf[1]=timeinf[2]= 0xffffffff;
|
||||
decframe[0]=decframe[1]=decframe[2]= 255;
|
||||
os_sleep_ms(2);
|
||||
|
||||
ie = disable_irq();
|
||||
framecnt[0]=framecnt[1]=framecnt[2]=0;
|
||||
disp_num = 0;
|
||||
for(itk = 0;itk < DEC_TABLE_NUM;itk++){
|
||||
if(decmsg[itk].addr != NULL){
|
||||
if(timeinf[decmsg[itk].devid] > decmsg[itk].timeinf){
|
||||
timeinf[decmsg[itk].devid] = decmsg[itk].timeinf;
|
||||
decframe[decmsg[itk].devid] = itk;
|
||||
}
|
||||
framerate[decmsg[itk].devid] = devtab[decmsg[itk].devid].frame_rate;
|
||||
framecnt[decmsg[itk].devid]++;
|
||||
disp_num++;
|
||||
}
|
||||
}
|
||||
enable_irq(ie);
|
||||
|
||||
|
||||
if(disp_num != 0){
|
||||
for(itk = 0;itk < 3;itk++){
|
||||
if(framecnt[itk] != 0){ //当前id存在帧
|
||||
flush_video = 0;
|
||||
if((os_jiffies() - lasttime[itk]) > 100){ //本次刷图像跟上次刷的时间差了100ms,那就直接推送
|
||||
flush_video = 1;
|
||||
}else{
|
||||
if(os_jiffies() > wanttime[itk]){ //时间到了推送时间,则发送
|
||||
flush_video = 1;
|
||||
}else{ //还没到推送时间,则要检查一下帧缓存有多少,如果多的话,则要适时推送
|
||||
if(framecnt[itk] > 12){ //存够12帧的话,不要想了,发送吧
|
||||
flush_video = 1;
|
||||
}else if(framecnt[itk] > 6){ //按照帧率时间减少15ms速度进行播放,以防数据拥堵引起延时
|
||||
if( os_jiffies() > (wanttime[itk] - 15)){
|
||||
flush_video = 1;
|
||||
}
|
||||
}else{
|
||||
if(os_jiffies() >= (wanttime[itk] - 10)){ //按照帧率时间减少10ms速度进行播放,如果严格按照帧率比例来整,肯定会造成数据拥堵到需提前播的位置
|
||||
flush_video = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(flush_video){
|
||||
total_disp_num++;
|
||||
lasttime[itk] = os_jiffies();
|
||||
wanttime[itk] = os_jiffies()+1000/decmsg[decframe[itk]].framerate;
|
||||
scaler2_dev_id =decmsg[decframe[itk]].devid;
|
||||
sys_dcache_clean_range((uint32_t *)decmsg[decframe[itk]].addr,decmsg[decframe[itk]].len+4);
|
||||
if(decmsg[decframe[itk]].type == 1){
|
||||
change_pixel = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if((decmsg[decframe[itk]].w == scale_get_input_width(scale_dev)||(1 == scale_get_input_width(scale_dev))) && (decmsg[decframe[itk]].h == scale_get_input_high(scale_dev)||(1 == scale_get_input_high(scale_dev))) && (change_pixel == 0)){//确认scale模块配置的源size跟目前要解码的size是一致
|
||||
//h264_dec_src_264(decmsg[decframe[itk]].addr,decmsg[decframe[itk]].len,decmsg[decframe[itk]].w,16*((decmsg[decframe[itk]].h + 15)/16) ,decmsg[decframe[itk]].devid);
|
||||
|
||||
|
||||
listaddr = put_h264msg_to_queue(1,decmsg[decframe[itk]].w,decmsg[decframe[itk]].h,decmsg[decframe[itk]].addr,decmsg[decframe[itk]].len);
|
||||
while(h264msg_queue_done(listaddr) == 0){
|
||||
os_sleep_ms(2);
|
||||
}
|
||||
}
|
||||
else{
|
||||
change_pixel = 1;
|
||||
}
|
||||
#else
|
||||
if(change_pixel == 0)
|
||||
{
|
||||
h264dat = decmsg[decframe[itk]].addr;
|
||||
|
||||
if(h264dat[4] == 0x67){ //SPS
|
||||
get_h264_stream_w_h(&w,&h,h264dat);
|
||||
if(h == 368){
|
||||
h = 360;
|
||||
}
|
||||
if(h == 128){
|
||||
h = 120;
|
||||
}
|
||||
|
||||
scale2_recfg_input_size(w,h,0);
|
||||
oldw = w;
|
||||
oldh = h;
|
||||
}
|
||||
//_os_printf("w:%d,h:%d\r\n",w,h);
|
||||
listaddr = put_h264msg_to_queue(1,w,h,(uint32_t)(decmsg[decframe[itk]].addr),decmsg[decframe[itk]].len);
|
||||
while(h264msg_queue_done(listaddr) == 0){
|
||||
os_sleep_ms(2);
|
||||
}
|
||||
}
|
||||
else{
|
||||
change_pixel = 1;
|
||||
}
|
||||
#endif
|
||||
av_psram_free(decmsg[decframe[itk]].addr);
|
||||
ie = disable_irq();
|
||||
frame_for_dec--;
|
||||
decmsg[decframe[itk]].addr = NULL;
|
||||
enable_irq(ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if((os_jiffies()-last_update_time) > 5000) {
|
||||
_os_printf("\n");
|
||||
os_printf("---disp num:%d---",(uint32_t)((float)total_disp_num/((float)(os_jiffies()-last_update_time)/1000.0f)));
|
||||
_os_printf("\n");
|
||||
last_update_time = os_jiffies();
|
||||
total_disp_num = 0;
|
||||
}
|
||||
}
|
||||
user_protocol_task_decrease();
|
||||
}
|
||||
|
||||
static uint16_t port_data;
|
||||
static uint16_t port_status;
|
||||
void udp_handle_server_init(uint16_t status_port,uint16_t data_port)
|
||||
{
|
||||
k_task_handle_t handle_lcd_task_recv;
|
||||
static k_task_handle_t handle_task_recv;
|
||||
static k_task_handle_t handle_data_task_recv;
|
||||
port_status = status_port;
|
||||
handle_protocol_fd = usr_protocol_create_server(port_status);
|
||||
port_data = data_port;
|
||||
handle_data_protocol_fd = usr_protocol_create_server(port_data);
|
||||
csi_kernel_task_new((k_task_entry_t)udp_handle_server_status_thread, "handle_udp_pkt", &port_status, 25, 0, NULL, 1024, &handle_task_recv);
|
||||
csi_kernel_task_new((k_task_entry_t)udp_handle_server_data_thread, "handle_data_udp_pkt", &port_data, 25, 0, NULL, 1024, &handle_data_task_recv);
|
||||
os_printf("status:%d data:%d\r\n",handle_protocol_fd,handle_data_protocol_fd);
|
||||
csi_kernel_task_new((k_task_entry_t)udp_handle_server_decode_to_lcd_thread, "handle_data_decode_pkt", NULL, 25, 0, NULL, 1024, &handle_lcd_task_recv);
|
||||
}
|
||||
|
||||
void udp_handle_server_deinit(void)
|
||||
{
|
||||
while(walkmsg.run_task > 0)
|
||||
os_sleep_ms(1);
|
||||
if(handle_protocol_fd != -1) {
|
||||
close(handle_protocol_fd);
|
||||
handle_protocol_fd = -1;
|
||||
}
|
||||
if(handle_data_protocol_fd != -1) {
|
||||
close(handle_data_protocol_fd);
|
||||
handle_data_protocol_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void protocol_server_init(uint16_t status_port,uint16_t data_port){
|
||||
#if 0
|
||||
struct h264_device *h264_dev;
|
||||
struct msi *scale2 = scale2_msi("scale2", 640, 360, 320, 240, FSTYPE_YUV_P0, 10);
|
||||
if (scale2)
|
||||
{
|
||||
msi_add_output(scale2, NULL, "sim_video");
|
||||
os_printf("%s %d\r\n",__func__,__LINE__);
|
||||
}
|
||||
//scaler_msi_gol = scale2;
|
||||
h264_dev = (struct h264_device *)dev_get(HG_H264_DEVID);
|
||||
memset(decmsg,0x00,sizeof(decmsg));
|
||||
h264_drv_init(h264_dev);
|
||||
h264_dec_room_init(2,1280,720);
|
||||
#endif
|
||||
|
||||
devtab[0].dev_id = 1; //把当前设备号记录下来
|
||||
devtab[0].frame_rate = 25;
|
||||
devtab[0].w = NET_W;
|
||||
devtab[0].h = NET_H;
|
||||
devtab[0].psram_photo = av_psram_malloc(200*1024); //给初始化空间 200K
|
||||
|
||||
net_s_h264_sema_init();
|
||||
udp_handle_server_init(status_port,data_port);
|
||||
// tcp_handle_server_init();
|
||||
}
|
||||
|
||||
void protocol_server_deinit()
|
||||
{
|
||||
udp_handle_server_deinit();
|
||||
net_s_h264_sema_deinit();
|
||||
for(uint32_t i=0; i<DEC_TABLE_NUM; i++){
|
||||
if(decmsg[i].addr != NULL){
|
||||
av_psram_free(decmsg[i].addr);
|
||||
decmsg[i].addr = NULL;
|
||||
}
|
||||
}
|
||||
if(devtab[0].psram_photo) {
|
||||
av_psram_free(devtab[0].psram_photo);
|
||||
devtab[0].psram_photo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void user_protocol2(uint16_t status_port,uint16_t data_port)
|
||||
{
|
||||
protocol_server_init(status_port,data_port); //进行推屏 AP
|
||||
}
|
||||
|
||||
void user_protocol2_deinit(void)
|
||||
{
|
||||
protocol_server_deinit();
|
||||
}
|
||||
#endif
|
||||
923
sdk/app/walkie-talkie/walkie_talkie_b.c
Normal file
923
sdk/app/walkie-talkie/walkie_talkie_b.c
Normal file
@@ -0,0 +1,923 @@
|
||||
/***************************************************
|
||||
该demo主要是使用AT命令拍一张照片,前提要将jpeg打开
|
||||
***************************************************/
|
||||
#include "sys_config.h"
|
||||
#include "tx_platform.h"
|
||||
#include "osal/string.h"
|
||||
#include "stream_frame.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal_file.h"
|
||||
#include "video_app/video_app.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "utlist.h"
|
||||
#include "jpgdef.h"
|
||||
#include "lib/lcd/lcd.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "netif/ethernetif.h"
|
||||
#include "lib/common/sysevt.h"
|
||||
#include "syscfg.h"
|
||||
#include <event.h>
|
||||
#include <csi_kernel.h>
|
||||
#include "lib/video/dvp/jpeg/jpg.h"
|
||||
#include "walkie_talkie.h"
|
||||
#include "stream_define.h"
|
||||
#include "lib/multimedia/msi.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
#include "dev/vpp/hgvpp.h"
|
||||
#include "lib/umac/ieee80211.h"
|
||||
#include "lib/video/h264/h264_drv.h"
|
||||
#include "lib/lmac/lmac.h"
|
||||
#include "hal/dvp.h"
|
||||
|
||||
#ifdef SYS_APP_WALKIE_TALKIE
|
||||
|
||||
// data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
// 结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
#define MAX_USER_VIDEO_TX 16
|
||||
#define MAX_VIDEO_PKT_LEN 1430
|
||||
|
||||
|
||||
#if OPEN_DBG
|
||||
#define CHILDREN_DBG(fmt, ...) _os_printf(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define CHILDREN_DBG(fmt, ...) //_os_printf(fmt, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
frame_msg client_frame;
|
||||
uint32_t client_dev_magic = 0;
|
||||
os_mutex_t thread_lock;
|
||||
|
||||
static struct os_semaphore net_h264_sem = {0,NULL};
|
||||
static struct os_semaphore net_h264_status_sem = {0,NULL};
|
||||
static struct os_semaphore net_tcp_sem = {0,NULL};
|
||||
|
||||
static k_task_handle_t handle_task_recv;
|
||||
static k_task_handle_t handle_data_task_recv;
|
||||
|
||||
static int handle_protocol_fd = - 1;
|
||||
static int handle_data_protocol_fd = - 1;
|
||||
static volatile uint32 status_unlock = 0;
|
||||
|
||||
static uint8_t photo_buf[1440] __attribute__ ((aligned(4)));;
|
||||
uint8_t server_staus_buf[200];
|
||||
volatile uint32 server_frame_rate;
|
||||
|
||||
uint32_t heartbeat = 0;
|
||||
|
||||
EVT_HDL tcp_read_ev;
|
||||
|
||||
static uint8_t current_bss_bw = 10;
|
||||
static uint8_t ctrl_mode = 4;
|
||||
|
||||
void net_h264_status_sema_init()
|
||||
{
|
||||
os_sema_init(&net_h264_status_sem,0);
|
||||
}
|
||||
|
||||
int32 net_h264_status_sema_down(int32 tmo_ms)
|
||||
{
|
||||
return os_sema_down(&net_h264_status_sem,tmo_ms);
|
||||
}
|
||||
|
||||
void net_h264_status_sema_up()
|
||||
{
|
||||
os_sema_up(&net_h264_status_sem);
|
||||
}
|
||||
|
||||
void net_h264_status_sema_deinit()
|
||||
{
|
||||
if(net_h264_status_sem.hdl) {
|
||||
os_sema_del(&net_h264_status_sem);
|
||||
}
|
||||
}
|
||||
|
||||
void net_h264_sema_init()
|
||||
{
|
||||
os_sema_init(&net_h264_sem,0);
|
||||
}
|
||||
|
||||
int32_t net_h264_sema_down(int32 tmo_ms)
|
||||
{
|
||||
return os_sema_down(&net_h264_sem,tmo_ms);
|
||||
}
|
||||
|
||||
void net_h264_sema_up()
|
||||
{
|
||||
os_sema_up(&net_h264_sem);
|
||||
}
|
||||
|
||||
void net_h264_sema_deinit()
|
||||
{
|
||||
if(net_h264_sem.hdl) {
|
||||
os_sema_del(&net_h264_sem);
|
||||
}
|
||||
}
|
||||
|
||||
void net_tcp_sema_init()
|
||||
{
|
||||
os_sema_init(&net_tcp_sem,0);
|
||||
}
|
||||
|
||||
int32 net_tcp_sema_down(int32 tmo_ms)
|
||||
{
|
||||
return os_sema_down(&net_tcp_sem,tmo_ms);
|
||||
}
|
||||
|
||||
void net_tcp_sema_up()
|
||||
{
|
||||
os_sema_up(&net_tcp_sem);
|
||||
}
|
||||
uint16_t w_gol,h_gol;
|
||||
static int net_video_msi_action(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2)
|
||||
{
|
||||
int ret = RET_OK;
|
||||
switch (cmd_id)
|
||||
{
|
||||
|
||||
// 暂时没有考虑释放
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
}
|
||||
break;
|
||||
// 接收,判断是否已经压缩了
|
||||
case MSI_CMD_TRANS_FB:
|
||||
{
|
||||
struct framebuff *fb = (struct framebuff *)param1;
|
||||
//_os_printf("&&");
|
||||
if(w_gol == 1280){
|
||||
if(fb->stype != FSTYPE_H264_VPP_DATA0)
|
||||
{
|
||||
ret = RET_ERR;
|
||||
}
|
||||
}else{
|
||||
if(fb->stype != FSTYPE_H264_GEN420_DATA)
|
||||
{
|
||||
ret = RET_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSI_CMD_FREE_FB:
|
||||
{
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usr_protocol_create_client(uint16_t port)
|
||||
{
|
||||
int socket_c, err;
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_len = sizeof(struct sockaddr_in);
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = htons(INADDR_ANY);
|
||||
|
||||
socket_c = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket_c < 0)
|
||||
{
|
||||
CHILDREN_DBG("get socket err");
|
||||
return - 1;
|
||||
}
|
||||
|
||||
err = bind(socket_c, (struct sockaddr*) &addr, sizeof(struct sockaddr_in));
|
||||
|
||||
if (err == - 1)
|
||||
{
|
||||
close(socket_c);
|
||||
return - 1;
|
||||
|
||||
}
|
||||
return socket_c;
|
||||
}
|
||||
|
||||
|
||||
void udp_handle_client_status_write_workqueue(void *ei, void *d){
|
||||
int tos;
|
||||
static uint8_t pri_inv = 0;
|
||||
uint32 ie;
|
||||
status_msg *msg_head;
|
||||
char buf[12];
|
||||
int len;
|
||||
msg_head = (status_msg *)buf;
|
||||
msg_head->framenum = client_frame.framenum;
|
||||
msg_head->type = 1;
|
||||
if(client_frame.lost_num != 0){
|
||||
pri_inv++;
|
||||
if((pri_inv%2)==1){
|
||||
tos = IPTOS_PREC_NETCONTROL; // 最高优先级
|
||||
setsockopt(handle_protocol_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
|
||||
}
|
||||
len = sendto(handle_protocol_fd, (char*)buf, 2, MSG_DONTWAIT, (struct sockaddr *)d, sizeof(struct sockaddr));
|
||||
tos = IPTOS_PREC_ROUTINE; // 最低优先级
|
||||
setsockopt(handle_protocol_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
|
||||
|
||||
CHILDREN_DBG("W(%x %x)",buf[0],buf[1]);
|
||||
}else{
|
||||
ie = disable_irq();
|
||||
if(status_unlock){
|
||||
status_unlock = 0;
|
||||
net_h264_status_sema_up();
|
||||
}
|
||||
enable_irq(ie);
|
||||
client_frame.status = 2; //已经收到完整数据,没必要重发,只修改状态就可以
|
||||
}
|
||||
}
|
||||
|
||||
void udp_handle_client_status_read_workqueue(){
|
||||
int retval;
|
||||
int ret;
|
||||
uint32 ie;
|
||||
uint8_t itk;
|
||||
uint8_t new_status;
|
||||
status_msg *msg_head;
|
||||
|
||||
struct sockaddr remote_addr;
|
||||
retval = 16;
|
||||
ret = recvfrom (handle_protocol_fd, server_staus_buf, 200, 0, &remote_addr, (socklen_t*)&retval);
|
||||
if(ret <= 0)
|
||||
return;
|
||||
os_mutex_lock(&thread_lock, osWaitForever);
|
||||
msg_head = (status_msg *)server_staus_buf;
|
||||
new_status = client_frame.status;
|
||||
client_frame.status = 2;
|
||||
|
||||
if(msg_head->framenum != client_frame.framenum){
|
||||
client_frame.status = new_status;
|
||||
os_mutex_unlock(&thread_lock);
|
||||
CHILDREN_DBG("E(%d)",msg_head->framenum);
|
||||
return;
|
||||
}
|
||||
os_mutex_unlock(&thread_lock);
|
||||
|
||||
CHILDREN_DBG("server recv:%d type:%d\r\n",msg_head->framenum,msg_head->type);
|
||||
|
||||
if(msg_head->type == 0){
|
||||
client_frame.lost_num = 0;
|
||||
}else if(msg_head->type == 2){
|
||||
client_frame.lost_num = ret - 2;
|
||||
memset(client_frame.lost_packet,0xff,100);
|
||||
for(itk = 0;itk < client_frame.lost_num;itk++){
|
||||
client_frame.lost_packet[itk] = server_staus_buf[2+itk];
|
||||
}
|
||||
}
|
||||
|
||||
ie = disable_irq();
|
||||
if(status_unlock){
|
||||
status_unlock = 0;
|
||||
net_h264_status_sema_up();
|
||||
}
|
||||
enable_irq(ie);
|
||||
}
|
||||
|
||||
extern in_addr_t send_addr;
|
||||
void udp_handle_client_status_thread(void *d)
|
||||
{
|
||||
uint32 ie;
|
||||
uint8_t loop_run;
|
||||
//uint16_t port = 6003;
|
||||
uint8_t framenum;
|
||||
uint32_t start_tmr = 0;
|
||||
struct sockaddr_in addrServer;
|
||||
uint16_t *port;
|
||||
int32_t time_out = 10;
|
||||
int32_t ret = 0;
|
||||
EVT_HDL event_fd = NULL;
|
||||
port = d;
|
||||
|
||||
user_protocol_task_increase();
|
||||
|
||||
memset(&addrServer,0,sizeof(struct sockaddr_in));
|
||||
while(send_addr == 0){
|
||||
if(walkmsg.run_state == 0) {
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
os_sleep_ms(10);
|
||||
}
|
||||
addrServer.sin_family=AF_INET;
|
||||
addrServer.sin_addr.s_addr=send_addr;//inet_addr("192.168.169.1");//client_addr;//
|
||||
addrServer.sin_port=htons(*port);
|
||||
|
||||
handle_protocol_fd = usr_protocol_create_client(*port);
|
||||
setsockopt(handle_protocol_fd, SOL_SOCKET, SO_RCVTIMEO, &time_out, sizeof(int32_t));
|
||||
event_fd = eloop_add_fd( handle_protocol_fd, EVENT_READ, EVENT_F_ENABLED, udp_handle_client_status_read_workqueue, 0 );
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0)
|
||||
break;
|
||||
CHILDREN_DBG("D");
|
||||
ret = net_h264_sema_down(10); //wait for data send finish
|
||||
if(ret != RET_OK)
|
||||
continue;
|
||||
CHILDREN_DBG("Q(%d)",client_frame.status);
|
||||
start_tmr = client_frame.time;
|
||||
framenum = client_frame.framenum;
|
||||
os_sleep_ms(client_frame.timeout);
|
||||
loop_run = 0;
|
||||
while((client_frame.status == 0)&&(framenum == client_frame.framenum)){ //如果当前frame还处于等待client状态的情况,发送请求状态的要求
|
||||
eloop_add_alarm(os_jiffies(),EVENT_F_ENABLED,udp_handle_client_status_write_workqueue,(void *)&addrServer); //eventloop send
|
||||
//client_frame.timeout = 5; //10ms都读不到对回复的状态,重发吧
|
||||
os_sleep_ms(10);
|
||||
loop_run++;
|
||||
if(loop_run > 12) //重发12次后还是读不到状态,认命吧,你掉线了
|
||||
break;
|
||||
}
|
||||
|
||||
if(client_frame.status == 0){
|
||||
if(client_frame.framenum == framenum){ //要是新的frame来了,表示旧的frame已经正常结束,否则要唤醒当前帧
|
||||
ie = disable_irq();
|
||||
if(status_unlock){
|
||||
status_unlock = 0;
|
||||
net_h264_status_sema_up();
|
||||
}
|
||||
client_frame.status = 3; //frame timeout,lost
|
||||
enable_irq(ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(handle_protocol_fd);
|
||||
eloop_remove_event(event_fd);
|
||||
user_protocol_task_decrease();
|
||||
}
|
||||
|
||||
#if 1
|
||||
void recfg_mclk_msg(struct dvp_device * mclkdev,uint8_t success){
|
||||
static uint8_t framecnt = 0;
|
||||
static uint8_t lost_frame_num = 0;
|
||||
static uint8_t success_frame_num = 0;
|
||||
static uint32_t timeout = 0;
|
||||
static uint8_t speed_level = 0; //
|
||||
static uint8_t last_speed_level = 0xff;
|
||||
int32 isstaconnect;
|
||||
if(apsta_mode == 2) //STA
|
||||
{
|
||||
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_STA);
|
||||
if(isstaconnect == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
else{
|
||||
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_AP);
|
||||
if(isstaconnect == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(framecnt > 15){ //15帧内丢帧比例
|
||||
if((os_jiffies() - timeout) > 1000){ //如果刚调整过mclk,那等3秒后再进行下次调整
|
||||
if(lost_frame_num > 12){
|
||||
timeout = os_jiffies();
|
||||
speed_level = 3;
|
||||
}else if(lost_frame_num > 6){ //15帧丢了6帧以上
|
||||
timeout = os_jiffies();
|
||||
speed_level = 2;
|
||||
}else if(lost_frame_num > 3){ //15帧丢了3帧以上
|
||||
timeout = os_jiffies();
|
||||
speed_level = 1;
|
||||
}else if(lost_frame_num == 0){ //没丢帧
|
||||
if(speed_level == 0){
|
||||
speed_level = 0;
|
||||
}else{
|
||||
speed_level--;
|
||||
}
|
||||
}
|
||||
|
||||
// speed_level = ctrl_mode;
|
||||
|
||||
if (ctrl_mode != 4) {
|
||||
speed_level = ctrl_mode;
|
||||
}
|
||||
|
||||
if(last_speed_level != speed_level){
|
||||
last_speed_level = speed_level;
|
||||
#if 0
|
||||
if(speed_level == 0){
|
||||
h264_recfg_bsp(1,200,200);
|
||||
h264_recfg_rate(1,25);
|
||||
h264_recfg_frm_gop(1,25);
|
||||
h264_recfg_ini_qp(1,26);
|
||||
//dvp_set_baudrate(mclkdev,24000000);
|
||||
}else if(speed_level == 1){
|
||||
h264_recfg_bsp(1,150,150);
|
||||
h264_recfg_rate(1,12);
|
||||
h264_recfg_frm_gop(1,12);
|
||||
h264_recfg_ini_qp(1,31);
|
||||
//dvp_set_baudrate(mclkdev,12000000);
|
||||
}else if(speed_level == 2){
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,37);
|
||||
//dvp_set_baudrate(mclkdev,6000000);
|
||||
}
|
||||
#endif
|
||||
walkmsg.speed = speed_level;
|
||||
}
|
||||
}
|
||||
framecnt = 0;
|
||||
lost_frame_num = 0;
|
||||
success_frame_num = 0;
|
||||
}else{
|
||||
if(success){
|
||||
success_frame_num++;
|
||||
}else{
|
||||
lost_frame_num++;
|
||||
}
|
||||
framecnt++;
|
||||
}
|
||||
walkmsg.speed = speed_level;
|
||||
}
|
||||
#endif
|
||||
void recfg_mclk_by_connect(){
|
||||
static int32 lastconnect;
|
||||
int32 isstaconnect;
|
||||
if(apsta_mode == 2){
|
||||
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_STA);
|
||||
}else{
|
||||
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_AP);
|
||||
}
|
||||
|
||||
if((isstaconnect != lastconnect)&&(isstaconnect == 0)){ //连接掉线,时钟恢复成高帧率,重连之后再恢复mcs控制
|
||||
//dvp_set_baudrate(mclkdev,24000000);
|
||||
lastconnect = isstaconnect;
|
||||
return;
|
||||
}
|
||||
|
||||
lastconnect = isstaconnect;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void recfg_mclk_by_mcs(uint8_t mcs,uint8_t frmtype)
|
||||
{
|
||||
static uint8_t lastmcs;
|
||||
static uint8_t lastfrmtype;
|
||||
static uint8_t speed_level = 0;
|
||||
|
||||
if((lastfrmtype != frmtype) && (frmtype == 0)) {
|
||||
lastfrmtype = frmtype;
|
||||
if(walkmsg.speed == 4)
|
||||
return;
|
||||
speed_level = 4;
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,37);
|
||||
walkmsg.speed = speed_level;
|
||||
h264_reflash_new_gop(1,1);
|
||||
}
|
||||
else if(lastmcs != mcs){
|
||||
lastmcs = mcs;
|
||||
if(current_bss_bw == 20) {
|
||||
if(lastmcs > 5){ //mcs 6 7
|
||||
if(walkmsg.speed == 0)
|
||||
return;
|
||||
speed_level = 0;
|
||||
h264_recfg_bsp(1,200,200);
|
||||
h264_recfg_rate(1,25);
|
||||
h264_recfg_frm_gop(1,25);
|
||||
h264_recfg_ini_qp(1,26);
|
||||
h264_reflash_new_gop(1,1);
|
||||
//dvp_set_baudrate(mclkdev,24000000);
|
||||
}else if(lastmcs > 3){ //mcs 4 5
|
||||
if(walkmsg.speed == 1)
|
||||
return;
|
||||
speed_level = 1;
|
||||
h264_recfg_bsp(1,150,150);
|
||||
h264_recfg_rate(1,20);
|
||||
h264_recfg_frm_gop(1,20);
|
||||
h264_recfg_ini_qp(1,29);
|
||||
h264_reflash_new_gop(1,1);
|
||||
//dvp_set_baudrate(mclkdev,20000000);
|
||||
}else if(lastmcs > 2){ //mcs 3
|
||||
if(walkmsg.speed == 2)
|
||||
return;
|
||||
speed_level = 2;
|
||||
h264_recfg_bsp(1,100,100);
|
||||
h264_recfg_rate(1,12);
|
||||
h264_recfg_frm_gop(1,12);
|
||||
h264_recfg_ini_qp(1,33);
|
||||
h264_reflash_new_gop(1,1);
|
||||
//dvp_set_baudrate(mclkdev,12000000);
|
||||
}else if(lastmcs > 1){ //mcs 2
|
||||
if(walkmsg.speed == 3)
|
||||
return;
|
||||
speed_level = 3;
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,37);
|
||||
h264_reflash_new_gop(1,1);
|
||||
//dvp_set_baudrate(mclkdev,6000000);
|
||||
}else { //mcs 1 0
|
||||
if(walkmsg.speed == 4)
|
||||
return;
|
||||
speed_level = 4;
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,37);
|
||||
h264_reflash_new_gop(1,1);
|
||||
}
|
||||
}
|
||||
else if(current_bss_bw == 5 || current_bss_bw == 10) {
|
||||
if(lastmcs > 5) {
|
||||
if(walkmsg.speed == 2)
|
||||
return;
|
||||
speed_level = 2;
|
||||
h264_recfg_bsp(1,100,100);
|
||||
h264_recfg_rate(1,12);
|
||||
h264_recfg_frm_gop(1,12);
|
||||
h264_recfg_ini_qp(1,33);
|
||||
h264_reflash_new_gop(1,1);
|
||||
}
|
||||
else if(lastmcs > 3) {
|
||||
if(walkmsg.speed == 3)
|
||||
return;
|
||||
speed_level = 3;
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,37);
|
||||
h264_reflash_new_gop(1,1);
|
||||
}
|
||||
else {
|
||||
if(walkmsg.speed == 4)
|
||||
return;
|
||||
speed_level = 4;
|
||||
h264_recfg_bsp(1,50,50);
|
||||
h264_recfg_rate(1,6);
|
||||
h264_recfg_frm_gop(1,6);
|
||||
h264_recfg_ini_qp(1,37);
|
||||
h264_reflash_new_gop(1,1);
|
||||
}
|
||||
}
|
||||
walkmsg.speed = speed_level;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void udp_handle_client_data_thread(void *d){
|
||||
int32 ret;
|
||||
uint32 ie;
|
||||
uint8_t framesuc = 0;
|
||||
// uint8_t mcs = 0;
|
||||
// uint8_t frmtype = 0;
|
||||
// uint32_t temp;
|
||||
// uint8_t mcslop=0;
|
||||
struct dvp_device *dvp_dev;
|
||||
uint8_t framenum;
|
||||
uint8_t oldcount = 0;
|
||||
uint8_t lostframe = 0;
|
||||
uint8_t itk;
|
||||
uint8_t lostidx = 0;
|
||||
uint8_t lostloop = 0;
|
||||
uint32_t framelen = 0;
|
||||
uint32_t datoffset = 0;
|
||||
uint32_t sendlen = 0;
|
||||
uint8_t pktcnt = 0;
|
||||
struct fb_h264_s *h264;
|
||||
|
||||
struct sockaddr_in addrServer;
|
||||
struct framebuff *h264_fb = NULL;
|
||||
int len;
|
||||
data_head *data_head_msg;
|
||||
struct msi *msi;
|
||||
uint16_t *port;
|
||||
port = d;
|
||||
dvp_dev = (struct dvp_device *)dev_get(HG_DVP_DEVID);
|
||||
|
||||
user_protocol_task_increase();
|
||||
|
||||
msi = msi_new("NET_H264", MAX_USER_VIDEO_TX, NULL);
|
||||
msi->action = net_video_msi_action;
|
||||
msi->enable = 1;
|
||||
msi_add_output(0, S_H264, "NET_H264"); //lvgl的msi输出到R_OSD_ENCODE的msi
|
||||
|
||||
while(send_addr == 0){
|
||||
if(walkmsg.run_state == 0) {
|
||||
msi_destroy(msi);
|
||||
msi_del_output(0, S_H264, "NET_H264");
|
||||
user_protocol_task_decrease();
|
||||
return;
|
||||
}
|
||||
os_sleep_ms(10);
|
||||
}
|
||||
framenum = 0;
|
||||
memset(&addrServer,0,sizeof(struct sockaddr_in));
|
||||
addrServer.sin_family=AF_INET;
|
||||
addrServer.sin_addr.s_addr=send_addr;//inet_addr("192.168.169.1");;//inet_addr("192.168.169.100");
|
||||
addrServer.sin_port=htons(*port);
|
||||
handle_data_protocol_fd = usr_protocol_create_client(*port);
|
||||
data_head_msg = (data_head *)photo_buf;
|
||||
while(1){
|
||||
if(walkmsg.run_state == 0)
|
||||
break;
|
||||
h264_fb = msi_get_fb(msi, 0);
|
||||
if (h264_fb){
|
||||
os_mutex_lock(&thread_lock, osWaitForever);
|
||||
h264 = (struct fb_h264_s *)h264_fb->priv;
|
||||
memset(data_head_msg,0,sizeof(data_head));
|
||||
data_head_msg->framenum = framenum;
|
||||
framenum++;
|
||||
data_head_msg->cnt = (h264_fb->len+MAX_VIDEO_PKT_LEN-1)/MAX_VIDEO_PKT_LEN;
|
||||
data_head_msg->frmtype = h264->type;
|
||||
framelen = h264_fb->len;
|
||||
CHILDREN_DBG("(%d %d %d)",data_head_msg->framenum,h264->type,framelen);
|
||||
client_frame.framenum = data_head_msg->framenum;
|
||||
client_frame.status = 0;
|
||||
|
||||
os_mutex_unlock(&thread_lock);
|
||||
|
||||
if(lostframe == 1){ //lost frame ,need to wait the I frame for re-send
|
||||
if(h264->type != 1){
|
||||
goto delete_frame;
|
||||
}
|
||||
}
|
||||
|
||||
if((oldcount + 1) != h264->count){
|
||||
if((h264->count == 2)&&(oldcount == 255)){
|
||||
if(lostframe == 1){
|
||||
if(h264->type != 1){
|
||||
CHILDREN_DBG("send slow,lost frame wait i frame\r\n");
|
||||
goto delete_frame;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(h264->type == 1){
|
||||
CHILDREN_DBG("frame lost ,but this frame is i frame ,send it\r\n");
|
||||
}else{
|
||||
CHILDREN_DBG("send slow ,lost frame ,wait I frame:%d %d\r\n",oldcount,h264->count);
|
||||
h264_reflash_new_gop(1,1);
|
||||
lostframe = 1;
|
||||
goto delete_frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lostframe = 0;
|
||||
|
||||
pktcnt = 0;
|
||||
datoffset = 0;
|
||||
|
||||
client_frame.lost_num = data_head_msg->cnt;
|
||||
framesuc = 1;
|
||||
while(framelen != 0){
|
||||
data_head_msg->pack = pktcnt;
|
||||
if(framelen >= MAX_VIDEO_PKT_LEN){
|
||||
framelen = framelen-MAX_VIDEO_PKT_LEN;
|
||||
memcpy(photo_buf+sizeof(data_head),h264_fb->data+datoffset,MAX_VIDEO_PKT_LEN);
|
||||
datoffset += MAX_VIDEO_PKT_LEN;
|
||||
sendlen = MAX_VIDEO_PKT_LEN;
|
||||
}else{
|
||||
memcpy(photo_buf+sizeof(data_head),h264_fb->data+datoffset,framelen);
|
||||
sendlen = framelen;
|
||||
framelen = 0;
|
||||
}
|
||||
len = sendto(handle_data_protocol_fd, (char*)photo_buf, sendlen+sizeof(data_head), MSG_DONTWAIT, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
|
||||
if(len >= 0)
|
||||
walkmsg.tx_data += len;
|
||||
pktcnt++;
|
||||
}
|
||||
net_h264_sema_up();
|
||||
ie = disable_irq();
|
||||
status_unlock = 1;
|
||||
enable_irq(ie);
|
||||
ret = net_h264_status_sema_down(200);
|
||||
|
||||
CHILDREN_DBG("status:%d lostnum:%d\r\n",client_frame.status,client_frame.lost_num);
|
||||
|
||||
framelen = h264_fb->len;
|
||||
pktcnt = 0;
|
||||
datoffset = 0;
|
||||
lostidx = 0;
|
||||
lostloop = 3; //所有丢包都重传3次,增加接收成功率
|
||||
|
||||
//if((walkmsg.speed >= 4) || (current_bss_bw == 5)) {
|
||||
if((walkmsg.speed >= 2)|| (current_bss_bw == 5) || (current_bss_bw == 10)) {
|
||||
lostloop = 1;
|
||||
}
|
||||
|
||||
if(client_frame.lost_num != 0){
|
||||
while(framelen != 0){
|
||||
data_head_msg->pack = pktcnt;
|
||||
if(framelen >= MAX_VIDEO_PKT_LEN){
|
||||
framelen = framelen-MAX_VIDEO_PKT_LEN;
|
||||
memcpy(photo_buf+sizeof(data_head),h264_fb->data+datoffset,MAX_VIDEO_PKT_LEN);
|
||||
datoffset += MAX_VIDEO_PKT_LEN;
|
||||
sendlen = MAX_VIDEO_PKT_LEN;
|
||||
}else{
|
||||
memcpy(photo_buf+sizeof(data_head),h264_fb->data+datoffset,framelen);
|
||||
sendlen = framelen;
|
||||
framelen = 0;
|
||||
}
|
||||
if(pktcnt == client_frame.lost_packet[lostidx]){
|
||||
lostidx++;
|
||||
for(itk = 0;itk < lostloop;itk++){
|
||||
len = sendto(handle_data_protocol_fd, (char*)photo_buf, sendlen+sizeof(data_head), MSG_DONTWAIT, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
|
||||
os_sleep_ms(1);
|
||||
if(len >= 0)
|
||||
walkmsg.tx_data += len;
|
||||
}
|
||||
}
|
||||
pktcnt++;
|
||||
}
|
||||
client_frame.status = 0;
|
||||
net_h264_sema_up();
|
||||
|
||||
ie = disable_irq();
|
||||
status_unlock = 1;
|
||||
enable_irq(ie);
|
||||
ret = net_h264_status_sema_down(200);
|
||||
|
||||
CHILDREN_DBG("status:%d down:%d\r\n",client_frame.status,ret);
|
||||
if(client_frame.status == 3){
|
||||
h264_reflash_new_gop(1,1);
|
||||
CHILDREN_DBG("frame already lost,wait I frame.......\r\n");
|
||||
framesuc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(framesuc){
|
||||
walkmsg.frame_tx_success++;
|
||||
}else{
|
||||
walkmsg.frame_tx_lost++;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(apsta_mode == 2){
|
||||
//ieee80211_conf_get_bssid(WIFI_MODE_STA,&connectmsg.addr);
|
||||
temp = ieee80211_conf_get_tx_mcs(WIFI_MODE_STA,NULL,0)&0xff;
|
||||
frmtype += (temp>>4)&0x0f;
|
||||
mcs += (temp&0x0f);
|
||||
}else{
|
||||
//ieee80211_conf_get_stalist(WIFI_MODE_AP,&connectmsg,1);
|
||||
temp = ieee80211_conf_get_tx_mcs(WIFI_MODE_AP,NULL,1)&0xff;
|
||||
frmtype += (temp>>4)&0x0f;
|
||||
mcs += (temp&0x0f);
|
||||
}
|
||||
mcslop++;
|
||||
if(mcslop == 10){
|
||||
mcslop = 0;
|
||||
walkmsg.mcs = mcs/10;
|
||||
walkmsg.frmtype = frmtype/10;
|
||||
mcs = 0;
|
||||
frmtype = 0;
|
||||
recfg_mclk_by_mcs(walkmsg.mcs,walkmsg.frmtype);
|
||||
}
|
||||
#else
|
||||
recfg_mclk_msg(dvp_dev,framesuc);
|
||||
|
||||
#endif
|
||||
|
||||
delete_frame:
|
||||
//_os_printf("U(%d %d)",h264->count,lostframe);
|
||||
oldcount = h264->count;
|
||||
msi_delete_fb(NULL, h264_fb);
|
||||
}else{
|
||||
os_sleep_ms(3);
|
||||
recfg_mclk_by_connect();
|
||||
}
|
||||
}
|
||||
close(handle_data_protocol_fd);
|
||||
msi_destroy(msi);
|
||||
msi_del_output(0, S_H264, "NET_H264");
|
||||
user_protocol_task_decrease();
|
||||
}
|
||||
|
||||
static uint16_t port_data;
|
||||
static uint16_t port_status;
|
||||
void udp_handle_client_init(uint16_t status_port,uint16_t data_port)
|
||||
{
|
||||
port_data = data_port;
|
||||
port_status = status_port;
|
||||
csi_kernel_task_new((k_task_entry_t)udp_handle_client_status_thread, "handle_udp_pkt", &port_status, 25, 0, NULL, 1024, &handle_task_recv);
|
||||
csi_kernel_task_new((k_task_entry_t)udp_handle_client_data_thread, "handle_data_udp_pkt", &port_data, 25, 0, NULL, 1024, &handle_data_task_recv);
|
||||
}
|
||||
|
||||
void udp_handle_client_deinit(void)
|
||||
{
|
||||
while(walkmsg.run_task > 0)
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
|
||||
void client_frame_msg_init(uint8_t frame_num,uint8_t timeout){
|
||||
client_frame.framenum = frame_num;
|
||||
client_frame.time = 0;
|
||||
client_frame.status = 0;
|
||||
client_frame.lost_num = 0;
|
||||
client_frame.timeout = timeout;
|
||||
memset(client_frame.lost_packet,0xff,100);
|
||||
}
|
||||
|
||||
|
||||
void protocol_client_init(uint16_t status_port,uint16_t data_port){
|
||||
os_mutex_init(&thread_lock);
|
||||
net_h264_sema_init();
|
||||
net_h264_status_sema_init();
|
||||
client_frame_msg_init(0,10);
|
||||
udp_handle_client_init(status_port,data_port);
|
||||
//net_tcp_sema_init();
|
||||
//tcp_handle_client_init();
|
||||
}
|
||||
|
||||
void protocol_client_deinit()
|
||||
{
|
||||
udp_handle_client_deinit();
|
||||
net_h264_status_sema_deinit();
|
||||
net_h264_sema_deinit();
|
||||
if(thread_lock.hdl) {
|
||||
os_mutex_del(&thread_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void user_protocol3(uint16_t status_port,uint16_t data_port)
|
||||
{
|
||||
protocol_client_init(status_port,data_port); //发送摄像头数据 STA
|
||||
}
|
||||
|
||||
void user_protocol3_deinit(void)
|
||||
{
|
||||
protocol_client_deinit();
|
||||
}
|
||||
|
||||
int32 atcmd_recv(uint8 *data, int32 len);
|
||||
int32 atcmd_current_bss_bw(const char *cmd, char *argv[], uint32 argc)
|
||||
{
|
||||
if(argc < 1) {
|
||||
os_printf("%s argc err:%d,enter the bss_bw\n",__FUNCTION__,argc);
|
||||
return 0;
|
||||
}
|
||||
if(argv[0]) {
|
||||
current_bss_bw = os_atoi(argv[0]);
|
||||
os_printf("\n***current_bss_bw:%d***\n",current_bss_bw);
|
||||
if(current_bss_bw == 20) {
|
||||
atcmd_recv((uint8_t*)"AT1+BSS_BW=20",0);
|
||||
lmac_set_beacon_modulation(NULL, LMAC_RATE_DSSS_CCK_RATE0);
|
||||
lmac_set_supp_rate(NULL, WIFI_TX_SUPP_RATE);
|
||||
}
|
||||
else if(current_bss_bw == 10) {
|
||||
atcmd_recv((uint8_t*)"AT1+BSS_BW=10",0);
|
||||
lmac_set_beacon_modulation(NULL, LMAC_RATE_NON_HT_RATE0);
|
||||
lmac_set_supp_rate(NULL, WIFI_TX_SUPP_RATE & 0xFFFFFFF0);
|
||||
}
|
||||
else if(current_bss_bw == 5) {
|
||||
atcmd_recv((uint8_t*)"AT1+BSS_BW=5",0);
|
||||
lmac_set_beacon_modulation(NULL, LMAC_RATE_NON_HT_RATE0);
|
||||
lmac_set_supp_rate(NULL, WIFI_TX_SUPP_RATE & 0xFFFFFFF0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void protocol_client_send_enable(uint8_t enable)
|
||||
{
|
||||
struct msi *h264_msi = NULL;
|
||||
h264_msi = msi_find(S_H264, 1);
|
||||
if(h264_msi) {
|
||||
msi_put(h264_msi);
|
||||
if(enable)
|
||||
msi_add_output(h264_msi, NULL, "NET_H264");
|
||||
else
|
||||
msi_del_output(h264_msi, NULL, "NET_H264");
|
||||
}
|
||||
}
|
||||
|
||||
int32 atcmd_client_send_enable(const char *cmd, char *argv[], uint32 argc)
|
||||
{
|
||||
if(argv[0]) {
|
||||
uint8_t enable = os_atoi(argv[0]);
|
||||
protocol_client_send_enable(enable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 atcmd_client_send_mode(const char *cmd, char *argv[], uint32 argc)
|
||||
{
|
||||
if(argv[0]) {
|
||||
ctrl_mode = os_atoi(argv[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user