503 lines
11 KiB
C
503 lines
11 KiB
C
/*
|
|
在硬件初始化后,这里就是相关video的接口
|
|
*/
|
|
#include "video_app_bbm.h"
|
|
|
|
//临时利用,V200接口需要用到
|
|
#include "devid.h"
|
|
#include "stream_frame.h"
|
|
#include "utlist.h"
|
|
#include "osal/work.h"
|
|
#include "jpgdef.h"
|
|
#include "custom_mem/custom_mem.h"
|
|
|
|
#include "osal/irq.h"
|
|
#ifdef PSRAM_HEAP
|
|
|
|
|
|
static stream *g_bbm_net_jpeg_s = NULL;
|
|
|
|
struct jpg_frame_msg
|
|
{
|
|
uint32_t len;
|
|
void *malloc_mem;
|
|
};
|
|
|
|
|
|
static void stram_get_wifi_psram_thread(void *d)
|
|
{
|
|
|
|
uint32_t jpg_len;
|
|
stream *s = g_bbm_net_jpeg_s;
|
|
uint32_t delete_frame_num = 4;
|
|
uint8_t *malloc_buf = NULL;
|
|
struct data_structure *data_s = NULL;
|
|
static uint32_t last_timestemp = 0;
|
|
static uint32_t cur_timestemp = 0;
|
|
static uint32_t temp = 0;
|
|
int send_ret = 0;
|
|
|
|
|
|
bbm_net_jpeg_frame* get_f = NULL;
|
|
|
|
uint32_t count = 0;
|
|
|
|
while(delete_frame_num)
|
|
{
|
|
get_f = bbm_get_frame();
|
|
if(get_f)
|
|
{
|
|
os_printf("delete frame:%d\n",get_f->timeinfo);
|
|
os_sleep_ms(900);
|
|
bbm_del_frame(get_f);
|
|
break;
|
|
}else{
|
|
os_sleep_ms(1);
|
|
}
|
|
}
|
|
|
|
|
|
while(1)
|
|
{
|
|
get_f = bbm_get_frame();
|
|
if(get_f)
|
|
{
|
|
count++;
|
|
jpg_len = get_f->frame_len;
|
|
data_s = get_src_data_f(s);
|
|
|
|
if(data_s)
|
|
{
|
|
if(!malloc_buf)
|
|
{
|
|
malloc_buf = (uint8_t*)custom_malloc_psram(jpg_len);
|
|
}
|
|
|
|
if(malloc_buf)
|
|
{
|
|
hw_memcpy(malloc_buf,get_f->data,jpg_len);
|
|
//这里代表图片收集完成,申请对应链表空间
|
|
int get_f_count = 1;
|
|
struct stream_jpeg_data_s *m = NULL;
|
|
struct stream_jpeg_data_s *el;//,*tmp;
|
|
struct stream_jpeg_data_s *dest_list = NULL;
|
|
if(get_f_count)
|
|
{
|
|
//多一个,为了固定头指针
|
|
m = (struct stream_jpeg_data_s *)os_malloc((get_f_count+1)*sizeof(struct stream_jpeg_data_s));
|
|
memset(m,0,(get_f_count+1)*sizeof(struct stream_jpeg_data_s));
|
|
el = m;
|
|
el->next = NULL;
|
|
el->data = NULL;
|
|
el->ref = 0;
|
|
LL_APPEND(dest_list,el);
|
|
m++;
|
|
}
|
|
|
|
if(m)
|
|
{
|
|
el = m;
|
|
//节点先添加
|
|
el->data = (void*)malloc_buf;
|
|
el->ref = 1;
|
|
el->next = NULL;
|
|
LL_APPEND(dest_list,el);
|
|
malloc_buf = NULL;
|
|
}
|
|
//申请失败,那么去处理掉异常吧
|
|
else
|
|
{
|
|
goto bbm_get_frame_err_deal;
|
|
}
|
|
|
|
data_s->data = dest_list;
|
|
data_s->ref = 0;
|
|
data_s->type = 1;
|
|
set_stream_data_time(data_s,get_f->timeinfo);
|
|
cur_timestemp = get_f->timeinfo;
|
|
|
|
struct jpg_frame_msg *j = (struct jpg_frame_msg*)data_s->priv;
|
|
j->len = get_f->frame_len;
|
|
j->malloc_mem = dest_list;
|
|
|
|
// _os_printf("W");
|
|
temp = cur_timestemp - last_timestemp;
|
|
|
|
|
|
// os_printf("video: sleep:%dms cur_timestemp:%d last_timestemp:%d\n",cur_timestemp-last_timestemp,
|
|
// cur_timestemp,
|
|
// last_timestemp);
|
|
|
|
data_s->type = SET_DATA_TYPE(JPEG,0);
|
|
send_ret = send_data_to_stream(data_s);
|
|
last_timestemp = cur_timestemp;
|
|
data_s = NULL;
|
|
}
|
|
else
|
|
{
|
|
//申请空间失败,强制删除data_s节点
|
|
os_printf("malloc buf failed\n");
|
|
force_del_data(data_s);
|
|
data_s = NULL;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
_os_printf("=");
|
|
}
|
|
bbm_del_frame(get_f);
|
|
get_f = NULL;
|
|
}
|
|
else
|
|
{
|
|
// printf("N");
|
|
os_sleep_ms(1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bbm_get_frame_err_deal:
|
|
_os_printf("!");
|
|
if(get_f)
|
|
{
|
|
bbm_del_frame(get_f);
|
|
get_f = NULL;
|
|
}
|
|
|
|
if(data_s)
|
|
{
|
|
force_del_data(data_s);
|
|
data_s = NULL;
|
|
}
|
|
|
|
if(malloc_buf)
|
|
{
|
|
custom_free_psram(malloc_buf);
|
|
malloc_buf = NULL;
|
|
}
|
|
|
|
bbm_net_jpeg_psram_stream_deinit(s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
static uint32_t bbm_net_jpg_custom_func_psram(void *data,int opcode,void *priv)
|
|
{
|
|
uint32_t res = 0;
|
|
uint32_t flags;
|
|
switch(opcode)
|
|
{
|
|
case CUSTOM_GET_NODE_LEN:
|
|
{
|
|
struct data_structure *d = (struct data_structure *)data;
|
|
struct jpg_frame_msg *j = (struct jpg_frame_msg*)d->priv;
|
|
res = j->len;
|
|
}
|
|
break;
|
|
case CUSTOM_GET_NODE_BUF:
|
|
res = (uint32_t)priv;
|
|
break;
|
|
case CUSTOM_GET_FIRST_BUF:
|
|
{
|
|
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)GET_DATA_BUF(data);
|
|
//头是固定用,next才是真正的数据
|
|
if(dest_list->next)
|
|
{
|
|
res =(uint32) dest_list->next->data;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case CUSTOM_FREE_NODE:
|
|
{
|
|
//释放data->data里面的图片数据
|
|
//清除已经提取的图片节点
|
|
struct data_structure *d = (struct data_structure *)data;
|
|
struct stream_jpeg_data_s *el,*tmp;
|
|
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)d->data;
|
|
struct stream_jpeg_data_s *dest_list_tmp = dest_list;
|
|
uint32_t flags;
|
|
flags = disable_irq();
|
|
//释放el->data后,最后将链表释放
|
|
LL_FOREACH_SAFE(dest_list,el,tmp)
|
|
{
|
|
if(el == dest_list_tmp)
|
|
{
|
|
continue;
|
|
}
|
|
el->ref--;
|
|
//是否要释放
|
|
if(!el->ref)
|
|
{
|
|
LL_DELETE(dest_list,el);
|
|
if(el->data)
|
|
{
|
|
custom_free_psram(el->data);
|
|
el->data = NULL;
|
|
}
|
|
}
|
|
}
|
|
enable_irq(flags);
|
|
|
|
}
|
|
break;
|
|
|
|
case CUSTOM_DEL_NODE:
|
|
{
|
|
uint32_t ref;
|
|
struct data_structure *d = (struct data_structure *)data;
|
|
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)d->data;
|
|
struct stream_jpeg_data_s *el = (struct stream_jpeg_data_s *)priv;
|
|
flags = disable_irq();
|
|
ref = --el->ref;
|
|
enable_irq(flags);
|
|
if(!ref)
|
|
{
|
|
LL_DELETE(dest_list,el);
|
|
custom_free_psram(el->data);
|
|
el->data = NULL;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
static uint32_t get_data_len(void *data)
|
|
{
|
|
struct data_structure *d = (struct data_structure *)data;
|
|
struct jpg_frame_msg *j = (struct jpg_frame_msg*)d->priv;
|
|
uint32_t len = 0;
|
|
if(j)
|
|
{
|
|
len = j->len;
|
|
}
|
|
return len;
|
|
}
|
|
|
|
static stream_ops_func stream_usb_jpg_ops =
|
|
{
|
|
.get_data_len = get_data_len,
|
|
.custom_func = bbm_net_jpg_custom_func_psram,
|
|
};
|
|
|
|
extern volatile uint8_t uvc_format;
|
|
#define BBM_PSRAM_MALLOC_SIZE_INIT (30*1024)
|
|
static int opcode_func_psram(stream *s,void *priv,int opcode)
|
|
{
|
|
int res = 0;
|
|
switch(opcode)
|
|
{
|
|
case STREAM_OPEN_ENTER:
|
|
break;
|
|
case STREAM_OPEN_EXIT:
|
|
{
|
|
|
|
stream_data_dis_mem(s,3);
|
|
|
|
streamSrc_bind_streamDest(s,R_AT_AVI_JPEG);
|
|
streamSrc_bind_streamDest(s,R_AT_SAVE_PHOTO);
|
|
#if LVGL_STREAM_ENABLE
|
|
streamSrc_bind_streamDest(s,SR_OTHER_JPG);
|
|
#endif
|
|
os_task_create("bbm_wifi_stream", stram_get_wifi_psram_thread, (void *)s, OS_TASK_PRIORITY_NORMAL, 0, NULL, 1024);
|
|
}
|
|
break;
|
|
case STREAM_OPEN_FAIL:
|
|
break;
|
|
case STREAM_DATA_DIS:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
data->type = 0x10;//设置声音的类型,后续用宏代替
|
|
//注册对应函数
|
|
data->ops = &stream_usb_jpg_ops;
|
|
data->data = NULL;
|
|
data->priv = (struct jpg_frame_msg*)os_malloc(sizeof(struct jpg_frame_msg));
|
|
if(data->priv)
|
|
{
|
|
memset(data->priv,0,sizeof(struct jpg_frame_msg));
|
|
}
|
|
else
|
|
{
|
|
os_printf("malloc mem fail,%s:%d\n",__FUNCTION__,__LINE__);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_DESTORY:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
if(data->priv)
|
|
{
|
|
os_free(data->priv);
|
|
data->priv = NULL;
|
|
}
|
|
}
|
|
break;
|
|
|
|
//如果释放空间,则删除所有的节点
|
|
case STREAM_DATA_FREE:
|
|
{
|
|
//释放data->data里面的图片数据
|
|
//清除已经提取的图片节点
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
struct stream_jpeg_data_s *el,*tmp;
|
|
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)data->data;
|
|
struct stream_jpeg_data_s *dest_list_tmp = dest_list;
|
|
//释放el->data后,最后将链表释放
|
|
LL_FOREACH_SAFE(dest_list,el,tmp)
|
|
{
|
|
if(dest_list_tmp == el)
|
|
{
|
|
continue;
|
|
}
|
|
if(el->data)
|
|
{
|
|
custom_free_psram(el->data);
|
|
el->data = NULL;
|
|
}
|
|
}
|
|
struct jpg_frame_msg *j = (struct jpg_frame_msg*)data->priv;
|
|
if(j)
|
|
{
|
|
os_free(j->malloc_mem);
|
|
j->malloc_mem = NULL;
|
|
}
|
|
data->data = NULL;
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE_END:
|
|
break;
|
|
|
|
//每次即将发送到一个流,就调用一次
|
|
case STREAM_SEND_TO_DEST:
|
|
{
|
|
//释放data->data里面的图片数据
|
|
//清除已经提取的图片节点
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
struct stream_jpeg_data_s *el,*tmp;
|
|
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)data->data;
|
|
uint32_t flags;
|
|
flags = disable_irq();
|
|
//释放el->data后,最后将链表释放
|
|
LL_FOREACH_SAFE(dest_list,el,tmp)
|
|
{
|
|
el->ref++;
|
|
}
|
|
enable_irq(flags);
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
//数据发送完成
|
|
case STREAM_SEND_DATA_FINISH:
|
|
{
|
|
//释放data->data里面的图片数据
|
|
//清除已经提取的图片节点
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
struct stream_jpeg_data_s *el,*tmp;
|
|
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)data->data;
|
|
struct stream_jpeg_data_s *dest_list_tmp = dest_list;
|
|
uint32_t flags;
|
|
flags = disable_irq();
|
|
//释放el->data后,最后将链表释放
|
|
LL_FOREACH_SAFE(dest_list,el,tmp)
|
|
{
|
|
if(el == dest_list_tmp)
|
|
{
|
|
continue;
|
|
}
|
|
el->ref--;
|
|
//是否要释放
|
|
if(!el->ref)
|
|
{
|
|
LL_DELETE(dest_list,el);
|
|
custom_free_psram(el->data);
|
|
el->data = NULL;
|
|
}
|
|
}
|
|
enable_irq(flags);
|
|
|
|
}
|
|
break;
|
|
|
|
//退出,则关闭对应得流
|
|
case STREAM_CLOSE_EXIT:
|
|
{
|
|
|
|
|
|
}
|
|
break;
|
|
|
|
case STREAM_DEL:
|
|
{
|
|
//struct bbm_net_jpeg_frame *userdata = (struct bbm_net_jpeg_frame*)s->priv;
|
|
}
|
|
|
|
default:
|
|
//默认都返回成功
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
stream *bbm_net_jpeg_psram_stream_init()
|
|
{
|
|
stream *src = NULL;
|
|
|
|
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
|
if(g_bbm_net_jpeg_s)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
src = open_stream_available(S_NET_JPEG,3,0,opcode_func_psram,NULL);
|
|
|
|
g_bbm_net_jpeg_s = src;
|
|
os_printf("src:%X\n",src);
|
|
if(src)
|
|
{
|
|
os_printf("src open_ref:%d\n",src->open_ref);
|
|
}
|
|
return src;
|
|
}
|
|
|
|
|
|
void bbm_net_jpeg_psram_stream_deinit(stream *s)
|
|
{
|
|
int res;
|
|
os_printf("%s g_bbm_net_jpeg_s:%X\n",__FUNCTION__,g_bbm_net_jpeg_s);
|
|
if(g_bbm_net_jpeg_s)
|
|
{
|
|
res = close_stream(g_bbm_net_jpeg_s);
|
|
os_printf("%s res:%d\n",__FUNCTION__,res);
|
|
if(!res)
|
|
{
|
|
g_bbm_net_jpeg_s = NULL;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void bbm_net_jpeg_init()
|
|
{
|
|
bbm_net_jpeg_psram_stream_init();
|
|
}
|
|
|
|
|
|
#endif
|