722 lines
23 KiB
C
722 lines
23 KiB
C
#include "sys_config.h"
|
|
#include "typesdef.h"
|
|
#include "dev.h"
|
|
#include "devid.h"
|
|
#include "stream_frame.h"
|
|
#include "utlist.h"
|
|
#include "osal/work.h"
|
|
#include "lib/lcd/lcd.h"
|
|
#include "dev/scale/hgscale.h"
|
|
#include "dev/jpg/hgjpg.h"
|
|
#include "jpg_decode_stream.h"
|
|
#include "custom_mem/custom_mem.h"
|
|
|
|
|
|
//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 jpg_decode_s
|
|
{
|
|
struct os_work work;
|
|
stream *s;
|
|
uint8_t *scaler2buf; //scale的buf
|
|
uint32_t scalerbuf_size;
|
|
struct jpg_device *jpg_dev;
|
|
struct scale_device *scale_dev;
|
|
uint32_t last_decode_time; //记录上一次解码的时间,预防有异常的时候可以计算超时
|
|
uint32_t dec_y_offset;
|
|
uint32_t dec_uv_offset;
|
|
uint32_t scale_p1_w;
|
|
uint32_t p1_w;
|
|
uint32_t p1_h;
|
|
|
|
|
|
//这两个值如果有用,会同时存在,不能只是存在一个
|
|
//图片的data_s,等图片解码完成后,可以选择释放
|
|
struct data_structure *parent_data_s;
|
|
|
|
//当前的使用的data_s,已经分配好了空间
|
|
struct data_structure *current_data_s;
|
|
//硬件模块是否准备好
|
|
uint8_t hardware_ready;
|
|
uint8_t hardware_err;
|
|
uint8_t is_register_isr;
|
|
};
|
|
|
|
|
|
|
|
struct jpg_decode_cmd_s
|
|
{
|
|
struct jpg_decode_arg_s *msg;
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32_t w;
|
|
uint32_t h;
|
|
uint32_t rotate;
|
|
}config;
|
|
|
|
struct
|
|
{
|
|
uint32_t in_w;
|
|
uint32_t in_h;
|
|
uint32_t out_w;
|
|
uint32_t out_h;
|
|
}in_out_size;
|
|
|
|
struct
|
|
{
|
|
uint32_t in_w;
|
|
uint32_t in_h;
|
|
uint32_t out_w;
|
|
uint32_t out_h;
|
|
}step;
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void stream_jpg_decode_scale2_done(uint32 irq_flag,uint32 irq_data,uint32 param1){
|
|
|
|
//struct jpg_decode_s *jpg_decode = (struct jpg_decode_s *)irq_data;
|
|
//struct jpg_device *jpg_dev = jpg_decode->jpg_dev;
|
|
//struct scale_device *scale_dev = jpg_decode->scale_dev;
|
|
//jpg_decode->hardware_ready = 1;
|
|
//os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
|
//_os_printf("S");
|
|
|
|
}
|
|
|
|
static void stream_jpg_decode_scale2_ov_isr(uint32 irq_flag,uint32 irq_data,uint32 param1){
|
|
//struct scale_device *scale_dev = (struct scale_device *)irq_data;
|
|
os_printf("sor2");
|
|
}
|
|
|
|
|
|
static void stream_jpg_decode_done(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2)
|
|
{
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s *)irq_data;
|
|
//os_printf("!!!!!!!!!!!!!!!!decode finish\r\n");
|
|
//_os_printf("D");
|
|
jpg_decode->hardware_ready = 1;
|
|
}
|
|
|
|
|
|
|
|
//这里解码失败,暂时代表硬件完成,后面应该有错误标志位,主要为了解码失败移除当前frame
|
|
static void stream_jpg_decode_err(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2)
|
|
{
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s *)irq_data;
|
|
os_printf("decode err\r\n");
|
|
os_printf("jpg_de->parent_data_s data:%X\n",get_stream_real_data(jpg_decode->parent_data_s));
|
|
//jpg_decode->hardware_ready = 1;
|
|
jpg_decode->hardware_err = 1;
|
|
}
|
|
|
|
|
|
|
|
static uint32_t jpg_decode_stream_cmd_func(stream *s,int opcode,uint32_t arg)
|
|
{
|
|
uint32_t res = 0;
|
|
// uint32_t flags;
|
|
switch(opcode)
|
|
{
|
|
|
|
case JPG_DECODE_ARG:
|
|
{
|
|
struct data_structure *data_s = (struct data_structure *)arg;
|
|
res = (uint32_t)data_s->priv;
|
|
}
|
|
break;
|
|
case YUV_ARG:
|
|
{
|
|
struct data_structure *data_s = (struct data_structure *)arg;
|
|
struct jpg_decode_arg_s *msg = (struct jpg_decode_arg_s*)data_s->priv;
|
|
res = (uint32_t)&msg->yuv_arg;
|
|
}
|
|
break;
|
|
//配置解码的参数大小
|
|
//配置输出到屏的size
|
|
case JPG_DECODE_SET_CONFIG:
|
|
{
|
|
struct jpg_decode_cmd_s *cfg = (struct jpg_decode_cmd_s*)arg;
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s*)s->priv;
|
|
jpg_decode->p1_w = cfg->config.w;
|
|
jpg_decode->p1_h = cfg->config.h;
|
|
jpg_decode->scale_p1_w = ((jpg_decode->p1_w+3)/4)*4;
|
|
if(cfg->config.rotate)
|
|
{
|
|
jpg_decode->dec_y_offset = jpg_decode->p1_w*(jpg_decode->p1_h-1);
|
|
jpg_decode->dec_uv_offset = ((jpg_decode->scale_p1_w/2+3)/4)*4 * (jpg_decode->p1_h/2-1);
|
|
}
|
|
else
|
|
{
|
|
jpg_decode->dec_y_offset = 0;
|
|
jpg_decode->dec_uv_offset = 0;
|
|
}
|
|
|
|
cfg->msg->yuv_arg.y_off = jpg_decode->dec_y_offset;
|
|
cfg->msg->yuv_arg.uv_off = jpg_decode->dec_uv_offset;
|
|
cfg->msg->yuv_arg.y_size = jpg_decode->scale_p1_w*jpg_decode->p1_h;
|
|
}
|
|
break;
|
|
|
|
//这只scale的输入参数大小和输出参数大小
|
|
case JPG_DECODE_SET_IN_OUT_SIZE:
|
|
{
|
|
struct jpg_decode_cmd_s *cfg = (struct jpg_decode_cmd_s*)arg;
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s*)s->priv;
|
|
scale_set_in_out_size(jpg_decode->scale_dev,cfg->in_out_size.in_w,cfg->in_out_size.in_h,cfg->in_out_size.out_w,cfg->in_out_size.out_h);
|
|
}
|
|
|
|
break;
|
|
|
|
//设置scale的步长,这里可以决定是否裁剪,如果step设置过大,到最后就不会有数据,解码的图片会补充0(黑色)
|
|
case JPG_DECODE_SET_STEP:
|
|
{
|
|
struct jpg_decode_cmd_s *cfg = (struct jpg_decode_cmd_s*)arg;
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s*)s->priv;
|
|
scale_set_step(jpg_decode->scale_dev,cfg->step.in_w,cfg->step.in_h,cfg->step.out_w,cfg->step.out_h);
|
|
}
|
|
|
|
break;
|
|
|
|
case JPG_DECODE_READY:
|
|
{
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s*)s->priv;
|
|
uint32 dst = (uint32)arg;
|
|
//scale_close(jpg_decode->scale_dev);
|
|
scale_set_out_yaddr(jpg_decode->scale_dev,(uint32)dst);
|
|
scale_set_out_uaddr(jpg_decode->scale_dev,(uint32)dst+jpg_decode->scale_p1_w*jpg_decode->p1_h);
|
|
scale_set_out_vaddr(jpg_decode->scale_dev,(uint32)dst+jpg_decode->scale_p1_w*jpg_decode->p1_h+jpg_decode->scale_p1_w*jpg_decode->p1_h/4);
|
|
//os_printf("scale_p1_w:%d\tp1_w:%d\tp1_h:%d\r\n",jpg_decode->scale_p1_w,jpg_decode->p1_w,jpg_decode->p1_h);
|
|
//如果空间不够,就重新申请把
|
|
if(32+jpg_decode->p1_w*2+(32*SRAMBUF_WLEN*4*3)/2 > jpg_decode->scalerbuf_size)
|
|
{
|
|
if(jpg_decode->scaler2buf)
|
|
{
|
|
STREAM_LIBC_FREE(jpg_decode->scaler2buf);
|
|
}
|
|
//默认一定申请到,没有做申请失败的处理
|
|
jpg_decode->scaler2buf = STREAM_LIBC_MALLOC(32+jpg_decode->p1_w*2+(32*SRAMBUF_WLEN*4*3)/2);
|
|
jpg_decode->scalerbuf_size = 32+jpg_decode->p1_w*2+(32*SRAMBUF_WLEN*4*3)/2;
|
|
}
|
|
|
|
|
|
scale_set_line_buf_addr(jpg_decode->scale_dev,(uint32)jpg_decode->scaler2buf);
|
|
scale_set_srambuf_wlen(jpg_decode->scale_dev,SRAMBUF_WLEN);
|
|
scale_set_start_addr(jpg_decode->scale_dev,0,0);
|
|
|
|
|
|
|
|
if(!jpg_decode->is_register_isr)
|
|
{
|
|
scale_request_irq(jpg_decode->scale_dev,FRAME_END,(scale_irq_hdl )&stream_jpg_decode_scale2_done,(uint32)jpg_decode);
|
|
scale_request_irq(jpg_decode->scale_dev,INBUF_OV,(scale_irq_hdl )&stream_jpg_decode_scale2_ov_isr,(uint32)jpg_decode);
|
|
jpg_request_irq(jpg_decode->jpg_dev,(jpg_irq_hdl )&stream_jpg_decode_done,JPG_IRQ_FLAG_JPG_DONE,(void *)jpg_decode);
|
|
jpg_request_irq(jpg_decode->jpg_dev,(jpg_irq_hdl )&stream_jpg_decode_err,JPG_IRQ_FLAG_ERROR,(void *)jpg_decode);
|
|
jpg_decode->is_register_isr = 1;
|
|
}
|
|
|
|
jpg_decode_target(jpg_decode->jpg_dev,1);
|
|
|
|
break;
|
|
}
|
|
|
|
case JPG_DECODE_START:
|
|
{
|
|
struct jpg_decode_s *jpg_decode = (struct jpg_decode_s*)s->priv;
|
|
uint32 dst = (uint32)arg;
|
|
jpg_decode->hardware_ready = 0;
|
|
jpg_decode->last_decode_time = os_jiffies();
|
|
scale_open(jpg_decode->scale_dev);
|
|
jpg_decode_photo(jpg_decode->jpg_dev,dst);
|
|
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
static int32 jpg_decode_work(struct os_work *work)
|
|
{
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s *)work;
|
|
struct data_structure *data_s;
|
|
//static int count = 0;
|
|
//检测解码模块是否完成或者超时代表解码失败
|
|
//能进去,模块需要reset或者已经解码完毕,可以重新去解码,否则只能慢慢等超时或者硬件解码完成
|
|
if(jpg_de->hardware_err || jpg_de->hardware_ready || os_jiffies() - jpg_de->last_decode_time > 1000)
|
|
{
|
|
if(jpg_de->current_data_s && (os_jiffies() - jpg_de->last_decode_time > 1000))
|
|
{
|
|
//解码可能失败了
|
|
_os_printf("decode failed1\n");
|
|
jpg_de->hardware_ready = 1;
|
|
//无论是完成还是失败,都要释放这张图片了
|
|
free_data(jpg_de->parent_data_s);
|
|
jpg_de->parent_data_s = NULL;
|
|
|
|
//不再解码了
|
|
force_del_data(jpg_de->current_data_s);
|
|
jpg_de->current_data_s = NULL;
|
|
|
|
//这里最好将硬件模块停止
|
|
}
|
|
//解码异常
|
|
else if(jpg_de->hardware_err)
|
|
{
|
|
_os_printf("decode failed2\n");
|
|
jpg_de->hardware_err = 0;
|
|
jpg_de->hardware_ready = 1;
|
|
if(jpg_de->current_data_s)
|
|
{
|
|
//无论是完成还是失败,都要释放这张图片了
|
|
free_data(jpg_de->parent_data_s);
|
|
jpg_de->parent_data_s = NULL;
|
|
|
|
//不再解码了
|
|
force_del_data(jpg_de->current_data_s);
|
|
jpg_de->current_data_s = NULL;
|
|
}
|
|
}
|
|
//解码完成,检查有解码完的数据需要发送
|
|
else if(jpg_de->current_data_s)
|
|
{
|
|
//os_printf("%s:%d\tbuf:%X\n",__FUNCTION__,__LINE__,get_stream_real_data(jpg_de->current_data_s));
|
|
data_s = jpg_de->current_data_s;
|
|
set_stream_data_time(data_s,get_stream_data_timestamp(jpg_de->parent_data_s));
|
|
data_s->magic = jpg_de->parent_data_s->magic;
|
|
//os_printf("%s:%d\tdata_s:%X\tdata->data:%X\n",__FUNCTION__,__LINE__,data_s,data_s->data);
|
|
_os_printf("&");
|
|
send_data_to_stream(data_s);
|
|
//无论是完成还是失败,都要释放这张图片了
|
|
free_data(jpg_de->parent_data_s);
|
|
jpg_de->parent_data_s = NULL;
|
|
jpg_de->current_data_s = NULL;
|
|
}
|
|
//硬件可用,但是current_data_s不存在
|
|
//有两种可能
|
|
//一、没有需要解码的图片
|
|
//二、有需要解码的图片,但是data_s没有申请成功或者内存空间不足以去解码图片数据
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//这里没有解码的图片,尝试去看看有没有需要解码图片
|
|
if(!jpg_de->parent_data_s)
|
|
{
|
|
//接收图片,尝试看看是否要解码
|
|
jpg_de->parent_data_s = recv_real_data(jpg_de->s);
|
|
|
|
//需要解码,然后申请空间
|
|
if(jpg_de->parent_data_s)
|
|
{
|
|
//os_printf("parent_data_s:%X\n",jpg_de->parent_data_s);
|
|
goto start_decode;
|
|
}
|
|
//不需要解码
|
|
else
|
|
{
|
|
goto not_decode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
goto start_decode;
|
|
}
|
|
|
|
//开始尝试解码
|
|
start_decode:
|
|
data_s = get_src_data_f(jpg_de->s);
|
|
//申请到data_s,申请解码空间
|
|
if(data_s)
|
|
{
|
|
//struct jpg_decode_arg_s *msg = (struct jpg_decode_arg_s *)jpg_de->parent_data_s->priv;
|
|
struct jpg_decode_arg_s *msg = (struct jpg_decode_arg_s *)stream_self_cmd_func(jpg_de->parent_data_s->s,JPG_DECODE_ARG,(uint32_t)jpg_de->parent_data_s);
|
|
//没有找到,代表发送过来的不是jpg或者说对应参数没有配置,不解码
|
|
if(msg)
|
|
{
|
|
//为data_s申请解码空间,申请不到下次申请
|
|
data_s->data = (uint8 *)STREAM_MALLOC(msg->yuv_arg.out_w*msg->yuv_arg.out_h*3/2);
|
|
|
|
if(data_s->data)
|
|
{
|
|
|
|
struct jpg_decode_cmd_s cfg;
|
|
memset(&cfg,0,sizeof(struct jpg_decode_cmd_s));
|
|
//提前配置好data的长度
|
|
set_stream_real_data_len(data_s,msg->yuv_arg.out_w*msg->yuv_arg.out_h*3/2);
|
|
memcpy(data_s->priv,msg,sizeof(struct jpg_decode_arg_s));
|
|
//将data_s的struct jpg_yuv_decode_msg_s接入cfg,后面有参数改动
|
|
cfg.msg = (struct jpg_decode_arg_s*)data_s->priv;
|
|
cfg.config.w = msg->yuv_arg.out_w;
|
|
cfg.config.h = msg->yuv_arg.out_h;
|
|
cfg.config.rotate = msg->rotate;
|
|
stream_self_cmd_func(jpg_de->s,JPG_DECODE_SET_CONFIG,(uint32_t)&cfg);
|
|
|
|
|
|
cfg.in_out_size.in_w = msg->decode_w;
|
|
cfg.in_out_size.in_h = msg->decode_h;
|
|
cfg.in_out_size.out_w = msg->yuv_arg.out_w;
|
|
cfg.in_out_size.out_h = msg->yuv_arg.out_h;
|
|
stream_self_cmd_func(jpg_de->s,JPG_DECODE_SET_IN_OUT_SIZE,(uint32_t)&cfg);
|
|
|
|
cfg.in_out_size.in_w = msg->decode_w;
|
|
cfg.in_out_size.in_h = msg->decode_h;
|
|
cfg.in_out_size.out_w = msg->step_w;
|
|
cfg.in_out_size.out_h = msg->step_h;
|
|
|
|
data_s->type = SET_DATA_TYPE(YUV,GET_DATA_TYPE2(jpg_de->parent_data_s->type));
|
|
|
|
void *ptr = get_stream_real_data(jpg_de->parent_data_s);
|
|
uint32_t len = get_stream_real_data_len(jpg_de->parent_data_s);
|
|
sys_dcache_clean_range((uint32_t*)((uint32_t)(ptr) & CACHE_CIR_INV_ADDR_Msk), len + ((uint32_t)(ptr)-((uint32_t)(ptr) & CACHE_CIR_INV_ADDR_Msk)));
|
|
|
|
stream_self_cmd_func(jpg_de->s,JPG_DECODE_SET_STEP,(uint32_t)&cfg);
|
|
stream_self_cmd_func(jpg_de->s,JPG_DECODE_READY,(uint32_t)get_stream_real_data(data_s));
|
|
stream_self_cmd_func(jpg_de->s,JPG_DECODE_START,(uint32_t)ptr);
|
|
jpg_de->current_data_s = data_s;
|
|
}
|
|
else
|
|
{
|
|
force_del_data(data_s);
|
|
data_s = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
os_printf("%s:%d\tdecode msg isn't normal\tmsg:%X\tname:%s\n",__FUNCTION__,__LINE__,msg,jpg_de->parent_data_s->s->name);
|
|
force_del_data(data_s);
|
|
data_s = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
not_decode:
|
|
os_run_work_delay(work, 1);
|
|
return 0;
|
|
}
|
|
|
|
//这个流主要是为了解码流使用
|
|
//为了充分利用psram,这里需要申请psram,可能效率会低,但是空间不至于容易浪费
|
|
//只有在极端情况下才会需要比原来更多的内存,但可以通过错开时间使用,来缓解这个问题
|
|
static int opcode_func(stream *s,void *priv,int opcode)
|
|
{
|
|
int res = 0;
|
|
switch(opcode)
|
|
{
|
|
case STREAM_OPEN_ENTER:
|
|
break;
|
|
case STREAM_OPEN_EXIT:
|
|
{
|
|
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s*)STREAM_LIBC_ZALLOC(sizeof(struct jpg_decode_s));
|
|
jpg_de->jpg_dev = (struct jpg_device *)dev_get(HG_JPG1_DEVID);
|
|
jpg_de->scale_dev = (struct scale_device *)dev_get(HG_SCALE2_DEVID);
|
|
//通过命令去申请空间以及配置寄存器,如果停止,则需要释放空间
|
|
jpg_de->scaler2buf = NULL;
|
|
s->priv = (void*)jpg_de;
|
|
register_stream_self_cmd_func(s,jpg_decode_stream_cmd_func);
|
|
stream_data_dis_mem_custom(s);
|
|
streamSrc_bind_streamDest(s,R_VIDEO_P0);
|
|
streamSrc_bind_streamDest(s,R_VIDEO_P1);
|
|
streamSrc_bind_streamDest(s,R_JPG_TO_RGB);
|
|
streamSrc_bind_streamDest(s,R_YUV_TO_JPG);
|
|
//启动一个workqueueu去接收图片,然后将图片解码成yuv数据,并且发送出去
|
|
jpg_de->s = s;
|
|
OS_WORK_INIT(&jpg_de->work, jpg_decode_work, 0);
|
|
os_run_work_delay(&jpg_de->work, 1);
|
|
enable_stream(s,1);
|
|
}
|
|
break;
|
|
case STREAM_OPEN_FAIL:
|
|
break;
|
|
case STREAM_DATA_DIS:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
data->priv = (struct jpg_decode_arg_s *)STREAM_LIBC_ZALLOC(sizeof(struct jpg_decode_arg_s));
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
if(data->data)
|
|
{
|
|
//os_printf("%s:%d\tdata:%X\tdata->data:%X\n",__FUNCTION__,__LINE__,data,data->data);
|
|
STREAM_FREE(data->data);
|
|
data->data = NULL;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case STREAM_FILTER_DATA:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
//os_printf("%s:%d\tdata:%X\n",__FUNCTION__,__LINE__,data);
|
|
if(GET_DATA_TYPE1(data->type) != JPEG)
|
|
{
|
|
res = 1;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE_END:
|
|
break;
|
|
|
|
|
|
//数据发送完成,可以选择唤醒对应的任务
|
|
case STREAM_SEND_DATA_FINISH:
|
|
break;
|
|
|
|
|
|
case STREAM_SEND_DATA_START:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_DESTORY:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
if(data->priv)
|
|
{
|
|
STREAM_LIBC_FREE(data->priv);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STREAM_CLOSE_ENTER:
|
|
{
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s *)s->priv;
|
|
os_work_cancle2(&jpg_de->work, 1);
|
|
}
|
|
break;
|
|
|
|
case STREAM_CLOSE_EXIT:
|
|
{
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s *)s->priv;
|
|
os_work_cancle2(&jpg_de->work, 1);
|
|
//关闭硬件
|
|
scale_close(jpg_de->scale_dev);
|
|
jpg_close(jpg_de->jpg_dev);
|
|
|
|
if(jpg_de->parent_data_s)
|
|
{
|
|
os_printf("parent_data_s:%X\n",jpg_de->parent_data_s);
|
|
free_data(jpg_de->parent_data_s);
|
|
jpg_de->parent_data_s = NULL;
|
|
}
|
|
|
|
if(jpg_de->current_data_s)
|
|
{
|
|
os_printf("parent_data_s:%X\n",jpg_de->current_data_s);
|
|
force_del_data(jpg_de->current_data_s);
|
|
jpg_de->current_data_s = NULL;
|
|
}
|
|
|
|
//释放line_buf
|
|
STREAM_LIBC_FREE(jpg_de->scaler2buf);
|
|
|
|
|
|
}
|
|
break;
|
|
|
|
case STREAM_MARK_GC_END:
|
|
{
|
|
STREAM_LIBC_FREE(s->priv);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
//默认都返回成功
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
static int opcode_func_not_bind(stream *s,void *priv,int opcode)
|
|
{
|
|
int res = 0;
|
|
switch(opcode)
|
|
{
|
|
case STREAM_OPEN_ENTER:
|
|
break;
|
|
case STREAM_OPEN_EXIT:
|
|
{
|
|
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s*)STREAM_LIBC_ZALLOC(sizeof(struct jpg_decode_s));
|
|
jpg_de->jpg_dev = (struct jpg_device *)dev_get(HG_JPG1_DEVID);
|
|
jpg_de->scale_dev = (struct scale_device *)dev_get(HG_SCALE2_DEVID);
|
|
//通过命令去申请空间以及配置寄存器,如果停止,则需要释放空间
|
|
jpg_de->scaler2buf = NULL;
|
|
jpg_de->scalerbuf_size = 0;
|
|
s->priv = (void*)jpg_de;
|
|
register_stream_self_cmd_func(s,jpg_decode_stream_cmd_func);
|
|
stream_data_dis_mem_custom(s);
|
|
//启动一个workqueueu去接收图片,然后将图片解码成yuv数据,并且发送出去
|
|
jpg_de->s = s;
|
|
OS_WORK_INIT(&jpg_de->work, jpg_decode_work, 0);
|
|
os_run_work_delay(&jpg_de->work, 1);
|
|
}
|
|
break;
|
|
case STREAM_OPEN_FAIL:
|
|
break;
|
|
case STREAM_DATA_DIS:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
data->priv = (struct jpg_decode_arg_s *)STREAM_LIBC_ZALLOC(sizeof(struct jpg_decode_arg_s));
|
|
os_printf("jpg decode data->priv:%x\n",data->priv);
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
if(data->data)
|
|
{
|
|
//os_printf("%s:%d\tdata:%X\tdata->data:%X\n",__FUNCTION__,__LINE__,data,data->data);
|
|
STREAM_FREE(data->data);
|
|
data->data = NULL;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case STREAM_FILTER_DATA:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
//os_printf("%s:%d\tdata:%X\n",__FUNCTION__,__LINE__,data);
|
|
if(GET_DATA_TYPE1(data->type) != JPEG)
|
|
{
|
|
res = 1;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE_END:
|
|
break;
|
|
|
|
|
|
//数据发送完成,可以选择唤醒对应的任务
|
|
case STREAM_SEND_DATA_FINISH:
|
|
break;
|
|
|
|
|
|
case STREAM_SEND_DATA_START:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_DESTORY:
|
|
{
|
|
struct data_structure *data = (struct data_structure *)priv;
|
|
if(data->priv)
|
|
{
|
|
STREAM_LIBC_FREE(data->priv);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STREAM_CLOSE_ENTER:
|
|
{
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s *)s->priv;
|
|
os_work_cancle2(&jpg_de->work, 1);
|
|
}
|
|
break;
|
|
|
|
case STREAM_CLOSE_EXIT:
|
|
{
|
|
struct jpg_decode_s *jpg_de = (struct jpg_decode_s *)s->priv;
|
|
os_work_cancle2(&jpg_de->work, 1);
|
|
//关闭硬件
|
|
scale_close(jpg_de->scale_dev);
|
|
jpg_close(jpg_de->jpg_dev);
|
|
|
|
if(jpg_de->parent_data_s)
|
|
{
|
|
os_printf("parent_data_s:%X\n",jpg_de->parent_data_s);
|
|
free_data(jpg_de->parent_data_s);
|
|
jpg_de->parent_data_s = NULL;
|
|
}
|
|
|
|
if(jpg_de->current_data_s)
|
|
{
|
|
os_printf("parent_data_s:%X\n",jpg_de->current_data_s);
|
|
force_del_data(jpg_de->current_data_s);
|
|
jpg_de->current_data_s = NULL;
|
|
}
|
|
|
|
//释放line_buf
|
|
STREAM_LIBC_FREE(jpg_de->scaler2buf);
|
|
jpg_de->scalerbuf_size = 0;
|
|
|
|
|
|
}
|
|
break;
|
|
|
|
case STREAM_MARK_GC_END:
|
|
{
|
|
STREAM_LIBC_FREE(s->priv);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
//默认都返回成功
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
stream *jpg_decode_stream(const char *name)
|
|
{
|
|
|
|
stream *s = open_stream_available(name,8,8,opcode_func,NULL);
|
|
return s;
|
|
}
|
|
|
|
|
|
//不是立刻绑定,动态绑定
|
|
stream *jpg_decode_stream_not_bind(const char *name)
|
|
{
|
|
|
|
stream *s = open_stream_available(name,8,8,opcode_func_not_bind,NULL);
|
|
return s;
|
|
} |