Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

View File

@@ -0,0 +1,852 @@
#include "basic_include.h"
#include "csi_kernel.h"
#include "syscfg.h"
#include "lwip/sockets.h"
#include "lib/lcd/lcd.h"
#include "netif/ethernetif.h"
#include "stream_define.h"
#include "stream_frame.h"
#include "babyprotocol_h264.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 "hal/vpp.h"
#include "lib/umac/ieee80211.h"
#ifdef SYS_APP_BBM_CAM
// 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
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 k_task_handle_t handle_tcp_task_recv;
static int handle_protocol_fd = - 1;
static int handle_data_protocol_fd = - 1;
static int tcp_connect_fd = -1;
static volatile uint32 status_unlock = 0;
static in_addr_t client_addr = 0;
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 src_filter_type = FSTYPE_H264_GEN420_DATA;
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_sema_init()
{
os_sema_init(&net_h264_sem,0);
}
void net_h264_sema_down(int32 tmo_ms)
{
os_sema_down(&net_h264_sem,tmo_ms);
}
void net_h264_sema_up()
{
os_sema_up(&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)
{
static uint16_t oldw = 0;
struct fb_h264_s *h264;
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(src_filter_type != FSTYPE_H264_FILE) {
if(oldw != w_gol){
h264 = (struct fb_h264_s *)fb->priv; //切换分辨率时要以I帧为基础
if(h264->type == 1){
oldw = w_gol;
}
}
if(oldw == 1280) {
src_filter_type = FSTYPE_H264_VPP_DATA0;
}
else {
src_filter_type = FSTYPE_H264_GEN420_DATA;
}
}
if(fb->stype != src_filter_type)
{
ret = RET_ERR;
}
}
break;
case MSI_CMD_FREE_FB:
{
}
break;
default:
break;
}
return ret;
}
int usr_protocol_create_server(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)
{
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;
}
return socket_c;
}
void recfg_babymonitor_msg(uint8_t success){
static uint8_t did = 0;
static uint16_t last_still = 0;
static uint16_t last_move = 0;
uint16_t max_still;
uint16_t max_move;
static uint8_t success_frame_num = 0;
#if 0
static uint8_t framecnt = 0;
static uint32_t timeout = 0;
static uint8_t lost_frame_num = 0;
static uint8_t speed_level = 0;
static uint8_t last_speed_level = 0xff;
static uint8_t success_frame_num = 0;
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--;
}
}
if(last_speed_level != speed_level){
last_speed_level = speed_level;
babymsg.speed = speed_level;
}
}
framecnt = 0;
lost_frame_num = 0;
success_frame_num = 0;
}else{
if(success){
success_frame_num++;
}else{
lost_frame_num++;
}
framecnt++;
}
babymsg.speed = speed_level;
#else
if(success == 0){
success_frame_num = 0;
if(w_gol == 1280){
did = 1;
}else{
did = 2;
}
if(did == 1){
max_still = MAIN_SENSOR_STILL_MAX;
max_move = MAIN_SENSOR_MOVE_MAX;
}else{
max_still = SEC_SENSOR_STILL_MAX;
max_move = SEC_SENSOR_MOVE_MAX;
}
if(last_still == 0){
last_still = max_still;
last_move = max_move;
}
if(did == 1){
if(last_still > MAIN_SENSOR_STILL_MIN){
last_still = last_still - BPS_STEP;
last_move = last_move - BPS_STEP;
}else{
last_still = MAIN_SENSOR_STILL_MIN;
last_move = MAIN_SENSOR_MOVE_MIN;
}
}else{
if(last_still > SEC_SENSOR_STILL_MIN){
last_still = last_still - BPS_STEP;
last_move = last_move - BPS_STEP;
}else{
last_still = SEC_SENSOR_STILL_MIN;
last_move = SEC_SENSOR_MOVE_MIN;
}
}
h264_recfg_bsp(did,last_move,last_still);
h264_reflash_new_gop(did,1);
}else{
success_frame_num++;
if(success_frame_num == UP_BPS_FRM_NUM){
if(w_gol == 1280){
did = 1;
}else{
did = 2;
}
success_frame_num = 0;
if(did == 1){
if(last_still < MAIN_SENSOR_STILL_MAX){
last_still = last_still + BPS_STEP;
last_move = last_move + BPS_STEP;
}else{
last_still = MAIN_SENSOR_STILL_MAX;
last_move = MAIN_SENSOR_MOVE_MAX;
}
}else{
if(last_still < SEC_SENSOR_STILL_MAX){
last_still = last_still + BPS_STEP;
last_move = last_move + BPS_STEP;
}else{
last_still = SEC_SENSOR_STILL_MAX;
last_move = SEC_SENSOR_MOVE_MAX;
}
}
h264_recfg_bsp(did,last_move,last_still);
h264_reflash_new_gop(did,1);
}
}
#endif
}
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));
BABY_DBG("W");
}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);
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);
BABY_DBG("E(%d)",msg_head->framenum);
return;
}
BABY_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];
}
client_frame.status = 3;
}
os_mutex_unlock(&thread_lock);
ie = disable_irq();
if(status_unlock){
status_unlock = 0;
net_h264_status_sema_up();
}
enable_irq(ie);
}
void udp_handle_client_status_thread()
{
uint32 ie;
uint8_t loop_run;
uint16_t port = 6003;
uint8_t framenum;
uint32_t start_tmr = 0;
struct sockaddr_in addrServer;
memset(&addrServer,0,sizeof(struct sockaddr_in));
while(client_addr == 0){
os_sleep_ms(100);
}
addrServer.sin_family=AF_INET;
addrServer.sin_addr.s_addr=client_addr;//inet_addr("192.168.169.100");
addrServer.sin_port=htons(6003);
handle_protocol_fd = usr_protocol_create_server(port);
eloop_add_fd( handle_protocol_fd, EVENT_READ, EVENT_F_ENABLED, udp_handle_client_status_read_workqueue, 0 );
while(1){
// _os_printf("D");
net_h264_sema_down(-1); //wait for data send finish
BABY_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; //5ms都读不到对回复的状态,重发吧
os_sleep_ms(10);
loop_run++;
if(loop_run > 12) //重发8次后还是读不到状态,认命吧,你掉线了
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);
}
}
}
}
void udp_handle_client_data_thread(){
// uint8_t loop_run;
int32 ret;
uint32 ie;
uint8_t framesuc = 0;
// int init_count = 0;
// void *priv;
uint16_t port = 6002;
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;
// uint32_t start_tmr = 0;
struct sockaddr_in addrServer;
struct framebuff *h264_fb = NULL;
int len;
data_head *data_head_msg;
struct msi *msi;
uint32_t nal_reserve = 0;
msi = msi_new("NET_H264", MAX_USER_VIDEO_TX, NULL);
msi->action = net_video_msi_action;
msi->enable = 1;
while(client_addr == 0){
os_sleep_ms(100);
}
framenum = 0;
memset(&addrServer,0,sizeof(struct sockaddr_in));
addrServer.sin_family=AF_INET;
addrServer.sin_addr.s_addr=client_addr;//inet_addr("192.168.169.100");
addrServer.sin_port=htons(6002);
handle_data_protocol_fd = usr_protocol_create_server(port);
data_head_msg = (data_head *)photo_buf;
while(1){
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;
BABY_DBG("((%d)%d %d %d)",client_dev_magic,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 == 0)&&(oldcount == 255)){
if(lostframe == 1){
if(h264->type != 1){
BABY_DBG("send slow,lost frame wait i frame\r\n");
goto delete_frame;
}
}
}else{
if(h264->type == 1){
BABY_DBG("frame lost ,but this frame is i frame ,send it\r\n");
}else{
BABY_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;
nal_reserve = 0;
if(h264_fb->stype == FSTYPE_H264_FILE) {
if(h264->type == 1) {
nal_reserve = h264->pps_len + h264->sps_len + 12;
}
else if(h264->type == 2) {
nal_reserve = 4;
}
}
while(framelen != 0){
data_head_msg->pack = pktcnt;
if(nal_reserve > 0) {
if(h264->type == 1) {
*((uint32_t*)(photo_buf+sizeof(data_head))) = 0x1000000;
os_memcpy(photo_buf+sizeof(data_head)+4, h264->sps, h264->sps_len);
*((uint32_t*)(photo_buf+sizeof(data_head)+h264->sps_len+4)) = 0x1000000;
os_memcpy(photo_buf+sizeof(data_head)+h264->sps_len+8, h264->pps, h264->pps_len);
*((uint32_t*)(photo_buf+sizeof(data_head)+h264->pps_len+h264->sps_len+8)) = 0x1000000;
}
else {
*((uint32_t*)(photo_buf+sizeof(data_head))) = 0x1000000;
}
}
if(framelen >= (MAX_VIDEO_PKT_LEN - nal_reserve)){
framelen = framelen - (MAX_VIDEO_PKT_LEN-nal_reserve);
memcpy(photo_buf+sizeof(data_head)+nal_reserve,h264_fb->data+datoffset,(MAX_VIDEO_PKT_LEN-nal_reserve));
datoffset += (MAX_VIDEO_PKT_LEN-nal_reserve);
sendlen = MAX_VIDEO_PKT_LEN;
}else{
memcpy(photo_buf+sizeof(data_head)+nal_reserve,h264_fb->data+datoffset,framelen);
sendlen = framelen + nal_reserve;
framelen = 0;
}
if(nal_reserve > 0)
nal_reserve = 0;
len = sendto(handle_data_protocol_fd, (char*)photo_buf, sendlen+sizeof(data_head), MSG_DONTWAIT, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
pktcnt++;
}
net_h264_sema_up();
ie = disable_irq();
status_unlock = 1;
enable_irq(ie);
ret = net_h264_status_sema_down(200);
BABY_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(client_frame.lost_num != 0){
nal_reserve = 0;
if(h264_fb->stype == FSTYPE_H264_FILE) {
if(h264->type == 1) {
nal_reserve = h264->pps_len + h264->sps_len + 12;
}
else if(h264->type == 1) {
nal_reserve = 4;
}
}
if(nal_reserve > 0) {
if(h264->type == 1) {
*((uint32_t*)(photo_buf+sizeof(data_head))) = 0x1000000;
os_memcpy(photo_buf+sizeof(data_head)+4, h264->sps, h264->sps_len);
*((uint32_t*)(photo_buf+sizeof(data_head)+h264->sps_len+4)) = 0x1000000;
os_memcpy(photo_buf+sizeof(data_head)+h264->sps_len+8, h264->pps, h264->pps_len);
*((uint32_t*)(photo_buf+sizeof(data_head)+h264->pps_len+h264->sps_len+8)) = 0x1000000;
}
else {
*((uint32_t*)(photo_buf+sizeof(data_head))) = 0x1000000;
}
}
while(framelen != 0){
data_head_msg->pack = pktcnt;
if(framelen >= (MAX_VIDEO_PKT_LEN - nal_reserve)){
framelen = framelen - (MAX_VIDEO_PKT_LEN-nal_reserve);
memcpy(photo_buf+sizeof(data_head)+nal_reserve,h264_fb->data+datoffset,(MAX_VIDEO_PKT_LEN-nal_reserve));
datoffset += (MAX_VIDEO_PKT_LEN-nal_reserve);
sendlen = MAX_VIDEO_PKT_LEN;
}else{
memcpy(photo_buf+sizeof(data_head)+nal_reserve,h264_fb->data+datoffset,framelen);
sendlen = framelen + nal_reserve;
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(nal_reserve > 0)
nal_reserve = 0;
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);
BABY_DBG("status:%d down:%d\r\n",client_frame.status,ret);
if(client_frame.status == 3){
h264_reflash_new_gop(1,1);
BABY_DBG("frame maybe lost,produce I frame.......\r\n");
framesuc = 0;
}
}
recfg_babymonitor_msg(framesuc);
delete_frame:
//_os_printf("U(%d %d)",h264->count,lostframe);
oldcount = h264->count;
msi_delete_fb(NULL, h264_fb);
}else{
os_sleep_ms(3);
}
}
}
void udp_handle_client_init()
{
csi_kernel_task_new((k_task_entry_t)udp_handle_client_status_thread, "handle_udp_pkt", 0, 25, 0, NULL, 1024, &handle_task_recv);
csi_kernel_task_new((k_task_entry_t)udp_handle_client_data_thread, "handle_data_udp_pkt", 0, 25, 0, NULL, 1024, &handle_data_task_recv);
}
void user_tcp_write_workqueue(void *e, void *d){
int ret;
connect_cfg_head tcp_hand;
if(client_dev_magic == 0)
tcp_hand.type = 0;
else
tcp_hand.type = 1;
if(src_filter_type == FSTYPE_H264_FILE) {
tcp_hand.w = 1280;
tcp_hand.h = 720;
}
else {
tcp_hand.w = w_gol;
tcp_hand.h = h_gol;
}
tcp_hand.packet_len = MAX_VIDEO_PKT_LEN;
tcp_hand.ip_grp = 25;
tcp_hand.frame_rate = 20;
tcp_hand.dev_magic = client_dev_magic;
ret = send(tcp_connect_fd,&tcp_hand,sizeof(tcp_hand),0);
BABY_DBG("send tcp heartbeat:%d\r\n",ret);
}
void user_tcpClientread(void *e, void *d)
{
struct h264_device *h264_dev;
static struct msi *h264_msi;
static uint16_t w;
static uint16_t h;
int ret;
struct vpp_device *vpp_dev;
uint8_t tcpbuf[64];
connect_cfg_head tcp_hand;
h264_dev = (struct h264_device *)dev_get(HG_H264_DEVID);
vpp_dev = (struct vpp_device *)dev_get(HG_VPP_DEVID);
ret = read(tcp_connect_fd,tcpbuf,64);
if(ret > 0) {
//memcpy(&tcp_hand,tcpbuf,sizeof(tcp_hand));
memcpy(&tcp_hand,tcpbuf,sizeof(tcp_hand));
BABY_DBG("get len:%d tcpbuf:%02x w:%d h:%d............\r\n",ret,tcp_hand.type,tcp_hand.w,tcp_hand.h);
if(tcp_hand.type == 0){
heartbeat++;
}else if(tcp_hand.type == 3){
h264_reflash_new_gop(1,1);
vpp_open(vpp_dev);
}else if(tcp_hand.type == 4){
vpp_close(vpp_dev);
}else if(tcp_hand.type == 5){
client_dev_magic = tcp_hand.dev_magic;
}else{
BABY_DBG("start tran photo\r\n");
if(tcp_hand.type == 2){
if(client_dev_magic == 0) { //第一次连接
client_dev_magic = tcp_hand.dev_magic;
h264_msi = msi_find(AUTO_H264, 1);
if(h264_msi) {
msi_put(h264_msi);
msi_add_output(h264_msi, NULL, "NET_H264");
}
}
w = tcp_hand.w;
h = tcp_hand.h;
w_gol = w;
h_gol = h;
}
}
}else{
// _os_printf("%s %d\r\n",__func__,__LINE__);
eloop_remove_event( tcp_read_ev );
tcp_read_ev = NULL;
}
//net_tcp_sema_up();
}
void tcp_handle_client_thread(){ //摄像头端
// connect_cfg_head tcp_hand;
int32 isstaconnect;
int32 ret;
struct sockaddr_in addr;
os_memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(6001);
addr.sin_addr.s_addr = inet_addr("192.168.169.1");
os_sleep_ms(1000);
reconnect:
heartbeat = 0;
ret = connect(tcp_connect_fd, (const struct sockaddr *)&addr, sizeof(struct sockaddr));
if(ret < 0){
closesocket(tcp_connect_fd);
tcp_connect_fd = socket(AF_INET, SOCK_STREAM, 0);
printf("connect error(%d)..\r\n",tcp_connect_fd);
os_sleep_ms(500);
goto reconnect;
}else{
printf("connect finish\r\n");
}
client_addr = addr.sin_addr.s_addr;
tcp_read_ev = eloop_add_fd( tcp_connect_fd, EVENT_READ, EVENT_F_ENABLED, user_tcpClientread, 0 );
#if 1
while(1){
ip_addr_t ipaddr;
ipaddr = lwip_netif_get_ip2("w0");
isstaconnect = ieee80211_conf_get_stacnt(WIFI_MODE_STA);
BABY_DBG("ipaddr:%x sta:%d\r\n",ipaddr.addr,ieee80211_conf_get_stacnt(WIFI_MODE_STA));
if(isstaconnect == 0){ //我们为sta,发现连接数为0则表示当前连接断开tcp事件关闭并等待重连
_os_printf("sta lost connect,reconnect TCP \r\n");
eloop_remove_event( tcp_read_ev );
tcp_read_ev = NULL;
}
if(tcp_read_ev == NULL){
closesocket( tcp_connect_fd );
tcp_connect_fd = -1;
tcp_connect_fd = socket(AF_INET, SOCK_STREAM, 0);
os_sleep_ms(500);
goto reconnect;
}else{
eloop_add_alarm(os_jiffies(),EVENT_F_ENABLED,user_tcp_write_workqueue,0);
}
os_sleep_ms(1000);
}
#endif
}
void tcp_handle_client_thread_init(){
tcp_connect_fd = socket(AF_INET, SOCK_STREAM, 0);
csi_kernel_task_new((k_task_entry_t)tcp_handle_client_thread, "handle_connect_tcp_pkt", NULL, 25, 0, NULL, 1024, &handle_tcp_task_recv);
}
void tcp_handle_client_init(){
tcp_handle_client_thread_init();
}
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(){
os_mutex_init(&thread_lock);
net_h264_sema_init();
net_h264_status_sema_init();
client_frame_msg_init(0,10);
udp_handle_client_init();
//net_tcp_sema_init();
tcp_handle_client_init();
}
void protocol_client_send_enable(uint8_t enable)
{
struct msi *h264_msi = NULL;
h264_msi = msi_find(AUTO_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");
}
}
void protocol_client_filtertype(uint8_t type)
{
src_filter_type = type;
}
void user_protocol()
{
protocol_client_filtertype(FSTYPE_H264_GEN420_DATA);
protocol_client_init(); //发送摄像头数据 STA
}
#endif

View File

@@ -0,0 +1,116 @@
#ifndef _PHOTO_TRAN_PROTOCOL_
#define _PHOTO_TRAN_PROTOCOL_
#include "osal/string.h"
#include "lib/net/eloop/eloop.h"
//#define OPEN_DBG 1
#if OPEN_DBG
#define BABY_DBG(fmt, ...) _os_printf(fmt, ##__VA_ARGS__)
#else
#define BABY_DBG(fmt, ...)
#endif
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;
EVT_HDL udp_read_status_ev;
uint32_t udp_data_task;
uint32_t dev_id;
uint32_t frame_rate;
uint8_t *psram_photo;
uint8_t larger;
uint16_t w;
uint16_t h;
}dev_map;
typedef struct
{
uint8_t speed;
uint8_t frame_tx_lost;
uint8_t frame_tx_success;
uint8_t frame_rx_lost;
uint8_t frame_rx_success;
}babymonitor_msg;
typedef struct
{
uint32_t target_width;
uint32_t target_high;
}target_resolution;
#define MAIN_SENSOR_STILL_MIN 300
#define MAIN_SENSOR_STILL_MAX 600
#define MAIN_SENSOR_MOVE_MIN 800
#define MAIN_SENSOR_MOVE_MAX 1500
#define SEC_SENSOR_STILL_MIN 200
#define SEC_SENSOR_STILL_MAX 400
#define SEC_SENSOR_MOVE_MIN 400
#define SEC_SENSOR_MOVE_MAX 1000
#define BPS_STEP 50
#define UP_BPS_FRM_NUM 25
#ifdef SYS_APP_BBM_LCD
extern void protocol_server_change_resolution(uint8_t id,uint32_t width, uint32_t high);
#endif
#endif

View File

@@ -0,0 +1,104 @@
#include "basic_include.h"
#include "stream_define.h"
#include "lib/multimedia/msi.h"
#include "video_app_h264_msi.h"
#include "audio_msi/audio_adc.h"
#include "audio_media_ctrl/audio_code_ctrl.h"
#include "intercom/intercom.h"
#include "babyprotocol_playback.h"
#include "babyprotocol_h264.h"
#ifdef SYS_APP_BBM_CAM
extern struct msi *mp4_demux_msi_init(const char *msi_name, const char *filename);
extern void protocol_client_filtertype(uint8_t type);
static struct msi *playback_msi = NULL;
static struct msi *aac_msi = NULL;
int32_t client_remote_playback_init(const char *filename)
{
struct msi *opus_msi = NULL;
AUDEC_INIT audec_init;
if(playback_msi) {
msi_destroy(playback_msi);
audio_decode_deinit(aac_msi);
}
audec_init.track_type = MEDIA_TRACK;
audec_init.priority = play_interruptible;
audec_init.direct_to_dac = 0;
audec_init.destroy_self = 0;
audec_init.use_tpc = 0;
audec_init.src_msi = NULL;
aac_msi = audio_decode_init(AAC_DEC, 8000, &audec_init);
if(aac_msi == NULL) {
return RET_ERR;
}
protocol_client_filtertype(FSTYPE_H264_FILE);
intercom_encode_pause(1, 1);
opus_msi = msi_find("SR_OPUS_ENCODE", 1);
if(opus_msi) {
msi_put(opus_msi);
audio_code_set_src_msi(opus_msi, aac_msi);
}
intercom_encode_pause(0, 0);
os_sleep_ms(100);
playback_msi = mp4_demux_msi_init("bbm_playback_mp4", filename);
if(playback_msi) {
msi_add_output(playback_msi, NULL, "NET_H264");
audio_code_set_src_msi(aac_msi, playback_msi);
intercom_set_stream_type(intercom_live_audio, intercom_playback_audio);
msi_do_cmd(playback_msi, MSI_CMD_VIDEO_DEMUX_CTRL, MSI_VIDEO_DEMUX_START, 0);
return RET_OK;
}
audio_decode_deinit(aac_msi);
return RET_ERR;
}
int32_t client_remote_playback_deinit(void)
{
struct msi *opus_msi = NULL;
if(playback_msi) {
msi_destroy(playback_msi);
os_sleep_ms(100);
protocol_client_filtertype(FSTYPE_H264_GEN420_DATA);
audio_decode_deinit(aac_msi);
intercom_encode_pause(1, 1);
opus_msi = msi_find("SR_OPUS_ENCODE", 1);
if(opus_msi) {
msi_put(opus_msi);
audio_code_set_src_msi(opus_msi, get_auadc_msi(AUSYS_AUAD));
}
intercom_set_stream_type(intercom_live_audio, intercom_live_audio);
intercom_encode_pause(0, 0);
}
playback_msi = NULL;
return RET_OK;
}
static uint32_t playback = 0;
static uint8_t playback_file_name[50] = {0};
static void mp4_playback_thread(void *d)
{
if(playback == 1) {
os_printf("\n***playback:%s***\n",playback_file_name);
client_remote_playback_init((const char*)playback_file_name);
}
else if(playback == 0) {
client_remote_playback_deinit();
}
}
int32 atcmd_bbm_client_playback(const char *cmd, char *argv[], uint32 argc)
{
if(argc >= 2) {
playback = os_atoi(argv[1]);
os_memset(playback_file_name, 0, 50);
os_memcpy(playback_file_name,argv[0],strlen(argv[0]));
os_task_create("mp4_playback_thread", mp4_playback_thread, NULL, OS_TASK_PRIORITY_NORMAL, 0, NULL, 2048);
}
return 0;
}
#endif

View File

@@ -0,0 +1,7 @@
#ifndef _BABYPROCOL_PLAYBACK_H_
#define _BABYPROCOL_PLAYBACK_H_
extern int32_t client_remote_playback_init(const char *filename);
extern int32_t client_remote_playback_deinit(void);
#endif

View File

@@ -0,0 +1,108 @@
#include "basic_include.h"
#include "stream_define.h"
#include "lib/multimedia/msi.h"
#include "video_app_h264_msi.h"
#include "audio_media_ctrl/audio_code_ctrl.h"
#include "audio_msi/audio_adc.h"
#include "intercom/intercom.h"
#include "babyprotocol_record.h"
#include "app/video_app/file_thumb.h"
#include "recorder/file_process.h"
#include "fs/fatfs/osal_file.h"
#include "app/loop_record_moudle/loop_record_moudle.h"
#include "app/video_app/file_common_api.h"
#ifdef SYS_APP_BBM_CAM
struct msi *mp4_encode_msi2_init(const char *mp4_msi_name, uint8_t srcID, uint8_t filter_type, uint8_t rec_time,
uint32_t audio_encode, struct file_process *file_process, uint8_t mode);
static struct msi *rec_msi = NULL;
static struct msi *h264_msi = NULL;
static struct msi *aac_msi = NULL;
int32_t client_local_record_init(uint32_t record_time_minutes)
{
AUENC_INIT auenc_init;
if(!rec_msi) {
h264_msi = msi_find(AUTO_H264, 1);
if(h264_msi) {
msi_put(h264_msi);
auenc_init.destroy_self = 0;
auenc_init.src_msi = get_auadc_msi(AUSYS_AUAD);
aac_msi = audio_encode_init(AAC_ENC, audio_adc_get_samplerate(AUSYS_AUAD), &auenc_init);
if(!aac_msi) {
h264_msi = NULL;
return RET_ERR;
}
struct file_process mp4_file_process = {
.loop = NULL,
.rec_path = REC_PATH,
.ext_name = MP4_EXTENSION_NAME,
.create_file = rec_create_file,
.loop_free = rec_loop_free,
.lock_file = NULL,
};
rec_msi = mp4_encode_msi2_init("bbm_record_mp4", FRAMEBUFF_SOURCE_CAMERA0, FSTYPE_H264_VPP_DATA0,
record_time_minutes, AAC_ENC, &mp4_file_process, 0);
if(rec_msi) {
msi_add_output(h264_msi, NULL, "bbm_record_mp4");
audio_code_add_output(aac_msi, "bbm_record_mp4");
msi_do_cmd(rec_msi, MSI_CMD_MEDIA_CTRL, MSI_MEDIA_CTRL_RECORD_START, 0);
return RET_OK;
}
else {
h264_msi = NULL;
audio_encode_deinit(aac_msi);
aac_msi = NULL;
return RET_ERR;
}
}
else {
return RET_ERR;
}
}
return RET_OK;
}
int32_t client_local_record_deinit(void)
{
if(rec_msi) {
if(h264_msi) {
msi_del_output(h264_msi, NULL, "bbm_record_mp4");
}
if(aac_msi) {
audio_code_del_output(aac_msi, "bbm_record_mp4");
audio_encode_deinit(aac_msi);
}
msi_destroy(rec_msi);
rec_msi = NULL;
h264_msi = NULL;
aac_msi = NULL;
}
return RET_OK;
}
static uint32_t mp4_record = 0;
static void mp4_record_thread(void *d)
{
uint32_t state = *((uint32_t*)d);
if(state == 1) {
client_local_record_init(1);
}
else if(state == 0) {
client_local_record_deinit();
}
}
int32 atcmd_bbm_client_record(const char *cmd, char *argv[], uint32 argc)
{
if(argc >= 1) {
mp4_record = os_atoi(argv[0]);
os_task_create("mp4_record_thread", mp4_record_thread, &mp4_record, OS_TASK_PRIORITY_NORMAL, 0, NULL, 1024);
}
return 0;
}
#endif

View File

@@ -0,0 +1,7 @@
#ifndef _BABYPROTOCOL_RECORD_H_
#define _BABYPROTOCOL_RECORD_H_
extern int32_t client_local_record_init(uint32_t record_time_minutes);
extern int32_t client_local_record_deinit(void);
#endif

View File

@@ -0,0 +1,975 @@
#include "basic_include.h"
#include "csi_kernel.h"
#include "lwip/sockets.h"
#include "lib/lcd/lcd.h"
#include "netif/ethernetif.h"
#include "stream_define.h"
#include "stream_frame.h"
#include "babyprotocol_h264.h"
#include "lib/multimedia/msi.h"
#include "lib/heap/av_heap.h"
#include "lib/heap/av_psram_heap.h"
#include "scale_msi/scale_msi.h"
#include "lib/video/h264/h264_drv.h"
#ifdef SYS_APP_BBM_LCD
// 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
static int8_t next_switch_device = 2;
static int8_t cur_switch_device = 2;
//static struct os_semaphore net_h264_sem = {0,NULL};
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];
static int tcp_connect_fd = -1;
//static k_task_handle_t handle_tcp_task_recv;
//static in_addr_t client_addr = 0;
volatile uint32 server_frame_rate;
#define STA_NUM 2
#define DEC_TABLE_NUM 32
decode_msg decmsg[DEC_TABLE_NUM];
uint32_t devnum = 0;
dev_map devtab[11];
frame_msg server_frame[10];
static volatile target_resolution server_resolution[STA_NUM];
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;
EVT_HDL udp_read_status_ev;
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);
extern void get_h264_stream_w_h(uint16_t* w,uint16_t* h,uint8_t *h264data);
void net_h264_sema_init()
{
os_msgq_init(&net_h264_msg,4);
}
uint32 net_h264_sema_down(int32 tmo_ms)
{
uint32 retval;
uint32 retdata;
//os_sema_down(&net_h264_sem,tmo_ms);
retdata = os_msgq_get2(&net_h264_msg, tmo_ms, (int32_t*)(&retval));
if(retval == 0){
return retdata;
}else{
return retval;
}
}
void net_h264_sema_up(uint32 clientaddr)
{
int32 ret;
ret = os_msgq_put(&net_h264_msg, clientaddr, osWaitForever);
if(ret != 0){
_os_printf("wakeup msg err:%d\r\n",ret);
}
}
int usr_protocol_create_server(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)
{
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;
}
return socket_c;
}
int usr_protocol_create_server_with_ip(uint16_t port,uint32_t ipaddr)
{
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);//ipaddr;//
//_os_printf("IP:%x %x %x\r\n",ipaddr,htons(INADDR_ANY),inet_addr("192.168.169.100"));
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;
}
return socket_c;
}
void udp_handle_server_status_write_workqueue(void *ei, void *d){
int tos;
struct sockaddr_in *addrServer;
status_msg *msg_head;
char buf[12];
int len;
uint8_t itk;
uint8_t id = 0;
uint8_t fd;
addrServer = d;
for(itk = 0;itk < 10;itk++){
if(addrServer->sin_addr.s_addr == devtab[itk].ipaddr){
id = devtab[itk].dev_id;
fd = devtab[itk].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));
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));
}
void udp_handle_server_status_read_workqueue(void *ei, void *status_fd){
int tos;
int retval;
int ret;
uint8_t itk;
uint8_t handlebuf[96];
struct sockaddr remote_addr;
struct sockaddr_in *addrServer;
status_msg *msg_head;
uint8_t id = 0;
msg_head = (status_msg *)handlebuf;
retval = 16;
int32_t fd = (int32_t)status_fd;
ret = recvfrom (fd, handlebuf, 24, 0, &remote_addr, (socklen_t*)&retval);
// _os_printf(" G");
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;
}
}
if((id == 0)||(id > 3)) //当前设备号不存在,先只支持三台设备
{
BABY_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){
BABY_DBG("L(%d %d)",id,server_frame[id].lost_num);
}else{
BABY_DBG("R%d",id);
}
if(server_frame[id].framenum != msg_head->framenum){
BABY_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;
}
BABY_DBG("S(%d %d)",id,msg_head->type);
tos = IPTOS_PREC_NETCONTROL; // 最高优先级
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
sendto(fd, handlebuf, 2+server_frame[id].lost_num, MSG_DONTWAIT, &remote_addr, sizeof(struct sockaddr));
tos = IPTOS_PREC_ROUTINE; // 最低优先级
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
}
void udp_handle_server_status_thread(void *d){
struct sockaddr_in addrServer;
in_addr_t cli_addr;
dev_map *dev_tbl;
dev_tbl = d;
memset(&addrServer,0,sizeof(struct sockaddr_in));
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(6003);
//dev_tbl->udp_read_status_ev = eloop_add_fd( dev_tbl->udp_status_fd, EVENT_READ, EVENT_F_ENABLED, udp_handle_server_status_read_workqueue, &dev_tbl->udp_status_fd );
dev_tbl->udp_read_status_ev = eloop_add_fd( handle_protocol_fd, EVENT_READ, EVENT_F_ENABLED, udp_handle_server_status_read_workqueue, (void*)handle_protocol_fd );
while(1){
cli_addr = net_h264_sema_down(-1);
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
}
}
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 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 = 0;
uint16_t h = 0;
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 = 0;
uint8_t type[10];
uint8_t cntnum[10];
uint8_t pktnum[10];
uint8_t *fbuf;
uint32 ie;
uint8_t *psarm_room = NULL;
data_head *frame_hand;
retval = 16;
//framenum = 0xffff; //初始化值
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){
//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(next_switch_device == -1) {
continue;
}
id = 0;
for(itk = 0;itk < 10;itk++){
if(remote_addr.sin_addr.s_addr == devtab[itk].ipaddr){
id = devtab[itk].dev_id;
psarm_room = devtab[itk].psram_photo;
framerate = devtab[itk].frame_rate;
w = devtab[itk].w;
h = devtab[itk].h;
break;
}
}
if((id == 0)||(id > 3)) //当前设备号不存在,先只支持三台设备
{
BABY_DBG("no this client dev....");
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;
}
if(framenum[id] != frame_hand->framenum){
if(framenum[id] != 0xffff){
if(cntnum[id] != pktnum[id]){
BABY_DBG("lost frame\r\n");
}
}
BABY_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{ //真实意义上的丢失了
if(type[id] != 1){ //不是I帧
os_printf("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;
}
}
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);
sys_dcache_invalid_range((uint32_t*)fbuf,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++;
BABY_DBG("w:%d h:%d id:%d len:%d\r\n",w,h,id,framelen[id]);
enable_irq(ie);
break;
}
}
}
if(itk == DEC_TABLE_NUM) {
os_printf("No room for dec!\r\n");
push_lcd_success[id] = 0;
}
if((os_jiffies() - timer_ref2) > 2000){
dispnum = dispnum_cnt;
dispnum_cnt = 0;
timer_ref2 = os_jiffies();
}
dispnum_cnt++;
oldframecnt[id] = framenum[id];
net_h264_sema_up(remote_addr.sin_addr.s_addr);
}
}
}
extern volatile uint8_t scaler2_dev_id;
void udp_handle_server_decode_to_lcd_thread(){
int itk = 0;
uint16 w,h;
uint16 oldw[STA_NUM];
uint16 oldh[STA_NUM];
uint8_t *h264dat;
uint8_t disp_num;
uint8_t decframe[3];
uint32_t timeinf[3];
// uint32_t dsptime;
// uint32_t newdspt;
struct scale_device *scale_dev;
uint32 ie;
// uint16 oldframecnt = 0xffff;
// uint8 frame_gop_lost = 1;
uint8_t flush_video;
uint8_t change_pixel = 0;
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);
while(1){
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){
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(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;
}
scale2_recfg_input_size(w,h,decmsg[decframe[itk]].devid);
oldw[decmsg[decframe[itk]].devid] = w;
oldh[decmsg[decframe[itk]].devid] = h;
}
if((oldw[decmsg[decframe[itk]].devid] != server_resolution[decmsg[decframe[itk]].devid].target_width) || (oldh[decmsg[decframe[itk]].devid] != server_resolution[decmsg[decframe[itk]].devid].target_high)){
BABY_DBG("drop:%d %d\r\n",decmsg[decframe[itk]].devid,decmsg[decframe[itk]].num);
}else{
if(next_switch_device == 2) {
if(cur_switch_device != next_switch_device) {
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
cur_switch_device = next_switch_device;
}
if(decmsg[decframe[itk]].devid == 0) {
scale2_output_larger_local_change(decmsg[decframe[itk]].devid, devtab[decmsg[decframe[itk]].devid].larger);
scale2_output_size_local_change(decmsg[decframe[itk]].devid,0,0,0,320,360);
}
else {
scale2_output_larger_local_change(decmsg[decframe[itk]].devid, devtab[decmsg[decframe[itk]].devid].larger);
scale2_output_size_local_change(decmsg[decframe[itk]].devid,0,320,0,320,360);
}
scale2_cfg_run(H264_DEC,decmsg[decframe[itk]].devid);
h264_dec_src_264(decmsg[decframe[itk]].addr,decmsg[decframe[itk]].len,oldw[decmsg[decframe[itk]].devid],16*((oldh[decmsg[decframe[itk]].devid]+15)/16) ,decmsg[decframe[itk]].devid);
}
else if(next_switch_device == 0) {
if(decmsg[decframe[itk]].devid == 0) {
if(cur_switch_device != next_switch_device) {
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
cur_switch_device = next_switch_device;
}
scale2_output_larger_local_change(decmsg[decframe[itk]].devid, devtab[decmsg[decframe[itk]].devid].larger);
scale2_output_size_local_change(decmsg[decframe[itk]].devid,1,0,0,640,360);
scale2_cfg_run(H264_DEC,decmsg[decframe[itk]].devid);
h264_dec_src_264(decmsg[decframe[itk]].addr,decmsg[decframe[itk]].len,oldw[decmsg[decframe[itk]].devid],16*((oldh[decmsg[decframe[itk]].devid]+15)/16) ,decmsg[decframe[itk]].devid);
}
}
else if(next_switch_device == 1){
if(decmsg[decframe[itk]].devid == 1) {
if(cur_switch_device != next_switch_device) {
msi_cmd(R_VIDEO_P0, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 0);
msi_cmd(R_VIDEO_P1, MSI_CMD_LCD_VIDEO, MSI_VIDEO_ENABLE, 1);
cur_switch_device = next_switch_device;
}
scale2_output_larger_local_change(decmsg[decframe[itk]].devid,devtab[decmsg[decframe[itk]].devid].larger);
scale2_output_size_local_change(decmsg[decframe[itk]].devid,1,0,0,640,360);
scale2_cfg_run(H264_DEC,decmsg[decframe[itk]].devid);
h264_dec_src_264(decmsg[decframe[itk]].addr,decmsg[decframe[itk]].len,oldw[decmsg[decframe[itk]].devid],16*((oldh[decmsg[decframe[itk]].devid]+15)/16) ,decmsg[decframe[itk]].devid);
}
}
}
}
else{
change_pixel = 1;
}
av_psram_free(decmsg[decframe[itk]].addr);
ie = disable_irq();
frame_for_dec--;
decmsg[decframe[itk]].addr = NULL;
enable_irq(ie);
}
}
}
}
}
}
void udp_photo_handle_server_thread(uint32_t ipaddr,uint8_t tab){
k_task_handle_t handle_task_recv;
k_task_handle_t handle_data_task_recv;
uint16_t port = 6003;
handle_protocol_table_fd[tab] = usr_protocol_create_server_with_ip(port,ipaddr);
port = 6002;
handle_data_protocol_table_fd[tab] = usr_protocol_create_server_with_ip(port,ipaddr);
BABY_DBG("build_fd:%d %d\r\n",handle_protocol_table_fd[tab],handle_data_protocol_table_fd[tab]);
devtab[tab].udp_status_fd = handle_protocol_table_fd[tab];
devtab[tab].udp_data_fd = handle_data_protocol_table_fd[tab];
csi_kernel_task_new((k_task_entry_t)udp_handle_server_status_thread, "handle_udp_pkt", &devtab[tab], 25, 0, NULL, 1024, &handle_task_recv);
csi_kernel_task_new((k_task_entry_t)udp_handle_server_data_thread, "handle_data_udp_pkt", &devtab[tab], 25, 0, NULL, 1024, &handle_data_task_recv);
devtab[tab].udp_status_task = (uint32_t)handle_task_recv;
devtab[tab].udp_data_task = (uint32_t)handle_data_task_recv;
BABY_DBG("devtab: status->%d data->%d status_Task:%x data_Task:%x\r\n",devtab[tab].udp_status_fd,devtab[tab].udp_data_fd,devtab[tab].udp_status_task,devtab[tab].udp_data_task);
}
void udp_handle_server_init()
{
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;
uint16_t port = 6003;
handle_protocol_fd = usr_protocol_create_server(port);
port = 6002;
handle_data_protocol_fd = usr_protocol_create_server(port);
csi_kernel_task_new((k_task_entry_t)udp_handle_server_status_thread, "handle_udp_pkt", &handle_protocol_fd, 25, 0, NULL, 1024, &handle_task_recv);
csi_kernel_task_new((k_task_entry_t)udp_handle_server_data_thread, "handle_data_udp_pkt", &handle_data_protocol_fd, 25, 0, NULL, 1024, &handle_data_task_recv);
BABY_DBG("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);
}
static void tcp_handle_server( void *ei, void *d ){
int ret;
// struct msi *scaler_msi;
int maskid = 0;
uint8_t itk = 0;
uint8_t jtk = 0;
uint32_t ip = 0;
uint8_t dev = 0;
uint8_t tab_idx;
// static uint8_t test_recfg = 0;
connect_cfg_head tcp_hand;
uint8_t tcpread[64];
int tcp_fd = (int)d;
ret = read(tcp_fd,tcpread,64);
if(ret > 0){
memcpy(&tcp_hand,tcpread,sizeof(tcp_hand));
BABY_DBG("get len:%d type:%02x w:%d h:%d............\r\n",ret,tcp_hand.type,tcp_hand.w,tcp_hand.h);
if(tcp_hand.type == 2){
tcp_hand.type = 2;
tcp_hand.w = tcp_hand.w;
tcp_hand.h = tcp_hand.h;
tcp_hand.frame_rate = 25;
tcp_hand.ip_grp = 25;
tcp_hand.packet_len = MAX_VIDEO_PKT_LEN;
ret = send(tcp_fd,&tcp_hand,sizeof(tcp_hand),0);
BABY_DBG("set tcp cfg:%d\r\n",ret);
}else if(tcp_hand.type == 0){
BABY_DBG("tcp get cfg:%d\r\n",tcp_hand.dev_magic);
if(tcp_hand.dev_magic == 0){ //新设备刚开机
tcp_hand.type = 2;
tcp_hand.w = 640;//640;
tcp_hand.h = 360;//360;
tcp_hand.frame_rate = 20;
tcp_hand.ip_grp = 25;
tcp_hand.packet_len = MAX_VIDEO_PKT_LEN;
tcp_hand.dev_magic = 0;
for(itk = 0;itk < 10;itk++){
if(tcp_fd == devtab[itk].tcpfd){
if(devtab[itk].dev_id != 0){
tcp_hand.dev_magic = devtab[itk].dev_id;
}
ip = devtab[itk].ipaddr;
}
}
if(tcp_hand.dev_magic == 0){
tcp_hand.dev_magic = ((ip>>24)&(STA_NUM-1)) + 1; //控制设备编号
}
ret = send(tcp_fd,&tcp_hand,sizeof(tcp_hand),0);
BABY_DBG("start client run:%d\r\n",ret);
}else{ //这个设备已经开机过了
for(itk = 0;itk < 10;itk++){
if(tcp_fd == devtab[itk].tcpfd){
devtab[itk].dev_id = tcp_hand.dev_magic;
devtab[itk].frame_rate = tcp_hand.frame_rate;
devtab[itk].w = tcp_hand.w;
devtab[itk].h = tcp_hand.h;
}
}
}
} else if(tcp_hand.type == 1){ //client心跳包
BABY_DBG("heartbeat...\r\n");
for(itk = 0;itk < 10;itk++){
if(tcp_hand.dev_magic == devtab[itk].dev_id){ //查看client的心跳包是否有记录在table中
//magic id存在但与设备号的不匹配
for(jtk = 0;jtk < 10;jtk++){
if(tcp_fd == devtab[jtk].tcpfd){
ip = devtab[jtk].ipaddr;
}
}
os_printf("check ip addr(%d %08x %d)",tcp_fd,ip,tcp_hand.dev_magic);
if((((ip>>24)&(STA_NUM-1)) + 1) != tcp_hand.dev_magic){ //根据ip地址分配的设备号匹配不上那得给对面设备重新配置
tcp_hand.type = 5;
tcp_hand.dev_magic = ((ip>>24)&(STA_NUM-1)) + 1;
ret = send(tcp_fd,&tcp_hand,sizeof(tcp_hand),0);
BABY_DBG("reset devid:%d ip:%x set id:%d\r\n",ret,ip,tcp_hand.dev_magic);
maskid = tcp_hand.dev_magic;
dev = maskid;
}else{
maskid = tcp_hand.dev_magic;
devtab[itk].w = tcp_hand.w; //更新心跳过来的设备长度
devtab[itk].h = tcp_hand.h;
dev = maskid;
}
}
}
if(maskid == 0){ //client心跳有但table中却没有此信息
for(itk = 0;itk < 10;itk++){
if(tcp_fd == devtab[itk].tcpfd){
devtab[itk].dev_id = tcp_hand.dev_magic; //把当前设备号记录下来
devtab[itk].frame_rate = tcp_hand.frame_rate;
devtab[itk].w = tcp_hand.w;
devtab[itk].h = tcp_hand.h;
devtab[itk].psram_photo = av_psram_malloc(200*1024); //给初始化空间 200K
dev = devtab[itk].dev_id;
}
}
}
//dev是对面给过来的,这里是心跳包,对方肯定已经开机并且有了设备号
dev--; //设备是从1开始,所以这里得--
if((server_resolution[dev].target_width != devtab[itk].w) || (server_resolution[dev].target_high != devtab[itk].h)) {
tcp_hand.type = 2;
tcp_hand.w = server_resolution[dev].target_width;
tcp_hand.h = server_resolution[dev].target_high;
tcp_hand.frame_rate = 20;
tcp_hand.ip_grp = 25;
tcp_hand.packet_len = MAX_VIDEO_PKT_LEN;
ret = send(tcp_fd,&tcp_hand,sizeof(tcp_hand),0);
}
//分辨率切换操作
#if 0
//if(test_recfg == 0)
{
test_recfg++;
//if(os_jiffies() > 10000)
if(test_recfg % 30 == 19)
{
os_printf("recfg size(%d)...\r\n",dev);
tcp_hand.type = 2;
if(tcp_hand.w == 1280){
tcp_hand.w = 640;
tcp_hand.h = 360;
server_resolution[dev].target_width = 640;
server_resolution[dev].target_high = 360;
}else{
tcp_hand.w = 1280;
tcp_hand.h = 720;
server_resolution[dev].target_width = 1280;
server_resolution[dev].target_high = 720;
}
tcp_hand.frame_rate = 20;
tcp_hand.ip_grp = 25;
tcp_hand.packet_len = MAX_VIDEO_PKT_LEN;
ret = send(tcp_fd,&tcp_hand,sizeof(tcp_hand),0);
//test_recfg = 1;
}else if(test_recfg % 60 == 26){
_os_printf("recfg size2(%d)...\r\n",dev);
tcp_hand.type = 2;
if(tcp_hand.w == 1280){
tcp_hand.w = 640;
tcp_hand.h = 360;
server_resolution[dev].target_width = 640;
server_resolution[dev].target_high = 360;
}else{
tcp_hand.w = 1280;
tcp_hand.h = 720;
server_resolution[dev].target_width = 1280;
server_resolution[dev].target_high = 720;
}
tcp_hand.frame_rate = 20;
tcp_hand.ip_grp = 25;
tcp_hand.packet_len = MAX_VIDEO_PKT_LEN;
ret = send(tcp_fd,&tcp_hand,sizeof(tcp_hand),0);
}
}
#endif
}
}else{
BABY_DBG("tcp read close fd....\r\n");
eloop_remove_event( ei );
closesocket( tcp_fd );
for(itk = 0;itk < 10;itk++){
if(tcp_fd == devtab[itk].tcpfd){ //释放的FD是存在于table表的确定没有进行重新连接
devtab[itk].tcpfd = 0;
devtab[itk].ipaddr= 0;
devtab[itk].dev_id= 0;
devtab[itk].frame_rate = 0;
av_psram_free(devtab[itk].psram_photo);
devtab[itk].psram_photo = NULL;
tab_idx = itk;
}
}
devnum--;
tcp_fd = -1;
}
}
void user_tcpServerAccept(void *e, void *d) //屏端
{
uint8_t itk=0;
uint8_t dnum = 0;
uint8_t mask = 0;
// connect_cfg_head tcp_hand;
// k_task_handle_t task_hdl;
struct sockaddr_in client;
socklen_t addrlen;
// int32 ret;
addrlen =sizeof(client);
int tcp_fd = accept(tcp_connect_fd, (struct sockaddr*)&client, &addrlen);
if(tcp_fd < 0)
{
BABY_DBG("accept()error...............\n");
return;
}
for(itk = 0;itk < 10;itk++){
if(devtab[itk].ipaddr == client.sin_addr.s_addr){ //发现当前列表里面已经有此IP地址
devtab[itk].tcpfd = tcp_fd; //更新此列表的fd
mask = 1; //标识,表明当前IP已有设备id分配
}
}
if(mask == 0){ //当前IP没被分配
for(itk = 0;itk < 10;itk++){
if(devtab[itk].tcpfd == 0){
dnum = itk;
break;
}
}
devtab[dnum].ipaddr = client.sin_addr.s_addr;
devtab[dnum].tcpfd = tcp_fd;
devnum++; //标明下个设备号
}
eloop_add_fd( tcp_fd, EVENT_READ, EVENT_F_ENABLED, tcp_handle_server, (void*)tcp_fd );
}
void tcp_handle_server_init(){
int InitSrv(uint16_t port);
tcp_connect_fd = InitSrv(6001);
eloop_add_fd( tcp_connect_fd, EVENT_READ, EVENT_F_ENABLED, user_tcpServerAccept, 0 );
}
void protocol_server_init(){
uint8_t i = 0;
struct h264_device *h264_dev;
struct msi *scale2 = scale2_msi("scale2", 640, 360, 640, 360, FSTYPE_YUV_P0, 10);
if (scale2)
{
msi_add_output(scale2, NULL, R_VIDEO_P0);
msi_add_output(scale2, NULL, R_VIDEO_P1);
os_printf("%s %d\r\n",__func__,__LINE__);
}
for(i = 0;i < STA_NUM;i++){
server_resolution[i].target_width = 1280;
server_resolution[i].target_high = 720;
}
//scaler_msi_gol = scale2;
h264_dev = (struct h264_device *)dev_get(HG_H264_DEVID);
memset(decmsg,0x00,sizeof(decmsg));
for(i=0; i<10; i++) {
devtab[i].larger = 10;
}
h264_drv_init(h264_dev);
h264_dec_room_init(2,1280,720);
net_h264_sema_init();
udp_handle_server_init();
tcp_handle_server_init();
}
void protocol_server_change_resolution(uint8_t id, uint32_t width, uint32_t high)
{
server_resolution[id].target_width = width;
server_resolution[id].target_high = high;
}
void user_protocol()
{
os_sleep_ms(100);
protocol_server_init(); //进行推屏 AP
}
static void babyprotocol_switch_device(int8_t device)
{
next_switch_device = device;
}
int32_t atcmd_babyprotocol_switch_device(const char *cmd, char *argv[], uint32 argc)
{
int8_t device = 0;
if(argv[0]) {
device = os_atoi(argv[0]);
babyprotocol_switch_device(device);
return RET_OK;
}
return RET_ERR;
}
static void babyprotocol_change_larger(uint8_t device, uint8_t larger)
{
devtab[device].larger = larger;
}
int32_t atcmd_babyprotocol_change_larger(const char *cmd, char *argv[], uint32 argc)
{
if(argc >= 2) {
uint8_t device = os_atoi(argv[0]);
uint8_t larger = os_atoi(argv[1]);
babyprotocol_change_larger(device, larger);
return RET_OK;
}
return RET_ERR;
}
#endif