From 68fcded9327dc8dfbd06fe9fefa4f4f715e8ab3a Mon Sep 17 00:00:00 2001 From: Song Zhao Date: Tue, 17 Dec 2019 21:35:41 -0800 Subject: [PATCH] v4l2: mpeg2: support multi-planar [1/1] PD#SWPL-12624 Problem: 1. Enable V4L2 Mpeg2 decoder 2. Enable V4L2 Mpeg2 ucode parser to support secure mode Solution: * Use canvas linear mode * Support NV21 * Add frame dump feature in aml_port * Use width/heigh from IF layer before ucode is enable to parse it, it will make sure canvas is correctly configured (not 0 width and height). * Add 00 00 01 00 padding for every frame in unsecure mode * pass buffer margin number from interface to decoder. Make sure vdec_mpeg12_hw_s->buf_num and aml_vcodec_ctx->dpb_size are in sync. * use completion to wait for decoder to parse the stream * Also limite the buffer number returned from REQBUFS to ctx->dbp_size It will prevent application from allocate more memory than enough. Verify: U212 Change-Id: Ib7542fccdde6a10f9ec38b5584b8b523d4d378dc Signed-off-by: Song Zhao --- drivers/amvdec_ports/aml_vcodec_dec.c | 34 ++++- drivers/amvdec_ports/aml_vcodec_dec_drv.c | 4 + drivers/amvdec_ports/decoder/vdec_mpeg12_if.c | 108 +++++++++++++- .../decoder/mpeg12/vmpeg12_multi.c | 139 +++++++++++++----- .../decoder/utils/vdec_v4l2_buffer_ops.c | 15 ++ .../decoder/utils/vdec_v4l2_buffer_ops.h | 4 + 6 files changed, 263 insertions(+), 41 deletions(-) diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index bd36b4d..880f3a5 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c @@ -160,6 +160,7 @@ static const struct aml_codec_framesizes aml_vdec_framesizes[] = { #define NUM_FORMATS ARRAY_SIZE(aml_video_formats) extern bool multiplanar; +extern bool dump_capture_frame; extern int dmabuf_fd_install_data(int fd, void* data, u32 size); extern bool is_v4l2_buf_file(struct file *file); @@ -514,6 +515,20 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f dstbuf->vb.vb2_buf.timestamp = vf->timestamp; dstbuf->ready_to_display = true; + if (dump_capture_frame) { + struct file *fp; + fp = filp_open("/data/dec_dump.raw", + O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600); + if (!IS_ERR(fp)) { + struct vb2_buffer *vb = &dstbuf->vb.vb2_buf; + kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].bytesused, 0); + if (dstbuf->frame_buffer.num_planes == 2) + kernel_write(fp,vb2_plane_vaddr(vb, 1), + vb->planes[1].bytesused, 0); + filp_close(fp, NULL); + } + } + if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { dstbuf->lastframe = true; dstbuf->vb.flags = V4L2_BUF_FLAG_LAST; @@ -1158,6 +1173,16 @@ static int vidioc_decoder_reqbufs(struct file *file, void *priv, v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", __func__, q->type); + if (!V4L2_TYPE_IS_OUTPUT(rb->type)) { + /* driver needs match v4l buffer number with dpb_size */ + if (rb->count > ctx->dpb_size) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "reqbufs (st:%d) %d -> %d\n", + ctx->state, rb->count, ctx->dpb_size); + rb->count = ctx->dpb_size; + } + } + return v4l2_m2m_ioctl_reqbufs(file, priv, rb); } @@ -1936,10 +1961,17 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { if (vb->index >= ctx->dpb_size) { v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, - "enque capture buf idx %d is invalid.\n", vb->index); + "enque capture buf idx %d/%d is invalid.\n", + vb->index, ctx->dpb_size); return; } + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "y_addr: %lx, vf_h: %lx, state: %d", + buf->frame_buffer.m.mem[0].addr, + buf->frame_buffer.vf_handle, + buf->frame_buffer.status); + if (!buf->que_in_m2m) { v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "enque capture buf idx %d, vf: %lx\n", diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c index f1505fb..beb5c00 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c +++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c @@ -608,6 +608,10 @@ bool multiplanar; EXPORT_SYMBOL(multiplanar); module_param(multiplanar, bool, 0644); +bool dump_capture_frame; +EXPORT_SYMBOL(dump_capture_frame); +module_param(dump_capture_frame, bool, 0644); + EXPORT_SYMBOL(scatter_mem_enable); module_param(scatter_mem_enable, bool, 0644); diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c index c35a80d..89725fa 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c @@ -111,6 +111,8 @@ struct vdec_mpeg12_inst { struct aml_vdec_adapt vdec; struct vdec_mpeg12_vsi *vsi; struct vcodec_vfm_s vfm; + struct aml_dec_params parms; + struct completion comp; }; static void get_pic_info(struct vdec_mpeg12_inst *inst, @@ -146,6 +148,39 @@ static void get_dpb_size(struct vdec_mpeg12_inst *inst, unsigned int *dpb_sz) v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "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_mpeg12_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_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_mpeg12_inst *inst = NULL; @@ -162,6 +197,8 @@ static int vdec_mpeg12_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; @@ -242,13 +279,13 @@ static void fill_vdec_params(struct vdec_mpeg12_inst *inst, /* config canvas size that be used for decoder. */ pic->coded_width = ALIGN(dec_ps->coded_width, 64); - pic->coded_height = ALIGN(dec_ps->coded_height, 64);; + pic->coded_height = ALIGN(dec_ps->coded_height, 32); 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); + /*1(EOS) + 8(DECODE_BUFFER_NUM_DEF)*/ + dec->dpb_sz = 9; v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", @@ -256,6 +293,24 @@ static void fill_vdec_params(struct vdec_mpeg12_inst *inst, pic->visible_width, pic->visible_height, dec->dpb_sz); } +static int stream_parse_by_ucode(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write(vdec, buf, size, 0); + if (ret < 0) { + pr_err("write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + static int stream_parse(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) { int ret = 0; @@ -296,7 +351,9 @@ static int vdec_mpeg12_probe(unsigned long h_vdec, if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) return 0; - if (st->magic == NORe || st->magic == NORn) + if (inst->ctx->param_sets_from_ucode) + ret = stream_parse_by_ucode(inst, buf, size); + else if (st->magic == NORe || st->magic == NORn) ret = stream_parse(inst, st->data, st->length); else ret = stream_parse(inst, buf, size); @@ -453,10 +510,48 @@ static int vdec_mpeg12_get_param(unsigned long h_vdec, return ret; } +static void set_param_write_sync(struct vdec_mpeg12_inst *inst) +{ + complete(&inst->comp); +} + static void set_param_ps_info(struct vdec_mpeg12_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_mpeg12_dec_info *dec = &inst->vsi->dec; + struct v4l2_rect *rect = &inst->vsi->crop; + + /* 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 + 1; + + 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 int vdec_mpeg12_set_param(unsigned long h_vdec, @@ -472,6 +567,9 @@ static int vdec_mpeg12_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/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index 8bb1d6b..356506d 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -46,6 +46,7 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/config_parser.h" #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" @@ -385,11 +386,13 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int { 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->pics[i].v4l_ref_buf_addr) return 0; @@ -397,44 +400,57 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { debug_print(DECODE_ID(hw), 0, - "[%d] get fb fail.\n", - ((struct aml_vcodec_ctx *) - (hw->v4l2_ctx))->id); + "[%d] get fb fail %d/%d.\n", + ctx->id, i, hw->buf_num); 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.coded_width; + hw->frame_height = pic.coded_height; + debug_print(DECODE_ID(hw), 0, + "[%d] set %d x %d from IF layer\n", ctx->id, + hw->frame_width, hw->frame_height); + } + hw->pics[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); 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); 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; } debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n", - ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, __func__, fb); + ctx->id, __func__, fb); if (vdec->parallel_dec == 1) { u32 tmp; - if (canvas_y(hw->canvas_spec[i]) == 0xff) { - tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - hw->canvas_spec[i] &= ~0xff; - hw->canvas_spec[i] |= tmp; - } if (canvas_u(hw->canvas_spec[i]) == 0xff) { tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); hw->canvas_spec[i] &= ~(0xffff << 8); hw->canvas_spec[i] |= tmp << 8; hw->canvas_spec[i] |= tmp << 16; } + if (canvas_y(hw->canvas_spec[i]) == 0xff) { + tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); + hw->canvas_spec[i] &= ~0xff; + hw->canvas_spec[i] |= tmp; + } canvas = hw->canvas_spec[i]; } else { canvas = vdec->get_canvas(i, 2); @@ -449,7 +465,7 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; canvas_config_config(canvas_y(canvas), &hw->canvas_config[i][0]); - hw->canvas_config[i][1].phy_addr = decbuf_start + decbuf_y_size; + hw->canvas_config[i][1].phy_addr = decbuf_uv_start; hw->canvas_config[i][1].width = canvas_width; hw->canvas_config[i][1].height = canvas_height / 2; hw->canvas_config[i][1].block_mode = hw->canvas_mode; @@ -457,6 +473,12 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; canvas_config_config(canvas_u(canvas), &hw->canvas_config[i][1]); + debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL, + "[%d] %s(), canvas: 0x%x mode: %d y: %x uv: %x w: %d h: %d\n", + ctx->id, __func__, canvas, hw->canvas_mode, + decbuf_start, decbuf_uv_start, + canvas_width, canvas_height); + return 0; } @@ -1778,7 +1800,7 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) 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.coded_height = ALIGN(hw->frame_height, 32); ps.dpb_size = hw->buf_num; hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); @@ -2072,6 +2094,15 @@ static void vmpeg12_work_implement(struct vdec_mpeg12_hw_s *hw, 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); + } + if (hw->vdec_cb) hw->vdec_cb(vdec, hw->vdec_cb_arg); } @@ -2507,15 +2538,17 @@ static void check_timer_func(unsigned long arg) static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) { - int index, i; + u32 index, i; + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + index = find_free_buffer(hw); if (index < 0 || index >= hw->buf_num) return -1; if (!hw->init_flag) vmpeg12_canvas_init(hw); else { + WRITE_VREG(MREG_CO_MV_START, hw->buf_start); if (!hw->is_used_v4l) { - WRITE_VREG(MREG_CO_MV_START, hw->buf_start); for (i = 0; i < hw->buf_num; i++) { canvas_config_config(canvas_y(hw->canvas_spec[i]), &hw->canvas_config[i][0]); @@ -2585,6 +2618,13 @@ static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg); WRITE_VREG(AV_SCRATCH_H, hw->reg_signal_type); + if (READ_VREG(MREG_ERROR_COUNT) != 0 || + READ_VREG(MREG_FATAL_ERROR) != 0) + debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE, + "err_cnt:%d fa_err:%d\n", + READ_VREG(MREG_ERROR_COUNT), + READ_VREG(MREG_FATAL_ERROR)); + /* clear error count */ WRITE_VREG(MREG_ERROR_COUNT, 0); WRITE_VREG(MREG_FATAL_ERROR, 0); @@ -2593,6 +2633,13 @@ static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) #ifdef NV21 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17); #endif + + /* cbcr_merge_swap_en */ + if (hw->is_used_v4l + && (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21 + || v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) + SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); + if (!hw->ctx_valid) WRITE_VREG(AV_SCRATCH_J, hw->userdata_wp_ctx); @@ -2822,15 +2869,31 @@ void (*callback)(struct vdec_s *, void *), if (size < 0) { hw->input_empty++; hw->dec_result = DEC_RESULT_AGAIN; + + debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, + "vdec_prepare_input: Insufficient data\n"); vdec_schedule_work(&hw->work); return; } + + if (vdec_frame_based(vdec) && !vdec_secure(vdec)) { + /* HW needs padding (NAL start) for frame ending */ + char* tail = (char *)hw->chunk->block->start_virt; + + tail += hw->chunk->offset + hw->chunk->size; + tail[0] = 0; + tail[1] = 0; + tail[2] = 1; + tail[3] = 0; + codec_mm_dma_flush(tail, 4, DMA_TO_DEVICE); + } + if (vdec_frame_based(vdec) && debug_enable) { u8 *data = NULL; - - debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "run: chunk offset 0x%x, size %d\n", - hw->chunk->offset, hw->chunk->size); + if (hw->chunk) + debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, + "run: chunk offset 0x%x, size %d\n", + hw->chunk->offset, hw->chunk->size); if (!hw->chunk->block->is_mapped) data = codec_mm_vmap(hw->chunk->block->start + @@ -2981,25 +3044,34 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, &vf_provider_ops, pdata); - if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { - debug_print(DECODE_ID(hw), 0, "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; - } else { - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - } - hw->buf_num = vmpeg12_get_buf_num(hw); - if (pdata->parallel_dec == 1) { int i; for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) hw->canvas_spec[i] = 0xffffff; } platform_set_drvdata(pdev, pdata); + + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; hw->canvas_mode = pdata->canvas_mode; + if (pdata->config_len) { + 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->canvas_mode = config_val; + + if ((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0 && + get_config_int(pdata->config, + "parm_v4l_buffer_margin", + &config_val) == 0) + hw->dynamic_buf_num_margin= config_val; + } + + hw->buf_num = vmpeg12_get_buf_num(hw); hw->platform_dev = pdev; hw->tvp_flag = vdec_secure(pdata) ? CODEC_MM_FLAGS_TVP : 0; @@ -3037,9 +3109,6 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) reset_user_data_buf(hw); #endif - hw->is_used_v4l = (((unsigned long) - hw->vmpeg12_amstream_dec_info.param & 0x80) >> 7); - /*INIT_WORK(&userdata_push_work, userdata_push_do_work);*/ return 0; } diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c index 107efec..88d2947 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c @@ -15,6 +15,21 @@ int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx, } EXPORT_SYMBOL(vdec_v4l_get_buffer); +int vdec_v4l_get_pic_info(struct aml_vcodec_ctx *ctx, + struct vdec_pic_info *pic) +{ + int ret = 0; + + if (ctx->drv_handle == 0) + return -EIO; + + ret = ctx->dec_if->get_param(ctx->drv_handle, + GET_PARAM_PIC_INFO, pic); + + return ret; +} +EXPORT_SYMBOL(vdec_v4l_get_pic_info); + int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx, struct aml_vdec_ps_infos *ps) { diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h index 13f3543..6254509 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h @@ -8,6 +8,10 @@ int vdec_v4l_get_buffer( struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out); +int vdec_v4l_get_pic_info( + struct aml_vcodec_ctx *ctx, + struct vdec_pic_info *pic); + int vdec_v4l_set_ps_infos( struct aml_vcodec_ctx *ctx, struct aml_vdec_ps_infos *ps); -- 2.20.1