v4l: mpeg4 support parse of parms sets by ucode for v4l codec. [2/2]
authorPeng Yixin <yixin.peng@amlogic.com>
Wed, 1 Apr 2020 02:02:52 +0000 (10:02 +0800)
committerPeng Yixin <yixin.peng@amlogic.com>
Mon, 11 May 2020 06:10:28 +0000 (14:10 +0800)
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 <yixin.peng@amlogic.com>
drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
firmware/video_ucode.bin

index c9ec20274efa2beca84e6db7c2b81aef53514a07..4bc945ef009a601efa98ac7181e86b88dc34898a 100644 (file)
@@ -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;
index 9a70c9b871ec9b3981cc4bf3cd221931e5113b2a..c6bea5bfe531717b96d7a326ba8dc1fadb5ce0b0 100644 (file)
@@ -47,6 +47,7 @@
 #include "../utils/firmware.h"
 #include "../utils/vdec_v4l2_buffer_ops.h"
 #include "../utils/config_parser.h"
+#include <media/v4l2-mem2mem.h>
 
 #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__);
 
index 2bb4cc32af0c67540fc454e5c0871135884c58b5..be1e3a55fc6e449c89e62aa2e7769f9a7a676ea4 100644 (file)
Binary files a/firmware/video_ucode.bin and b/firmware/video_ucode.bin differ