pure sdk for main
This commit is contained in:
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
在硬件初始化后,这里就是相关video的接口
|
||||
*/
|
||||
#include "video_app.h"
|
||||
|
||||
//临时利用,V200接口需要用到
|
||||
#include "devid.h"
|
||||
|
||||
#if JPG_EN == 1
|
||||
#include "stream_frame.h"
|
||||
#include "utlist.h"
|
||||
#include "osal/work.h"
|
||||
#include "jpgdef.h"
|
||||
#include "hal/jpeg.h"
|
||||
#include "hal/vpp.h"
|
||||
#include "custom_mem/custom_mem.h"
|
||||
#include "lib/lcd/lcd.h"
|
||||
#include "lib/lcd/gui.h"
|
||||
#include "lib/video/dvp/jpeg/jpg.h"
|
||||
#include "osal/irq.h"
|
||||
|
||||
extern uint32_t get_jpg_default_dpi(uint8_t id);
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC custom_malloc_psram
|
||||
#define STREAM_FREE custom_free_psram
|
||||
#define STREAM_ZALLOC custom_zalloc_psram
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC custom_malloc
|
||||
#define STREAM_LIBC_FREE custom_free
|
||||
#define STREAM_LIBC_ZALLOC custom_zalloc
|
||||
|
||||
struct video_app_s
|
||||
{
|
||||
struct os_work work;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
};
|
||||
|
||||
|
||||
static uint8_t video_app_running = 0;
|
||||
static stream *g_jpeg_s = NULL;
|
||||
|
||||
|
||||
//txw81x重写一下,因为有些模块可能被其他模块用
|
||||
#if TXW80X
|
||||
static void start_jpeg_stream()
|
||||
{
|
||||
jpg_recfg();
|
||||
jpg_start(0);
|
||||
|
||||
csi_recfg();
|
||||
csi_open();
|
||||
}
|
||||
|
||||
void stop_jpeg_stream()
|
||||
{
|
||||
csi_close();
|
||||
jpg_stop(0);
|
||||
}
|
||||
#else
|
||||
|
||||
extern volatile uint32 prc_new_frame;
|
||||
uint8 spi_sensor_to_mjpeg_is_run();
|
||||
extern void jpg_start_dpi(uint8 jpg_num,uint16_t w,uint16_t h);
|
||||
static void start_jpeg_stream(struct video_app_s *msg)
|
||||
{
|
||||
//jpg_recfg();
|
||||
//为了尽量保留旧逻辑,这里用宏去隔离,新框架要使用msg参数
|
||||
#if LVGL_STREAM_ENABLE == 1
|
||||
jpg_recfg(0);
|
||||
jpg_start_dpi(0,msg->w,msg->h);
|
||||
#else
|
||||
#if PRC_EN
|
||||
if(spi_sensor_to_mjpeg_is_run()){
|
||||
while(prc_new_frame == 0){
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
jpg_recfg(0);
|
||||
jpg_start(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stop_jpeg_stream()
|
||||
{
|
||||
//csi_close();
|
||||
jpg_stop(0);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//注意,如果调用这里,new_video_app.c的接口就不能随便调用了
|
||||
//这个文件是旧逻辑,保留是为了旧版本代码可以运行,新代码最好参考new_video_app.c去作改动
|
||||
//实际两个文件是高度相似的
|
||||
void stop_jpeg()
|
||||
{
|
||||
jpeg_stream_deinit();
|
||||
}
|
||||
|
||||
void start_jpeg()
|
||||
{
|
||||
jpeg_stream_init();
|
||||
}
|
||||
|
||||
stream *start_jpeg_return_stream()
|
||||
{
|
||||
return jpeg_stream_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct jpg_frame_msg
|
||||
{
|
||||
uint32_t len;
|
||||
void *malloc_mem;
|
||||
};
|
||||
|
||||
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 uint32_t jpg_custom_func(void *data,int opcode,void *priv);
|
||||
static int32 stream_get_jpg_work(struct os_work *work);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const stream_ops_func stream_jpg_ops =
|
||||
{
|
||||
.get_data_len = get_data_len,
|
||||
.custom_func = jpg_custom_func,
|
||||
};
|
||||
|
||||
static uint32_t jpg_custom_func(void *data,int opcode,void *priv)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
uint32_t flags;
|
||||
struct data_structure *d = (struct data_structure *)data;
|
||||
switch(opcode)
|
||||
{
|
||||
case CUSTOM_GET_NODE_LEN:
|
||||
{
|
||||
|
||||
struct jpg_frame_msg *j = (struct jpg_frame_msg*)d->priv;
|
||||
if(GET_DATA_TYPE2(d->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
res = get_jpg_node_len(0);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(d->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
res = j->len;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case CUSTOM_GET_NODE_BUF:
|
||||
if(GET_DATA_TYPE2(d->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
res = (uint32_t)get_jpeg_node_buf(priv);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(d->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
res = (uint32_t)priv;
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
if(GET_DATA_TYPE2(d->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
res =(uint32) get_jpeg_node_buf(dest_list->next->data);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(d->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
res =(uint32) dest_list->next->data;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
||||
|
||||
if(GET_DATA_TYPE2(d->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
del_jpeg_node(el->data,0);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(d->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
custom_free_psram(el->data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
if(GET_DATA_TYPE2(d->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
del_jpeg_node(el->data,0);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(d->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
custom_free_psram(el->data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CUSTOM_GET_NODE_COUNT:
|
||||
{
|
||||
struct data_structure *d = (struct data_structure *)data;
|
||||
struct stream_jpeg_data_s *el;
|
||||
struct stream_jpeg_data_s *dest_list = (struct stream_jpeg_data_s *)d->data;
|
||||
//struct stream_jpeg_data_s *dest_list_tmp = dest_list;
|
||||
LL_COUNT(dest_list,el,res);
|
||||
res -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint32_t stream_cmd_func(stream *s,int cmd,uint32_t arg)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case SET_MJPEG_RESOLUTION_PARM_CMD:
|
||||
{
|
||||
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
resolution_parm *gui_cfg = (resolution_parm*)arg;
|
||||
os_printf("dvp_h:%d dvp_w:%d rec_h:%d rec_w:%d\n",gui_cfg->dvp_h,gui_cfg->dvp_w,gui_cfg->rec_h,gui_cfg->rec_w);
|
||||
|
||||
extern uint8 *yuvbuf;
|
||||
#if LCD_EN
|
||||
struct scale_device *scale_dev;
|
||||
struct vpp_device *vpp_dev;
|
||||
scale_dev = (struct scale_device *)dev_get(HG_SCALE1_DEVID);
|
||||
vpp_dev = (struct vpp_device *)dev_get(HG_VPP_DEVID);
|
||||
struct video_app_s *msg = (struct video_app_s*)s->priv;
|
||||
|
||||
if(gui_cfg->dvp_h != gui_cfg->rec_h || gui_cfg->dvp_w != gui_cfg->rec_w)
|
||||
{
|
||||
os_work_cancle2(&msg->work,1);
|
||||
stop_jpeg_stream();
|
||||
os_printf("---------SCALE TO MJPEG---------\n");
|
||||
scale_from_vpp_to_jpg(scale_dev,(uint32)yuvbuf,gui_cfg->dvp_w,gui_cfg->dvp_h,gui_cfg->rec_w,gui_cfg->rec_h);
|
||||
jpg_cfg(HG_JPG0_DEVID,SCALER_DATA);
|
||||
vpp_open(vpp_dev);
|
||||
start_jpeg_stream((struct video_app_s*)s->priv);
|
||||
OS_WORK_REINIT(&msg->work);
|
||||
os_run_work_delay(&msg->work, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_work_cancle2(&msg->work,1);
|
||||
stop_jpeg_stream();
|
||||
vpp_close(vpp_dev);
|
||||
os_printf("---------VPP TO MJPEG---------\n");
|
||||
os_sleep_ms(50);
|
||||
jpg_cfg(HG_JPG0_DEVID,VPP_DATA0);
|
||||
vpp_open(vpp_dev);
|
||||
start_jpeg_stream((struct video_app_s*)s->priv);
|
||||
OS_WORK_REINIT(&msg->work);
|
||||
os_run_work_delay(&msg->work, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case RESET_MJPEG_DPI:
|
||||
{
|
||||
struct video_app_s *msg = (struct video_app_s*)s->priv;
|
||||
os_work_cancle2(&msg->work,1);
|
||||
stop_jpeg_stream();
|
||||
uint32_t w_h = (uint32_t)arg;
|
||||
os_printf("w_h:%X\n",w_h);
|
||||
msg->w = w_h>>16;
|
||||
msg->h = w_h&0xffff;
|
||||
start_jpeg_stream(msg);
|
||||
OS_WORK_REINIT(&msg->work);
|
||||
os_run_work_delay(&msg->work, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int opcode_func(stream *s,void *priv,int opcode)
|
||||
{
|
||||
int res = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
case STREAM_OPEN_ENTER:
|
||||
break;
|
||||
case STREAM_OPEN_EXIT:
|
||||
{
|
||||
s->priv = (struct video_app_s*) STREAM_LIBC_ZALLOC(sizeof(struct video_app_s));
|
||||
struct video_app_s *msg = (struct video_app_s*)s->priv;
|
||||
stream_data_dis_mem_custom(s);
|
||||
#if 0
|
||||
streamSrc_bind_streamDest(s,R_PSRAM_JPEG);
|
||||
|
||||
#else
|
||||
//注意这里,使用psram的时候不要直接到图传,先到psram变成一帧图,然后psram再发送到图传和录卡流
|
||||
streamSrc_bind_streamDest(s,R_RTP_JPEG);
|
||||
streamSrc_bind_streamDest(s,R_RECORD_JPEG);
|
||||
streamSrc_bind_streamDest(s,R_ALK_JPEG);
|
||||
streamSrc_bind_streamDest(s,R_PHOTO_JPEG);
|
||||
streamSrc_bind_streamDest(s,R_AT_SAVE_PHOTO);
|
||||
streamSrc_bind_streamDest(s,R_AT_AVI_JPEG);
|
||||
streamSrc_bind_streamDest(s,R_LOWPOERRESUME_EVENT);
|
||||
// streamSrc_bind_streamDest(s,SR_OTHER_JPG);
|
||||
#endif
|
||||
register_stream_self_cmd_func(s,stream_cmd_func);
|
||||
//启动jpeg流
|
||||
|
||||
|
||||
//这里实际是为了兼容旧逻辑产生的
|
||||
//设置mjpeg的默认值
|
||||
uint32_t w_h = get_jpg_default_dpi(0);
|
||||
msg->w = w_h>>16;
|
||||
msg->h = w_h&0xffff;
|
||||
start_jpeg_stream(msg);
|
||||
//启动workqueue
|
||||
OS_WORK_INIT(&msg->work, stream_get_jpg_work, 0);
|
||||
os_run_work_delay(&msg->work, 1);
|
||||
}
|
||||
break;
|
||||
case STREAM_OPEN_FAIL:
|
||||
break;
|
||||
case STREAM_DATA_DIS:
|
||||
{
|
||||
struct data_structure *data = (struct data_structure *)priv;
|
||||
//注册对应函数
|
||||
data->ops = (stream_ops_func*)&stream_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);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
//这里只要判断type2,因为默认type1一定是JPEG
|
||||
if(GET_DATA_TYPE2(data->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
del_jpeg_node(el->data,0);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(data->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
custom_free_psram(el->data);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
struct jpg_frame_msg *j = (struct jpg_frame_msg*)data->priv;
|
||||
if(j)
|
||||
{
|
||||
os_free(j->malloc_mem);
|
||||
j->malloc_mem = 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);
|
||||
//这里只要判断type2,因为默认type1一定是JPEG
|
||||
if(GET_DATA_TYPE2(data->type) == JPEG_DVP_NODE)
|
||||
{
|
||||
del_jpeg_node(el->data,0);
|
||||
}
|
||||
#ifdef PSRAM_HEAP
|
||||
else if(GET_DATA_TYPE2(data->type) == JPEG_DVP_FULL)
|
||||
{
|
||||
custom_free_psram(el->data);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
enable_irq(flags);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//退出,则关闭对应得流
|
||||
case STREAM_CLOSE_EXIT:
|
||||
{
|
||||
struct video_app_s *msg = (struct video_app_s*)s->priv;
|
||||
os_work_cancle2(&msg->work,1);
|
||||
stop_jpeg_stream();
|
||||
if(msg)
|
||||
{
|
||||
STREAM_LIBC_FREE(msg);
|
||||
s->priv = NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_MARK_GC_END:
|
||||
//这里代表流已经完毕,也代表整个数据流已经被关闭了
|
||||
video_app_running = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
//默认都返回成功
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void jpeg_in_sram(struct list_head *get_f)
|
||||
{
|
||||
stream *s = g_jpeg_s;
|
||||
struct list_head *data;
|
||||
int err = 1;
|
||||
if(get_f)
|
||||
{
|
||||
struct stream_jpeg_data_s *el,*tmp;
|
||||
struct stream_jpeg_data_s *dest_list = NULL;
|
||||
int get_f_count = get_node_count(get_f);
|
||||
struct stream_jpeg_data_s *m = 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++;
|
||||
}
|
||||
|
||||
//节点进行提取到stream里面,如果节点不够,也要删除已经提取的节点(理论节点与jpeg节点一致,不应该不一样)
|
||||
//先判断get_f的节点数量是多少
|
||||
while(m && get_f_count--)
|
||||
{
|
||||
//图片节点提取
|
||||
if(list_empty(get_f))
|
||||
{
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
el = m++;
|
||||
//保存next
|
||||
data = get_f->next;
|
||||
//将next断开
|
||||
list_del(get_f->next);
|
||||
el->data = (void*)data;
|
||||
el->ref = 1;
|
||||
el->next = NULL;
|
||||
err = 0;
|
||||
//添加到另一个链表
|
||||
LL_APPEND(dest_list,el);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct data_structure *data_s = NULL;
|
||||
//没有错误的情况才去申请空间
|
||||
if(!err)
|
||||
{
|
||||
data_s = get_src_data_f(s);
|
||||
if(data_s)
|
||||
{
|
||||
//设置这个为正常图片的的形式
|
||||
data_s->type = SET_DATA_TYPE(JPEG,JPEG_DVP_NODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(err || !data_s || !data_s->priv)
|
||||
{
|
||||
del_jpeg_frame(get_f);
|
||||
//清除已经提取的图片节点
|
||||
LL_FOREACH_SAFE(dest_list,el,tmp)
|
||||
{
|
||||
el->ref = 0;
|
||||
el->next = NULL;
|
||||
if(el->data)
|
||||
{
|
||||
del_jpeg_node(el->data,0);
|
||||
}
|
||||
el->data = NULL;
|
||||
}
|
||||
os_free(dest_list);
|
||||
|
||||
if(data_s)
|
||||
{
|
||||
force_del_data(data_s);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//数据绑定
|
||||
data_s->data = dest_list;
|
||||
data_s->ref = 0;
|
||||
//设置这个为图片节点形式,接收端需要根据这个去实现读取图片方式
|
||||
data_s->type = SET_DATA_TYPE(JPEG,JPEG_DVP_NODE);
|
||||
set_stream_data_time(data_s,os_jiffies());
|
||||
struct jpg_frame_msg *j = (struct jpg_frame_msg*)data_s->priv;
|
||||
j->len = get_jpeg_len(get_f);
|
||||
j->malloc_mem = dest_list;
|
||||
del_jpeg_frame(get_f);
|
||||
//统一发送数据,这个时候,其他流才有可能获取到数据
|
||||
_os_printf("$");
|
||||
send_data_to_stream(data_s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PSRAM_HEAP
|
||||
void jpeg_in_psram(struct list_head *get_f)
|
||||
{
|
||||
|
||||
uint8_t *tmp_buf;
|
||||
stream *s = g_jpeg_s;
|
||||
int err = 1;
|
||||
uint32_t jpg_len,jpg_len_tmp,cp_offset,cp_len;
|
||||
uint8_t *jpg_psram_space = NULL;
|
||||
uint32_t node_len;
|
||||
|
||||
if(get_f)
|
||||
{
|
||||
node_len = get_jpg_node_len_new((void*)get_f);
|
||||
struct stream_jpeg_data_s *el,*tmp;
|
||||
struct stream_jpeg_data_s *dest_list = NULL;
|
||||
jpg_len = get_jpeg_len(get_f);
|
||||
//os_printf("get_f:%X\tjpg_len:%d\n",get_f,jpg_len);
|
||||
//带psram的情况下,这里总是等于1,因为psram空间大,一张图片约30KB的情况,可以尽量保证图片在内存是连续的
|
||||
int get_f_count = 1;
|
||||
struct stream_jpeg_data_s *m = NULL;
|
||||
|
||||
//与无psram的结构同步,用于兼容
|
||||
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++;
|
||||
}
|
||||
jpg_psram_space = (uint8_t*)custom_malloc_psram(jpg_len);
|
||||
jpg_len_tmp = jpg_len;
|
||||
cp_offset = 0;
|
||||
|
||||
if(m)
|
||||
{
|
||||
el = m;
|
||||
//节点先添加
|
||||
el->data = (void*)jpg_psram_space;
|
||||
el->ref = 1;
|
||||
el->next = NULL;
|
||||
LL_APPEND(dest_list,el);
|
||||
}
|
||||
//节点进行提取到stream里面,如果节点不够,也要删除已经提取的节点(理论节点与jpeg节点一致,不应该不一样)
|
||||
//先判断get_f的节点数量是多少
|
||||
while(jpg_psram_space && m)
|
||||
{
|
||||
|
||||
//图片节点提取
|
||||
if(list_empty(get_f) || jpg_len_tmp == 0)
|
||||
{
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(jpg_len_tmp > node_len)
|
||||
{
|
||||
cp_len = node_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_len = jpg_len_tmp;
|
||||
}
|
||||
jpg_len_tmp -= cp_len;
|
||||
tmp_buf = get_jpeg_first_buf(get_f);
|
||||
|
||||
|
||||
hw_memcpy0(jpg_psram_space+cp_offset,get_jpeg_first_buf(get_f),cp_len);
|
||||
del_jpeg_first_node(get_f);
|
||||
cp_offset += cp_len;
|
||||
}
|
||||
|
||||
struct data_structure *data_s = NULL;
|
||||
//没有错误的情况才去申请空间
|
||||
if(!err)
|
||||
{
|
||||
data_s = get_src_data_f(s);
|
||||
if(data_s)
|
||||
{
|
||||
//设置这个为正常图片的的形式
|
||||
data_s->type = SET_DATA_TYPE(JPEG,JPEG_DVP_FULL);
|
||||
}
|
||||
|
||||
}
|
||||
if(err || !data_s || !data_s->priv || !jpg_psram_space)
|
||||
{
|
||||
del_jpeg_frame(get_f);
|
||||
struct stream_jpeg_data_s *dest_list_tmp = dest_list;
|
||||
//清除已经提取的图片节点
|
||||
LL_FOREACH_SAFE(dest_list,el,tmp)
|
||||
{
|
||||
if(el == dest_list_tmp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
el->ref = 0;
|
||||
el->next = NULL;
|
||||
//理论psram的空间在这里释放
|
||||
if(el->data)
|
||||
{
|
||||
custom_free_psram(el->data);
|
||||
}
|
||||
el->data = NULL;
|
||||
}
|
||||
os_free(dest_list);
|
||||
if(data_s)
|
||||
{
|
||||
force_del_data(data_s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//数据绑定
|
||||
data_s->data = dest_list;
|
||||
data_s->ref = 0;
|
||||
|
||||
set_stream_data_time(data_s,os_jiffies());
|
||||
struct jpg_frame_msg *j = (struct jpg_frame_msg*)data_s->priv;
|
||||
j->len = jpg_len;
|
||||
j->malloc_mem = dest_list;
|
||||
del_jpeg_frame(get_f);
|
||||
//统一发送数据,这个时候,其他流才有可能获取到数据
|
||||
_os_printf("V");
|
||||
send_data_to_stream(data_s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32 stream_get_jpg_work(struct os_work *work)
|
||||
{
|
||||
//首先获取节点先
|
||||
uint32_t flags;
|
||||
|
||||
flags = disable_irq();
|
||||
struct list_head *get_f = (void*)get_frame(HG_JPG0_DEVID);
|
||||
enable_irq(flags);
|
||||
|
||||
uint32_t jpg_len;
|
||||
|
||||
if(get_f)
|
||||
{
|
||||
#ifdef PSRAM_HEAP
|
||||
jpg_len = get_jpeg_len(get_f);
|
||||
if(jpg_len < 200*1024)
|
||||
{
|
||||
jpeg_in_psram(get_f);
|
||||
}
|
||||
else
|
||||
{
|
||||
jpeg_in_sram(get_f);
|
||||
}
|
||||
#else
|
||||
jpeg_in_sram(get_f);
|
||||
#endif
|
||||
|
||||
}
|
||||
os_run_work_delay(work, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
stream *jpeg_stream_init()
|
||||
{
|
||||
stream *src = NULL;
|
||||
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
||||
src = open_stream_available(S_JPEG,2,0,opcode_func,NULL);
|
||||
g_jpeg_s = src;
|
||||
os_printf("src:%X\n",src);
|
||||
if(src)
|
||||
{
|
||||
os_printf("src open_ref:%d\n",src->open_ref);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
void jpeg_stream_deinit(stream *s)
|
||||
{
|
||||
int res;
|
||||
if(g_jpeg_s)
|
||||
{
|
||||
res = close_stream(g_jpeg_s);
|
||||
if(!res)
|
||||
{
|
||||
g_jpeg_s = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jpeg_stream_sync()
|
||||
{
|
||||
while(video_app_running)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
}
|
||||
//同步关闭,就是会等到整个流时间被关闭为止,这个用的时候一定要注意,否则会阻塞整个线程
|
||||
//并且不能在中断使用
|
||||
void jpeg_stream_deinit_sync(stream *s)
|
||||
{
|
||||
int res;
|
||||
if(g_jpeg_s)
|
||||
{
|
||||
res = close_stream(g_jpeg_s);
|
||||
if(!res)
|
||||
{
|
||||
g_jpeg_s = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
jpeg_stream_sync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else
|
||||
stream *jpeg_stream_init()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void jpeg_stream_deinit(stream *s)
|
||||
{
|
||||
|
||||
}
|
||||
void stop_jpeg()
|
||||
{
|
||||
}
|
||||
|
||||
void start_jpeg()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user