From 9fdadf75a392c93a12b6d4fb5c4e965f19d388da Mon Sep 17 00:00:00 2001 From: Peng Yixin Date: Wed, 1 Apr 2020 10:02:52 +0800 Subject: [PATCH] v4l: mpeg4 support parse of parms sets by ucode for v4l codec. [2/2] PD#SWPL-23440 Problem: mpeg4 need to support parse of parms sets by ucode. Solution: mpeg4 support parse of parms sets by ucode. ucode gerrit id: 104148 ucode change id: I6f3ec Verify: u212 Change-Id: I8e7b5e4cddee999d3a753ffda3d76d3d90fa93df Signed-off-by: Peng Yixin --- drivers/amvdec_ports/decoder/vdec_mpeg4_if.c | 97 ++++++- .../decoder/mpeg4/vmpeg4_multi.c | 252 ++++++++++++++---- firmware/video_ucode.bin | Bin 1404416 -> 1404416 bytes 3 files changed, 282 insertions(+), 67 deletions(-) diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c index c9ec202..4bc945e 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c @@ -112,6 +112,7 @@ struct vdec_mpeg4_inst { struct aml_vdec_adapt vdec; struct vdec_mpeg4_vsi *vsi; struct vcodec_vfm_s vfm; + struct aml_dec_params parms; struct completion comp; }; @@ -144,10 +145,45 @@ static void get_crop_info(struct vdec_mpeg4_inst *inst, struct v4l2_rect *cr) static void get_dpb_size(struct vdec_mpeg4_inst *inst, unsigned int *dpb_sz) { - *dpb_sz = 9;//inst->vsi->dec.dpb_sz; + *dpb_sz = inst->vsi->dec.dpb_sz; v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz); } +static u32 vdec_config_default_parms(u8 *parm) +{ + u8 *pbuf = parm; + + pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); + pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;"); + pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:0;"); + + return pbuf - parm; +} + +static void vdec_parser_parms(struct vdec_mpeg4_inst *inst) +{ + struct aml_vcodec_ctx *ctx = inst->ctx; + + if (ctx->config.parm.dec.parms_status & + V4L2_CONFIG_PARM_DECODE_CFGINFO) { + u8 *pbuf = ctx->config.buf; + + pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); + pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;", + ctx->config.parm.dec.cfg.canvas_mem_mode); + pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;", + ctx->config.parm.dec.cfg.ref_buf_margin); + ctx->config.length = pbuf - ctx->config.buf; + } else { + ctx->config.length = vdec_config_default_parms(ctx->config.buf); + } + + inst->vdec.config = ctx->config; + inst->parms.cfg = ctx->config.parm.dec.cfg; + inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO; +} + + static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_mpeg4_inst *inst = NULL; @@ -165,6 +201,7 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vdec.ctx = ctx; inst->ctx = ctx; + vdec_parser_parms(inst); /* set play mode.*/ if (ctx->is_drm_mode) inst->vdec.port.flag |= PORT_FLAG_DRM; @@ -203,18 +240,10 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) goto err; } - inst->vsi->pic.visible_width = 1920; - inst->vsi->pic.visible_height = 1080; - inst->vsi->pic.coded_width = 1920; - inst->vsi->pic.coded_height = 1088; - inst->vsi->pic.y_bs_sz = 0; - inst->vsi->pic.y_len_sz = (1920 * 1088); - inst->vsi->pic.c_bs_sz = 0; - inst->vsi->pic.c_len_sz = (1920 * 1088 / 2); - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "mpeg4 Instance >> %lx\n", (ulong) inst); + init_completion(&inst->comp); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -268,8 +297,8 @@ static void fill_vdec_params(struct vdec_mpeg4_inst *inst, pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; - /* calc DPB size */ - dec->dpb_sz = 9;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h); + /*8(DECODE_BUFFER_NUM_DEF) */ + dec->dpb_sz = 8; v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", @@ -540,7 +569,46 @@ static int vdec_mpeg4_get_param(unsigned long h_vdec, static void set_param_ps_info(struct vdec_mpeg4_inst *inst, struct aml_vdec_ps_infos *ps) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "\n"); + struct vdec_pic_info *pic = &inst->vsi->pic; + struct vdec_mpeg4_dec_info *dec = &inst->vsi->dec; + struct v4l2_rect *rect = &inst->vsi->crop; + + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "%s in\n", __func__); + /* fill visible area size that be used for EGL. */ + pic->visible_width = ps->visible_width; + pic->visible_height = ps->visible_height; + + /* calc visible ares. */ + rect->left = 0; + rect->top = 0; + rect->width = pic->visible_width; + rect->height = pic->visible_height; + + /* config canvas size that be used for decoder. */ + pic->coded_width = ps->coded_width; + pic->coded_height = ps->coded_height; + pic->y_len_sz = pic->coded_width * pic->coded_height; + pic->c_len_sz = pic->y_len_sz >> 1; + + dec->dpb_sz = ps->dpb_size; + + inst->parms.ps = *ps; + inst->parms.parms_status |= + V4L2_CONFIG_PARM_DECODE_PSINFO; + + /*wake up*/ + complete(&inst->comp); + + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", + ps->visible_width, ps->visible_height, + ps->coded_width, ps->coded_height, + dec->dpb_sz); +} + +static void set_param_write_sync(struct vdec_mpeg4_inst *inst) +{ + complete(&inst->comp); } static int vdec_mpeg4_set_param(unsigned long h_vdec, @@ -556,6 +624,9 @@ static int vdec_mpeg4_set_param(unsigned long h_vdec, } switch (type) { + case SET_PARAM_WRITE_FRAME_SYNC: + set_param_write_sync(inst); + break; case SET_PARAM_PS_INFO: set_param_ps_info(inst, in); break; diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 9a70c9b..c6bea5b 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -47,6 +47,7 @@ #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" +#include #define DRIVER_NAME "ammvdec_mpeg4" #define MODULE_NAME "ammvdec_mpeg4" @@ -81,6 +82,7 @@ #define MP4_OFFSET_REG AV_SCRATCH_C #define MP4_SYS_RATE AV_SCRATCH_E #define MEM_OFFSET_REG AV_SCRATCH_F +#define MP4_PIC_INFO AV_SCRATCH_H #define PARC_FORBIDDEN 0 #define PARC_SQUARE 1 @@ -136,6 +138,8 @@ static struct vframe_s *vmpeg_vf_get(void *); static void vmpeg_vf_put(struct vframe_s *, void *); static int vmpeg_vf_states(struct vframe_states *states, void *); static int vmpeg_event_cb(int type, void *data, void *private_data); +static int notify_v4l_eos(struct vdec_s *vdec); + static int pre_decode_buf_level = 0x800; static int start_decode_buf_level = 0x4000; static int debug_enable; @@ -155,6 +159,8 @@ static u32 without_display_mode; #undef pr_info #define pr_info printk unsigned int mpeg4_debug_mask = 0xff; +static u32 run_ready_min_buf_num = 2; + #define PRINT_FLAG_ERROR 0x0 #define PRINT_FLAG_RUN_FLOW 0X0001 @@ -310,11 +316,13 @@ struct vdec_mpeg4_hw_s { u32 i_only; int sidebind_type; int sidebind_channel_id; + unsigned int res_ch_flag; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); static unsigned char get_data_check_sum(struct vdec_mpeg4_hw_s *hw, int size); +static void flush_output(struct vdec_mpeg4_hw_s * hw); #define PROVIDER_NAME "vdec.mpeg4" @@ -359,11 +367,13 @@ static int vmpeg4_v4l_alloc_buff_config_canvas(struct vdec_mpeg4_hw_s *hw, int i { int ret; u32 canvas; - ulong decbuf_start = 0; - int decbuf_y_size = 0; + ulong decbuf_start = 0, decbuf_uv_start = 0; + int decbuf_y_size = 0, decbuf_uv_size = 0; u32 canvas_width = 0, canvas_height = 0; struct vdec_s *vdec = hw_to_vdec(hw); struct vdec_v4l2_buffer *fb = NULL; + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); if (hw->pic[i].v4l_ref_buf_addr) return 0; @@ -377,20 +387,34 @@ static int vmpeg4_v4l_alloc_buff_config_canvas(struct vdec_mpeg4_hw_s *hw, int i return ret; } + if (!hw->frame_width || !hw->frame_height) { + struct vdec_pic_info pic; + vdec_v4l_get_pic_info(ctx, &pic); + hw->frame_width = pic.visible_width; + hw->frame_height = pic.visible_height; + mmpeg4_debug_print(DECODE_ID(hw), 0, + "[%d] set %d x %d from IF layer\n", ctx->id, + hw->frame_width, hw->frame_height); + } + hw->pic[i].v4l_ref_buf_addr = (ulong)fb; if (fb->num_planes == 1) { decbuf_start = fb->m.mem[0].addr; decbuf_y_size = fb->m.mem[0].offset; + decbuf_uv_start = decbuf_start + decbuf_y_size; + decbuf_uv_size = decbuf_y_size / 2; canvas_width = ALIGN(hw->frame_width, 64); - canvas_height = ALIGN(hw->frame_height, 32); + canvas_height = ALIGN(hw->frame_height, 64); fb->m.mem[0].bytes_used = fb->m.mem[0].size; } else if (fb->num_planes == 2) { decbuf_start = fb->m.mem[0].addr; decbuf_y_size = fb->m.mem[0].size; + decbuf_uv_start = fb->m.mem[1].addr; + decbuf_uv_size = fb->m.mem[1].size; canvas_width = ALIGN(hw->frame_width, 64); - canvas_height = ALIGN(hw->frame_height, 32); + canvas_height = ALIGN(hw->frame_height, 64); fb->m.mem[0].bytes_used = decbuf_y_size; - fb->m.mem[1].bytes_used = decbuf_y_size << 1; + fb->m.mem[1].bytes_used = decbuf_uv_size; } mmpeg4_debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n", @@ -427,7 +451,7 @@ static int vmpeg4_v4l_alloc_buff_config_canvas(struct vdec_mpeg4_hw_s *hw, int i &hw->canvas_config[i][0]); hw->canvas_config[i][1].phy_addr = - decbuf_start + decbuf_y_size; + decbuf_uv_start; hw->canvas_config[i][1].width = canvas_width; hw->canvas_config[i][1].height = (canvas_height >> 1); hw->canvas_config[i][1].block_mode = hw->blkmode; @@ -465,9 +489,18 @@ static int find_free_buffer(struct vdec_mpeg4_hw_s *hw) if (i == hw->buf_num) return -1; - if (hw->is_used_v4l) - if (vmpeg4_v4l_alloc_buff_config_canvas(hw, i)) - return -1; + if (hw->is_used_v4l) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { + /*run to parser csd data*/ + i = 0; + } else { + if (vmpeg4_v4l_alloc_buff_config_canvas(hw, i)) + return -1; + } + } + return i; } @@ -881,6 +914,53 @@ static void vmpeg4_prepare_input(struct vdec_mpeg4_hw_s *hw) } } +static int vmpeg4_get_ps_info(struct vdec_mpeg4_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps) +{ + ps->visible_width = width; + ps->visible_height = height; + ps->coded_width = ALIGN(width, 64); + ps->coded_height = ALIGN(height, 64); + ps->dpb_size = hw->buf_num; + + return 0; +} + +static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height) +{ + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + int ret = 0; + + if (ctx->param_sets_from_ucode && + hw->res_ch_flag == 0) { + struct aml_vdec_ps_infos ps; + + if ((hw->frame_width != 0 && + hw->frame_height != 0) && + (hw->frame_width != width || + hw->frame_height != height)) { + mmpeg4_debug_print(DECODE_ID(hw), 0, + "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d)\n", + hw->frame_width, hw->frame_height, + width, + height); + vmpeg4_get_ps_info(hw, width, height, &ps); + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + hw->v4l_params_parsed = false; + hw->res_ch_flag = 1; + hw->eos = 1; + flush_output(hw); + notify_v4l_eos(hw_to_vdec(hw)); + + ret = 1; + } + } + + return ret; +} + + static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) { u32 reg; @@ -897,6 +977,35 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) if (hw->eos) return IRQ_HANDLED; + if (READ_VREG(MP4_PIC_INFO) == 1) { + if (hw->is_used_v4l) { + int frame_width = READ_VREG(MP4_PIC_WH)>> 16; + int frame_height = READ_VREG(MP4_PIC_WH) & 0xffff; + if (!v4l_res_change(hw, frame_width, frame_height)) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { + struct aml_vdec_ps_infos ps; + + vmpeg4_get_ps_info(hw, frame_width, frame_height, &ps); + hw->v4l_params_parsed = true; + vdec_v4l_set_ps_infos(ctx, &ps); + reset_process_time(hw); + hw->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hw->work); + } else { + WRITE_VREG(MP4_PIC_INFO, 0); + } + } else { + reset_process_time(hw); + hw->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hw->work); + } + } else + WRITE_VREG(MP4_PIC_INFO, 0); + return IRQ_HANDLED; + } + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); if (READ_VREG(AV_SCRATCH_M) != 0 && (debug_enable & PRINT_FLAG_UCODE_DETAIL)) { @@ -994,23 +1103,6 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) if (dec_h != 0) hw->frame_height = dec_h; - if (hw->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - - if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - - ps.visible_width = hw->frame_width; - ps.visible_height = hw->frame_height; - ps.coded_width = ALIGN(hw->frame_width, 64); - ps.coded_height = ALIGN(hw->frame_height, 64); - ps.dpb_size = hw->buf_num; - hw->v4l_params_parsed = true; - vdec_v4l_set_ps_infos(ctx, &ps); - } - } - if (hw->vmpeg4_amstream_dec_info.rate == 0) { if (vop_time_inc < hw->last_vop_time_inc) { duration = vop_time_inc + @@ -1305,6 +1397,7 @@ static int notify_v4l_eos(struct vdec_s *vdec) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); struct vframe_s *vf = NULL; struct vdec_v4l2_buffer *fb = NULL; + int index; if (hw->is_used_v4l && hw->eos) { if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) { @@ -1314,13 +1407,18 @@ static int notify_v4l_eos(struct vdec_s *vdec) return -1; } - if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { + index = find_free_buffer(hw); + + if ((index == -1) && + vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { pr_err("[%d] get fb fail.\n", ctx->id); return -1; } + vf->type |= VIDTYPE_V4L_EOS; vf->timestamp = ULONG_MAX; - vf->v4l_mem_handle = (unsigned long)fb; + vf->v4l_mem_handle = (index == -1) ? (ulong)fb : + hw->pic[index].v4l_ref_buf_addr;; vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; kfifo_put(&hw->display_q, (const struct vframe_s *)vf); @@ -1405,6 +1503,15 @@ static void vmpeg4_work(struct work_struct *work) del_timer_sync(&hw->check_timer); hw->stat &= ~STAT_TIMER_ARM; + if (hw->is_used_v4l) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + + if (ctx->param_sets_from_ucode && + !hw->v4l_params_parsed) + vdec_v4l_write_frame_sync(ctx); + } + /* mark itself has all HW resource released and input released */ if (vdec->parallel_dec == 1) vdec_core_finish_run(vdec, CORE_MASK_VDEC_1); @@ -1879,7 +1986,7 @@ static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw) /* disable PSCALE for hardware sharing */ WRITE_VREG(PSCALE_CTRL, 0); - WRITE_VREG(MREG_BUFFEROUT, 0); + WRITE_VREG(MREG_BUFFEROUT, 0x10000); /* clear mailbox interrupt */ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); @@ -1938,8 +2045,14 @@ static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw) hw->vmpeg4_rotation = (((unsigned long)hw->vmpeg4_amstream_dec_info.param) >> 16) & 0xffff; hw->sys_mp4_rate = hw->vmpeg4_amstream_dec_info.rate; - hw->frame_width = hw->vmpeg4_amstream_dec_info.width; - hw->frame_height = hw->vmpeg4_amstream_dec_info.height; + if (hw->is_used_v4l) { + hw->frame_width = 0; + hw->frame_height = 0; + } else { + hw->frame_width = hw->vmpeg4_amstream_dec_info.width; + hw->frame_height = hw->vmpeg4_amstream_dec_info.height; + } + hw->frame_dur = 0; hw->frame_prog = 0; hw->unstable_pts = @@ -2081,6 +2194,29 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) } } + if (hw->is_used_v4l) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + + if (ctx->param_sets_from_ucode) { + if (hw->v4l_params_parsed) { + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + return 0; + } else { + if ((hw->res_ch_flag == 1) && + ((ctx->state <= AML_STATE_INIT) || + (ctx->state >= AML_STATE_FLUSHING))) + return 0; + } + } else if (!ctx->v4l_codec_dpb_ready) { + if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + return 0; + } + } + if (!is_enough_free_buffer(hw)) { hw->buffer_not_ready++; return 0; @@ -2334,27 +2470,6 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); hw->platform_dev = pdev; - if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { - mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "pdata->config: %s\n", pdata->config); - if (get_config_int(pdata->config, "parm_v4l_buffer_margin", - &config_val) == 0) - hw->dynamic_buf_num_margin = config_val; - else - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - - if (get_config_int(pdata->config, "sidebind_type", - &config_val) == 0) - hw->sidebind_type = config_val; - - if (get_config_int(pdata->config, "sidebind_channel_id", - &config_val) == 0) - hw->sidebind_channel_id = config_val; - } else { - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - } - hw->buf_num = vmpeg4_get_buf_num(hw); - if (pdata->parallel_dec == 1) { int i; for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) @@ -2384,10 +2499,39 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) hw->vmpeg4_amstream_dec_info.width, hw->vmpeg4_amstream_dec_info.height, hw->vmpeg4_amstream_dec_info.rate); - hw->is_used_v4l = (((unsigned long) - hw->vmpeg4_amstream_dec_info.param & 0x80) >> 7); } + if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { + mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, + "pdata->config: %s\n", pdata->config); + if (get_config_int(pdata->config, "parm_v4l_buffer_margin", + &config_val) == 0) + hw->dynamic_buf_num_margin = config_val; + else + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + + if (get_config_int(pdata->config, "sidebind_type", + &config_val) == 0) + hw->sidebind_type = config_val; + + if (get_config_int(pdata->config, "sidebind_channel_id", + &config_val) == 0) + hw->sidebind_channel_id = config_val; + + if (get_config_int(pdata->config, + "parm_v4l_codec_enable", + &config_val) == 0) + hw->is_used_v4l = config_val; + + if (get_config_int(pdata->config, + "parm_v4l_canvas_mem_mode", + &config_val) == 0) + hw->blkmode = config_val; + } else + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; + + hw->buf_num = vmpeg4_get_buf_num(hw); + if (vmmpeg4_init(hw) < 0) { pr_err("%s init failed.\n", __func__); diff --git a/firmware/video_ucode.bin b/firmware/video_ucode.bin index 2bb4cc32af0c67540fc454e5c0871135884c58b5..be1e3a55fc6e449c89e62aa2e7769f9a7a676ea4 100644 GIT binary patch delta 11758 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 j72c{)^A64w720h&A#?euk(jAg=4N3w*9y2s