v4l: fixed some issues for v4l codec. [1/1]
authorNanxin Qin <nanxin.qin@amlogic.com>
Sun, 24 Nov 2019 09:40:53 +0000 (17:40 +0800)
committerZhi Zhou <zhi.zhou@amlogic.com>
Wed, 27 Nov 2019 16:02:59 +0000 (09:02 -0700)
PD#SWPL-5313

Problem:
Decoder V4L2 interface Phase3(AFBC&MMU Support)

Solution:
1. fixed an issue of get/set parms abnormal.
2. fixed the issue of register vfm failed cause crash.
3. added post events for exception happend.
4. fixed profile_idc changes cause stuck.

Verify:
U212

Change-Id: I4519c91409d570e6fe8f9fedaad6c48628be85a0
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
22 files changed:
drivers/amvdec_ports/aml_vcodec_adapt.c
drivers/amvdec_ports/aml_vcodec_dec.c
drivers/amvdec_ports/aml_vcodec_dec.h
drivers/amvdec_ports/aml_vcodec_drv.h
drivers/amvdec_ports/aml_vcodec_vfm.c
drivers/amvdec_ports/aml_vcodec_vfm.h
drivers/amvdec_ports/decoder/aml_h264_parser.c
drivers/amvdec_ports/decoder/vdec_h264_if.c
drivers/amvdec_ports/decoder/vdec_hevc_if.c
drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
drivers/amvdec_ports/decoder/vdec_vp9_if.c
drivers/amvdec_ports/vdec_drv_if.h
drivers/frame_provider/decoder/h264_multi/vmh264.c
drivers/frame_provider/decoder/h265/vh265.c
drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
drivers/frame_provider/decoder/vp9/vvp9.c

index a307a2b41e7b190e3283d1a2c99ee4b51148bc61..7ac9ad5a6858b502ed0b6e0d2b2ff8f2562cb301 100644 (file)
@@ -695,7 +695,7 @@ int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
        /* dump to file */
        dump_write(buf, count);
 #endif
-       aml_v4l2_debug(4, "[%d] write frames, vbuf: %p, size: %u, ret: %d, crc: %x",
+       aml_v4l2_debug(3, "[%d] write frames, vbuf: %p, size: %u, ret: %d, crc: %x",
                ada_ctx->ctx->id, buf, count, ret, crc32_le(0, buf, count));
 
        return ret;
index 7774522e3a3adfcc8f18fc74a79bc84c8f61b175..f0a0d88008f20b09d7ef93ce79851adeae0127cd 100644 (file)
@@ -203,16 +203,26 @@ static struct aml_q_data *aml_vdec_get_q_data(struct aml_vcodec_ctx *ctx,
        return &ctx->q_data[AML_Q_DATA_DST];
 }
 
-static void aml_vdec_queue_res_chg_event(struct aml_vcodec_ctx *ctx)
+void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes)
 {
-       static const struct v4l2_event ev_src_ch = {
-               .type = V4L2_EVENT_SOURCE_CHANGE,
-               .u.src_change.changes =
-               V4L2_EVENT_SRC_CH_RESOLUTION,
-       };
+       struct v4l2_event event = {0};
 
-       aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
-       v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
+       switch (changes) {
+       case V4L2_EVENT_SRC_CH_RESOLUTION:
+       case V4L2_EVENT_SRC_CH_HDRINFO:
+       case V4L2_EVENT_REQUEST_RESET:
+       case V4L2_EVENT_REQUEST_EXIT:
+               event.type = V4L2_EVENT_SOURCE_CHANGE;
+               event.u.src_change.changes = changes;
+               break;
+       default:
+               pr_err("unsupport dispatch event %x\n", changes);
+               return;
+       }
+
+       v4l2_event_queue_fh(&ctx->fh, &event);
+       aml_v4l2_debug(3, "[%d] %s() changes: %x",
+               ctx->id, __func__, changes);
 }
 
 static void aml_vdec_flush_decoder(struct aml_vcodec_ctx *ctx)
@@ -484,6 +494,10 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f
 
        if (dstbuf->lastframe &&
                ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
+
+               /* make the run to stanby until new buffs to enque. */
+               ctx->v4l_codec_dpb_ready = false;
+
                /*
                 * After all buffers containing decoded frames from
                 * before the resolution change point ready to be
@@ -492,7 +506,7 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f
                 * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper
                 * layer will get new information from cts->picinfo.
                 */
-               aml_vdec_queue_res_chg_event(ctx);
+               aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
        }
 
        ctx->decoded_frame_cnt++;
@@ -518,6 +532,23 @@ static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffe
        return ret;
 }
 
+static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
+{
+       if (!ctx->v4l_codec_dpb_ready) {
+               int buf_ready_num;
+
+               /* is there enough dst bufs for decoding? */
+               buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
+               if ((ctx->dpb_size) &&
+                       ((buf_ready_num + ctx->buf_used_count) >= ctx->dpb_size))
+                       ctx->v4l_codec_dpb_ready = true;
+               aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d, dpb is ready: %s",
+                               ctx->id, __func__, ctx->dpb_size,
+                               buf_ready_num, ctx->buf_used_count,
+                               ctx->v4l_codec_dpb_ready ? "yes" : "no");
+       }
+}
+
 static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
 {
        struct aml_vcodec_dev *dev = ctx->dev;
@@ -552,17 +583,8 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
        }
        mutex_unlock(&ctx->state_lock);
 
-       if (!ctx->v4l_codec_dpb_ready) {
-               int buf_ready_num;
-
-               /* is there enough dst bufs for decoding? */
-               buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
-               if ((buf_ready_num + ctx->buf_used_count) >= ctx->dpb_size)
-                       ctx->v4l_codec_dpb_ready = true;
-               aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d",
-                               ctx->id, __func__, ctx->dpb_size,
-                               buf_ready_num, ctx->buf_used_count);
-       }
+       /* check dpb ready */
+       //aml_check_dpb_ready(ctx);
 
        return 1;
 }
@@ -653,7 +675,7 @@ static void aml_vdec_worker(struct work_struct *work)
                mutex_lock(&ctx->state_lock);
                if (ctx->state == AML_STATE_ACTIVE) {
                        ctx->state = AML_STATE_FLUSHING;// prepare flushing
-                       aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-END)",
+                       aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-LASTFRM)",
                                ctx->id, __func__);
                }
                mutex_unlock(&ctx->state_lock);
@@ -934,9 +956,16 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
                                V4L2_BUF_TYPE_VIDEO_CAPTURE);
        switch (cmd->cmd) {
        case V4L2_DEC_CMD_STOP:
-
-               if (ctx->state != AML_STATE_ACTIVE)
-                       return 0;
+               if (ctx->state != AML_STATE_ACTIVE) {
+                       if (ctx->state >= AML_STATE_IDLE &&
+                               ctx->state <= AML_STATE_PROBE) {
+                               ctx->state = AML_STATE_ABORT;
+                               aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
+                               aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
+                                       ctx->id, __func__);
+                               return -1;
+                       }
+               }
 
                src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
                                V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
@@ -1684,6 +1713,9 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
                        buf->queued_in_vb2 = true;
                        buf->queued_in_v4l2 = true;
                        buf->ready_to_display = false;
+
+                       /* check dpb ready */
+                       aml_check_dpb_ready(ctx);
                } else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
                        buf->queued_in_vb2 = false;
                        buf->queued_in_v4l2 = true;
@@ -1737,7 +1769,7 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
 
        ctx->dpb_size = dpb;
        ctx->last_decoded_picinfo = ctx->picinfo;
-       aml_vdec_queue_res_chg_event(ctx);
+       aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
 
        mutex_lock(&ctx->state_lock);
        if (ctx->state == AML_STATE_INIT) {
@@ -2071,10 +2103,22 @@ static int vidioc_vdec_s_parm(struct file *file, void *fh,
        struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
 
        if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+               struct aml_dec_params *in =
+                       (struct aml_dec_params *) a->parm.raw_data;
+               struct aml_dec_params *dec = &ctx->config.parm.dec;
+
                ctx->config.type = V4L2_CONFIG_PARM_DECODE;
-               ctx->config.length = sizeof(a->parm.raw_data);
-               memcpy(ctx->config.parm.data, a->parm.raw_data,
-                       sizeof(a->parm.raw_data));
+
+               if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+                       dec->cfg = in->cfg;
+               if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+                       dec->ps = in->ps;
+               if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+                       dec->hdr = in->hdr;
+               if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+                       dec->cnt = in->cnt;
+
+               dec->parms_status |= in->parms_status;
        }
 
        return 0;
index c46585722270cd35e45d377e423436ace45e5225..7ca3337654329628ba458eee5798cbf872e60bc4 100644 (file)
 
 #define AML_V4L2_SET_DECMODE (V4L2_CID_USER_AMLOGIC_BASE + 0)
 
-/* codec types of get/set parms. */
-#define V4L2_CONFIG_PARM_ENCODE                (0)
-#define V4L2_CONFIG_PARM_DECODE                (1)
-
-/* types of decode parms. */
-#define V4L2_CONFIG_PARM_DECODE_COMMON (1 << 0)
-#define V4L2_CONFIG_PARM_DECODE_PICINFO        (1 << 1)
-#define V4L2_CONFIG_PARM_DECODE_HDRINFO        (1 << 2)
-
 /* for video composer metafd private_data struct */
 struct file_privdata {
        struct vframe_s vf;
@@ -139,5 +130,6 @@ int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
 void aml_thread_stop(struct aml_vcodec_ctx *ctx);
 void wait_vcodec_ending(struct aml_vcodec_ctx *ctx);
 void vdec_frame_buffer_release(void *data);
+void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes);
 
 #endif /* _AML_VCODEC_DEC_H_ */
index 21a1ab2445823b1c791163602238747f93122a3d..fb1930e179503c1c4dadb04437a9928ab98ebd68 100644 (file)
 #define AML_V4L2_BENCHMARK     0
 #define WAIT_INTR_TIMEOUT_MS   1000
 
+/* codec types of get/set parms. */
+#define V4L2_CONFIG_PARM_ENCODE                (0)
+#define V4L2_CONFIG_PARM_DECODE                (1)
+
+/* types of decode parms. */
+#define V4L2_CONFIG_PARM_DECODE_CFGINFO        (1 << 0)
+#define V4L2_CONFIG_PARM_DECODE_PSINFO (1 << 1)
+#define V4L2_CONFIG_PARM_DECODE_HDRINFO        (1 << 2)
+#define V4L2_CONFIG_PARM_DECODE_CNTINFO        (1 << 3)
+
+/* amlogic event define. */
+/* #define V4L2_EVENT_SRC_CH_RESOLUTION        (1 << 0) */
+#define V4L2_EVENT_SRC_CH_HDRINFO      (1 << 1)
+#define V4L2_EVENT_SRC_CH_PSINFO       (1 << 2)
+#define V4L2_EVENT_SRC_CH_CNTINFO      (1 << 3)
+
+/* exception handing */
+#define V4L2_EVENT_REQUEST_RESET       (1 << 8)
+#define V4L2_EVENT_REQUEST_EXIT                (1 << 9)
+
 /**
  * enum aml_hw_reg_idx - AML hw register base index
  */
@@ -234,14 +254,15 @@ struct vdec_pic_info {
        unsigned int c_bs_sz;
        unsigned int y_len_sz;
        unsigned int c_len_sz;
+       int profile_idc;
 };
 
-struct aml_vdec_pic_infos {
-       u32 visible_width;
-       u32 visible_height;
-       u32 coded_width;
-       u32 coded_height;
-       u32 dpb_size;
+struct aml_vdec_cfg_infos {
+       u32 double_write_mode;
+       u32 init_width;
+       u32 init_height;
+       u32 ref_buf_margin;
+       u32 block_mode;
 };
 
 struct aml_vdec_hdr_infos {
@@ -265,16 +286,33 @@ struct aml_vdec_hdr_infos {
        struct vframe_master_display_colour_s color_parms;
 };
 
+struct aml_vdec_ps_infos {
+       u32 visible_width;
+       u32 visible_height;
+       u32 coded_width;
+       u32 coded_height;
+       u32 profile;
+       u32 mb_width;
+       u32 mb_height;
+       u32 dpb_size;
+       u32 ref_frames;
+       u32 reorder_frames;
+};
+
+struct aml_vdec_cnt_infos {
+       u32 bit_rate;
+       u32 frame_count;
+       u32 error_frame_count;
+       u32 drop_frame_count;
+       u32 total_data;
+};
+
 struct aml_dec_params {
-       u32 dec_parms_status;
-       u32 es_need_header;
-       u32 double_write_mode;
-       u32 buffer_mode;
-       u32 buffer_width;
-       u32 buffer_height;
-       u32 buffer_margin;
-       struct aml_vdec_pic_infos pic;
-       struct aml_vdec_hdr_infos hdr;
+       u32 parms_status;
+       struct aml_vdec_cfg_infos       cfg;
+       struct aml_vdec_ps_infos        ps;
+       struct aml_vdec_hdr_infos       hdr;
+       struct aml_vdec_cnt_infos       cnt;
 };
 
 struct v4l2_config_parm {
index e7b85fb0fbe7c7616da99aee98e5d0474edba85d..f5fdc7b5a92fa27dfd8371d463f8bfc3deeda495 100644 (file)
@@ -214,6 +214,8 @@ struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm)
 
 int vcodec_vfm_init(struct vcodec_vfm_s *vfm)
 {
+       int ret;
+
        snprintf(vfm->recv_name, VF_NAME_SIZE, "%s-%d",
                RECEIVER_NAME, vfm->ctx->id);
        snprintf(vfm->prov_name, VF_NAME_SIZE, "%s-%d",
@@ -222,13 +224,16 @@ int vcodec_vfm_init(struct vcodec_vfm_s *vfm)
        vfm->ada_ctx->recv_name = vfm->recv_name;
 
        vf_receiver_init(&vfm->vf_recv, vfm->recv_name, &vf_receiver, vfm);
-       vf_reg_receiver(&vfm->vf_recv);
+       ret = vf_reg_receiver(&vfm->vf_recv);
 
-       return 0;
+       vfm->vfm_initialized = ret ? false : true;
+
+       return ret;
 }
 
 void vcodec_vfm_release(struct vcodec_vfm_s *vfm)
 {
-       vf_unreg_receiver(&vfm->vf_recv);
+       if (vfm->vfm_initialized)
+               vf_unreg_receiver(&vfm->vf_recv);
 }
 
index 9aaf266ed3ff9400429a48dcb272bed8fb7fdf8a..141e9a77655a5fb35c4f4e9260b4becc07417573 100644 (file)
@@ -41,6 +41,7 @@ struct vcodec_vfm_s {
        char prov_name[VF_NAME_SIZE];
        struct vframe_provider_s vf_prov;
        struct vframe_receiver_s vf_recv;
+       bool vfm_initialized;
 };
 
 int vcodec_vfm_init(struct vcodec_vfm_s *vfm);
index d5d1d91a21cbf2682c24b38ef71a349a43b8c688..8963afd845445ce8c109f4f24926a8eb9cdf904d 100644 (file)
@@ -495,6 +495,7 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s
                goto out;
        }
 
+#if 0
        /* if the maximum delay is not stored in the SPS, derive it based on the level */
        if (!sps->bitstream_restriction_flag && sps->ref_frame_count) {
                sps->num_reorder_frames = MAX_DELAYED_PIC_COUNT - 1;
@@ -507,6 +508,28 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s
                        }
                }
        }
+#endif
+
+       sps->num_reorder_frames = MAX_DELAYED_PIC_COUNT - 1;
+       for (i = 0; i < ARRAY_SIZE(level_max_dpb_mbs); i++) {
+               if (level_max_dpb_mbs[i][0] == sps->level_idc) {
+                       sps->num_reorder_frames =
+                               MIN(level_max_dpb_mbs[i][1] / (sps->mb_width * sps->mb_height),
+                                       sps->num_reorder_frames);
+                       sps->num_reorder_frames += 1;
+                       if (sps->max_dec_frame_buffering > sps->num_reorder_frames)
+                               sps->num_reorder_frames = sps->max_dec_frame_buffering;
+                       break;
+               }
+       }
+
+       if ((sps->bitstream_restriction_flag) &&
+               (sps->max_dec_frame_buffering <
+               sps->num_reorder_frames)) {
+               sps->num_reorder_frames = sps->max_dec_frame_buffering;
+               pr_info("set reorder_pic_num to %d\n",
+                       sps->num_reorder_frames);
+       }
 
        if (!sps->sar.den)
                sps->sar.den = 1;
index 7bf4d5e8dec272eeb2efda6609baa815722f9c58..ea1d0f8b367ffa0cfbccbc3f2d0afc4833f50e01 100644 (file)
@@ -261,29 +261,24 @@ static void vdec_parser_parms(struct vdec_h264_inst *inst)
 {
        struct aml_vcodec_ctx *ctx = inst->ctx;
 
-       if (!ctx->config.length) {
-               ctx->config.type = V4L2_CONFIG_PARM_DECODE;
-               ctx->config.parm.dec.double_write_mode = 16;
-               inst->parms = ctx->config.parm.dec;
-
-               ctx->config.length =
-                       vdec_config_default_parms(ctx->config.buf);
-       } else {
+       if (ctx->config.parm.dec.parms_status &
+               V4L2_CONFIG_PARM_DECODE_CFGINFO) {
                u8 *pbuf = ctx->config.buf;
 
-               inst->parms = ctx->config.parm.dec;
                pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
                pbuf += sprintf(pbuf, "mh264_double_write_mode:%d;",
-                       inst->parms.double_write_mode);
+                       ctx->config.parm.dec.cfg.double_write_mode);
                pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
-                       inst->parms.buffer_margin);
+                       ctx->config.parm.dec.cfg.ref_buf_margin);
                ctx->config.length = pbuf - ctx->config.buf;
+       } else {
+               ctx->config.parm.dec.cfg.double_write_mode = 16;
+               ctx->config.length = vdec_config_default_parms(ctx->config.buf);
        }
 
-       inst->vdec.config = ctx->config;
-
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_COMMON;
+       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_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
@@ -310,26 +305,30 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
        /* init vfm */
        inst->vfm.ctx           = ctx;
        inst->vfm.ada_ctx       = &inst->vdec;
-       vcodec_vfm_init(&inst->vfm);
+       ret = vcodec_vfm_init(&inst->vfm);
+       if (ret) {
+               pr_err("%s, init vfm failed.\n", __func__);
+               goto err;
+       }
 
        ret = video_decoder_init(&inst->vdec);
        if (ret) {
                aml_vcodec_err(inst, "vdec_h264 init err=%d", ret);
-               goto error_free_inst;
+               goto err;
        }
 
        /* probe info from the stream */
        inst->vsi = kzalloc(sizeof(struct vdec_h264_vsi), GFP_KERNEL);
        if (!inst->vsi) {
                ret = -ENOMEM;
-               goto error_free_inst;
+               goto err;
        }
 
        /* alloc the header buffer to be used cache sps or spp etc.*/
        inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
        if (!inst->vsi) {
                ret = -ENOMEM;
-               goto error_free_vsi;
+               goto err;
        }
 
        init_completion(&inst->comp);
@@ -342,11 +341,15 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
        //dump_init();
 
        return 0;
-
-error_free_vsi:
-       kfree(inst->vsi);
-error_free_inst:
-       kfree(inst);
+err:
+       if (inst)
+               vcodec_vfm_release(&inst->vfm);
+       if (inst && inst->vsi && inst->vsi->header_buf)
+               kfree(inst->vsi->header_buf);
+       if (inst && inst->vsi)
+               kfree(inst->vsi);
+       if (inst)
+               kfree(inst);
        *h_vdec = 0;
 
        return ret;
@@ -446,8 +449,8 @@ static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps
        struct vdec_pic_info *pic = &inst->vsi->pic;
        struct vdec_h264_dec_info *dec = &inst->vsi->dec;
        struct v4l2_rect *rect = &inst->vsi->crop;
-       int dw = inst->parms.double_write_mode;
-       int margin = inst->parms.buffer_margin;
+       int dw = inst->parms.cfg.double_write_mode;
+       int margin = inst->parms.cfg.ref_buf_margin;
        u32 mb_w, mb_h, width, height;
 
        mb_w = sps->mb_width;
@@ -474,20 +477,29 @@ static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps
        pic->coded_height       = ALIGN(mb_h, 4) << 4;
        pic->y_len_sz           = pic->coded_width * pic->coded_height;
        pic->c_len_sz           = pic->y_len_sz >> 1;
+       pic->profile_idc        = sps->profile_idc;
 
        /* calc DPB size */
-       dec->dpb_sz = sps->num_reorder_frames + 1 + margin;
+       dec->dpb_sz             = sps->num_reorder_frames + margin;
+
+       inst->parms.ps.visible_width    = pic->visible_width;
+       inst->parms.ps.visible_height   = pic->visible_height;
+       inst->parms.ps.coded_width      = pic->coded_width;
+       inst->parms.ps.coded_height     = pic->coded_height;
+       inst->parms.ps.profile          = sps->profile_idc;
+       inst->parms.ps.mb_width         = sps->mb_width;
+       inst->parms.ps.mb_height        = sps->mb_height;
+       inst->parms.ps.ref_frames       = sps->ref_frame_count;
+       inst->parms.ps.reorder_frames   = sps->num_reorder_frames;
+       inst->parms.ps.dpb_size         = dec->dpb_sz;
+       inst->parms.parms_status        |= V4L2_CONFIG_PARM_DECODE_PSINFO;
 
        vdec_config_dw_mode(pic, dw);
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_PICINFO;
-
        aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
-               inst->ctx->id,inst->parms.double_write_mode,
-               pic->coded_width, pic->coded_height,
+               inst->ctx->id, dw, pic->coded_width, pic->coded_height,
                pic->visible_width, pic->visible_height,
-               dec->dpb_sz - margin + 1, margin);
+               dec->dpb_sz - margin, margin);
 }
 
 static bool check_frame_combine(u8 *buf, u32 size, int *pos)
@@ -778,10 +790,13 @@ static bool monitor_res_change(struct vdec_h264_inst *inst, u8 *buf, u32 size)
 
                        if (type == NAL_H264_SPS) {
                                ret = stream_parse(inst, p, len);
-                               if (!ret && (inst->vsi->cur_pic.coded_width !=
+                               if (!ret && ((inst->vsi->cur_pic.coded_width !=
                                        inst->vsi->pic.coded_width ||
                                        inst->vsi->cur_pic.coded_height !=
-                                       inst->vsi->pic.coded_height)) {
+                                       inst->vsi->pic.coded_height) ||
+                                       (inst->vsi->pic.profile_idc !=
+                                       inst->vsi->cur_pic.profile_idc))) {
+                                       pr_info("res change\n");
                                        inst->vsi->cur_pic = inst->vsi->pic;
                                        return true;
                                }
@@ -834,9 +849,18 @@ static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
 static void get_param_config_info(struct vdec_h264_inst *inst,
        struct aml_dec_params *parms)
 {
-       *parms = inst->parms;
+       if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+               parms->cfg = inst->parms.cfg;
+       if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+               parms->ps = inst->parms.ps;
+       if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+               parms->hdr = inst->parms.hdr;
+       if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+               parms->cnt = inst->parms.cnt;
+
+       parms->parms_status |= inst->parms.parms_status;
 
-       aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
+       aml_vcodec_debug(inst, "parms status: %u", parms->parms_status);
 }
 
 static int vdec_h264_get_param(unsigned long h_vdec,
@@ -887,16 +911,16 @@ static void set_param_write_sync(struct vdec_h264_inst *inst)
        complete(&inst->comp);
 }
 
-static void set_param_pic_info(struct vdec_h264_inst *inst,
-       struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_h264_inst *inst,
+       struct aml_vdec_ps_infos *ps)
 {
        struct vdec_pic_info *pic = &inst->vsi->pic;
        struct vdec_h264_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      = info->visible_width;
-       pic->visible_height     = info->visible_height;
+       pic->visible_width      = ps->visible_width;
+       pic->visible_height     = ps->visible_height;
 
        /* calc visible ares. */
        rect->left              = 0;
@@ -905,33 +929,45 @@ static void set_param_pic_info(struct vdec_h264_inst *inst,
        rect->height            = pic->visible_height;
 
        /* config canvas size that be used for decoder. */
-       pic->coded_width        = info->coded_width;
-       pic->coded_height       = info->coded_height;
+       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 = info->dpb_size;
+       dec->dpb_sz             = ps->dpb_size;
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_PICINFO;
+       inst->parms.ps  = *ps;
+       inst->parms.parms_status |=
+               V4L2_CONFIG_PARM_DECODE_PSINFO;
 
        /*wake up*/
        complete(&inst->comp);
 
        pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
-               info->visible_width, info->visible_height,
-               info->coded_width, info->coded_height,
-               info->dpb_size);
+               ps->visible_width, ps->visible_height,
+               ps->coded_width, ps->coded_height,
+               dec->dpb_sz);
 }
 
 static void set_param_hdr_info(struct vdec_h264_inst *inst,
        struct aml_vdec_hdr_infos *hdr)
 {
        inst->parms.hdr = *hdr;
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_HDRINFO;
+       if (!(inst->parms.parms_status &
+               V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+               inst->parms.hdr = *hdr;
+               inst->parms.parms_status |=
+                       V4L2_CONFIG_PARM_DECODE_HDRINFO;
+               aml_vdec_dispatch_event(inst->ctx,
+                       V4L2_EVENT_SRC_CH_HDRINFO);
+               pr_info("H264 set HDR infos\n");
+       }
+}
 
-       //pr_info("H264 set HDR infos\n");
+static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event)
+{
+       aml_vdec_dispatch_event(inst->ctx, *event);
+       pr_info("H264 post event: %d\n", *event);
 }
 
 static int vdec_h264_set_param(unsigned long h_vdec,
@@ -950,13 +986,17 @@ static int vdec_h264_set_param(unsigned long h_vdec,
                set_param_write_sync(inst);
                break;
 
-       case SET_PARAM_PIC_INFO:
-               set_param_pic_info(inst, in);
+       case SET_PARAM_PS_INFO:
+               set_param_ps_info(inst, in);
                break;
 
        case SET_PARAM_HDR_INFO:
                set_param_hdr_info(inst, in);
                break;
+
+       case SET_PARAM_POST_EVENT:
+               set_param_post_event(inst, in);
+               break;
        default:
                aml_vcodec_err(inst, "invalid set parameter type=%d", type);
                ret = -EINVAL;
index fb3fce776c79e211d0456bd42c49ac7d5bca1c07..1b06d776848f92dbeadb639d467b5f177ec3f614 100644 (file)
@@ -164,35 +164,27 @@ static void vdec_parser_parms(struct vdec_hevc_inst *inst)
 {
        struct aml_vcodec_ctx *ctx = inst->ctx;
 
-       if (!ctx->config.length) {
-               ctx->config.type = V4L2_CONFIG_PARM_DECODE;
-               ctx->config.parm.dec.double_write_mode = 16;
-               inst->parms = ctx->config.parm.dec;
-
-               ctx->config.length =
-                       vdec_config_default_parms(ctx->config.buf);
-       } else {
+       if (ctx->config.parm.dec.parms_status &
+               V4L2_CONFIG_PARM_DECODE_CFGINFO) {
                u8 *pbuf = ctx->config.buf;
 
-               inst->parms = ctx->config.parm.dec;
                pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
                pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
-                       inst->parms.buffer_margin);
+                       ctx->config.parm.dec.cfg.ref_buf_margin);
                pbuf += sprintf(pbuf, "hevc_double_write_mode:%d;",
-                       inst->parms.double_write_mode);
-               pbuf += sprintf(pbuf, "hevc_buf_width:%d;",
-                       inst->parms.buffer_width);
-               pbuf += sprintf(pbuf, "hevc_buf_height:%d;",
-                       inst->parms.buffer_height);
-               pbuf += sprintf(pbuf, "save_buffer_mode:%d;",
-                       inst->parms.buffer_mode);
+                       ctx->config.parm.dec.cfg.double_write_mode);
+               pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
+               pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
+               pbuf += sprintf(pbuf, "save_buffer_mode:0;");
                ctx->config.length = pbuf - ctx->config.buf;
+       } else {
+               ctx->config.parm.dec.cfg.double_write_mode = 16;
+               ctx->config.length = vdec_config_default_parms(ctx->config.buf);
        }
 
-       inst->vdec.config = ctx->config;
-
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_COMMON;
+       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_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
@@ -222,26 +214,30 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
        /* init vfm */
        inst->vfm.ctx           = ctx;
        inst->vfm.ada_ctx       = &inst->vdec;
-       vcodec_vfm_init(&inst->vfm);
+       ret = vcodec_vfm_init(&inst->vfm);
+       if (ret) {
+               pr_err("%s, init vfm failed.\n", __func__);
+               goto err;
+       }
 
        ret = video_decoder_init(&inst->vdec);
        if (ret) {
                aml_vcodec_err(inst, "vdec_hevc init err=%d", ret);
-               goto error_free_inst;
+               goto err;
        }
 
        /* probe info from the stream */
        inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL);
        if (!inst->vsi) {
                ret = -ENOMEM;
-               goto error_free_inst;
+               goto err;
        }
 
        /* alloc the header buffer to be used cache sps or spp etc.*/
        inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
        if (!inst->vsi) {
                ret = -ENOMEM;
-               goto error_free_vsi;
+               goto err;
        }
 
        init_completion(&inst->comp);
@@ -254,11 +250,15 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
        //dump_init();
 
        return 0;
-
-error_free_vsi:
-       kfree(inst->vsi);
-error_free_inst:
-       kfree(inst);
+err:
+       if (inst)
+               vcodec_vfm_release(&inst->vfm);
+       if (inst && inst->vsi && inst->vsi->header_buf)
+               kfree(inst->vsi->header_buf);
+       if (inst && inst->vsi)
+               kfree(inst->vsi);
+       if (inst)
+               kfree(inst);
        *h_vdec = 0;
 
        return ret;
@@ -297,9 +297,9 @@ static int refer_buffer_num(struct h265_SPS_t *sps)
 
 static int vdec_get_dw_mode(struct vdec_hevc_inst *inst, int dw_mode)
 {
-       u32 valid_dw_mode = inst->parms.double_write_mode;
-       int w = inst->parms.buffer_width;
-       int h = inst->parms.buffer_height;
+       u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
+       int w = inst->parms.cfg.init_width;
+       int h = inst->parms.cfg.init_height;
        u32 dw = 0x1; /*1:1*/
 
        switch (valid_dw_mode) {
@@ -355,8 +355,8 @@ static void fill_vdec_params(struct vdec_hevc_inst *inst, struct h265_SPS_t *sps
        struct vdec_pic_info *pic = &inst->vsi->pic;
        struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
        struct v4l2_rect *rect = &inst->vsi->crop;
-       int dw = inst->parms.double_write_mode;
-       int margin = inst->parms.buffer_margin;
+       int dw = inst->parms.cfg.double_write_mode;
+       int margin = inst->parms.cfg.ref_buf_margin;
 
        /* fill visible area size that be used for EGL. */
        pic->visible_width = sps->width - (sps->output_window.left_offset +
@@ -380,14 +380,17 @@ static void fill_vdec_params(struct vdec_hevc_inst *inst, struct h265_SPS_t *sps
        pic->c_len_sz           = pic->y_len_sz >> 1;
 
        /* calc DPB size */
-       dec->dpb_sz = refer_buffer_num(sps) + margin;
+       dec->dpb_sz             = refer_buffer_num(sps) + margin;
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_PICINFO;
+       inst->parms.ps.visible_width    = pic->visible_width;
+       inst->parms.ps.visible_height   = pic->visible_height;
+       inst->parms.ps.coded_width      = pic->coded_width;
+       inst->parms.ps.coded_height     = pic->coded_height;
+       inst->parms.ps.dpb_size         = dec->dpb_sz;
+       inst->parms.parms_status        |= V4L2_CONFIG_PARM_DECODE_PSINFO;
 
        pr_info("[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
-               inst->ctx->id, inst->parms.double_write_mode,
-               pic->coded_width, pic->coded_height,
+               inst->ctx->id, dw, pic->coded_width, pic->coded_height,
                pic->visible_width, pic->visible_height,
                dec->dpb_sz - margin, margin);
 }
@@ -615,9 +618,18 @@ static int vdec_hevc_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
  static void get_param_config_info(struct vdec_hevc_inst *inst,
        struct aml_dec_params *parms)
  {
-       *parms = inst->parms;
-
-       aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+                parms->cfg = inst->parms.cfg;
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+                parms->ps = inst->parms.ps;
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+                parms->hdr = inst->parms.hdr;
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+                parms->cnt = inst->parms.cnt;
+
+        parms->parms_status |= inst->parms.parms_status;
+
+        aml_vcodec_debug(inst, "parms status: %u", parms->parms_status);
  }
 
 static int vdec_hevc_get_param(unsigned long h_vdec,
@@ -668,16 +680,16 @@ static void set_param_write_sync(struct vdec_hevc_inst *inst)
        complete(&inst->comp);
 }
 
-static void set_param_pic_info(struct vdec_hevc_inst *inst,
-       struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_hevc_inst *inst,
+       struct aml_vdec_ps_infos *ps)
 {
        struct vdec_pic_info *pic = &inst->vsi->pic;
        struct vdec_hevc_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      = info->visible_width;
-       pic->visible_height     = info->visible_height;
+       pic->visible_width      = ps->visible_width;
+       pic->visible_height     = ps->visible_height;
 
        /* calc visible ares. */
        rect->left              = 0;
@@ -686,15 +698,16 @@ static void set_param_pic_info(struct vdec_hevc_inst *inst,
        rect->height            = pic->visible_height;
 
        /* config canvas size that be used for decoder. */
-       pic->coded_width        = ALIGN(info->coded_width, 64);
-       pic->coded_height       = ALIGN(info->coded_height, 64);
+       pic->coded_width        = ALIGN(ps->coded_width, 64);
+       pic->coded_height       = ALIGN(ps->coded_height, 64);
        pic->y_len_sz           = pic->coded_width * pic->coded_height;
        pic->c_len_sz           = pic->y_len_sz >> 1;
 
-       dec->dpb_sz = info->dpb_size;
+       dec->dpb_sz             = ps->dpb_size;
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_PICINFO;
+       inst->parms.ps          = *ps;
+       inst->parms.parms_status |=
+               V4L2_CONFIG_PARM_DECODE_PSINFO;
 
        /*wake up*/
        complete(&inst->comp);
@@ -708,11 +721,21 @@ static void set_param_pic_info(struct vdec_hevc_inst *inst,
 static void set_param_hdr_info(struct vdec_hevc_inst *inst,
        struct aml_vdec_hdr_infos *hdr)
 {
-       inst->parms.hdr = *hdr;
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_HDRINFO;
+       if (!(inst->parms.parms_status &
+               V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+               inst->parms.hdr = *hdr;
+               inst->parms.parms_status |=
+                       V4L2_CONFIG_PARM_DECODE_HDRINFO;
+               aml_vdec_dispatch_event(inst->ctx,
+                       V4L2_EVENT_SRC_CH_HDRINFO);
+               pr_info("H265 set HDR infos\n");
+       }
+}
 
-       //pr_info("H265 set HDR infos\n");
+static void set_param_post_event(struct vdec_hevc_inst *inst, u32 *event)
+{
+       aml_vdec_dispatch_event(inst->ctx, *event);
+       pr_info("H265 post event: %d\n", *event);
 }
 
 static int vdec_hevc_set_param(unsigned long h_vdec,
@@ -731,13 +754,17 @@ static int vdec_hevc_set_param(unsigned long h_vdec,
                set_param_write_sync(inst);
                break;
 
-       case SET_PARAM_PIC_INFO:
-               set_param_pic_info(inst, in);
+       case SET_PARAM_PS_INFO:
+               set_param_ps_info(inst, in);
                break;
 
        case SET_PARAM_HDR_INFO:
                set_param_hdr_info(inst, in);
                break;
+
+       case SET_PARAM_POST_EVENT:
+               set_param_post_event(inst, in);
+               break;
        default:
                aml_vcodec_err(inst, "invalid set parameter type=%d", type);
                ret = -EINVAL;
index 09bfd5eee96ad0d7cdb1e422e330d2e8fa2275b9..0db4eca5c80d9d68c9bbffd6f4c2f07a445db64b 100644 (file)
@@ -451,8 +451,8 @@ static int vdec_mjpeg_get_param(unsigned long h_vdec,
        return ret;
 }
 
-static void set_param_pic_info(struct vdec_mjpeg_inst *inst,
-       struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_mjpeg_inst *inst,
+       struct aml_vdec_ps_infos *ps)
 {
        pr_info("---%s, %d\n", __func__, __LINE__);
 }
@@ -469,8 +469,8 @@ static int vdec_mjpeg_set_param(unsigned long h_vdec,
        }
 
        switch (type) {
-       case SET_PARAM_PIC_INFO:
-               set_param_pic_info(inst, in);
+       case SET_PARAM_PS_INFO:
+               set_param_ps_info(inst, in);
                break;
 
        default:
index cf69aa956c23ae346833f3237f8ae2dc11c563a4..5d5ca07bd433ac03c7ca8b42255b13ce8f8a586a 100644 (file)
@@ -443,8 +443,8 @@ static int vdec_mpeg12_get_param(unsigned long h_vdec,
        return ret;
 }
 
-static void set_param_pic_info(struct vdec_mpeg12_inst *inst,
-       struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_mpeg12_inst *inst,
+       struct aml_vdec_ps_infos *ps)
 {
        pr_info("---%s, %d\n", __func__, __LINE__);
 }
@@ -461,8 +461,8 @@ static int vdec_mpeg12_set_param(unsigned long h_vdec,
        }
 
        switch (type) {
-       case SET_PARAM_PIC_INFO:
-               set_param_pic_info(inst, in);
+       case SET_PARAM_PS_INFO:
+               set_param_ps_info(inst, in);
                break;
 
        default:
index a78c90495236159cf489fc26bffb4dbd0f3bb8af..ab428afe97680d7fbc1e171454f249724dc762e4 100644 (file)
@@ -452,8 +452,8 @@ static int vdec_mpeg4_get_param(unsigned long h_vdec,
        return ret;
 }
 
-static void set_param_pic_info(struct vdec_mpeg4_inst *inst,
-       struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_mpeg4_inst *inst,
+       struct aml_vdec_ps_infos *ps)
 {
        pr_info("---%s, %d\n", __func__, __LINE__);
 }
@@ -470,8 +470,8 @@ static int vdec_mpeg4_set_param(unsigned long h_vdec,
        }
 
        switch (type) {
-       case SET_PARAM_PIC_INFO:
-               set_param_pic_info(inst, in);
+       case SET_PARAM_PS_INFO:
+               set_param_ps_info(inst, in);
                break;
 
        default:
index 6aa8bd876013c8258017c24b4411416dec3cab27..54a6e1726ac4c9d5b8471c883bb9948365ea37bd 100644 (file)
@@ -178,66 +178,64 @@ static void vdec_parser_parms(struct vdec_vp9_inst *inst)
 {
        struct aml_vcodec_ctx *ctx = inst->ctx;
 
-       if (!ctx->config.length) {
-               ctx->config.type = V4L2_CONFIG_PARM_DECODE;
-               ctx->config.parm.dec.double_write_mode = 16;
-               inst->parms = ctx->config.parm.dec;
-
-               ctx->config.length =
-                       vdec_config_default_parms(ctx->config.buf);
-       } else {
+       if (ctx->config.parm.dec.parms_status &
+               V4L2_CONFIG_PARM_DECODE_CFGINFO) {
                u8 *pbuf = ctx->config.buf;
 
-               inst->parms = ctx->config.parm.dec;
                pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
                pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
-                       inst->parms.buffer_margin);
+                       ctx->config.parm.dec.cfg.ref_buf_margin);
                pbuf += sprintf(pbuf, "vp9_double_write_mode:%d;",
-                       inst->parms.double_write_mode);
+                       ctx->config.parm.dec.cfg.double_write_mode);
                pbuf += sprintf(pbuf, "vp9_buf_width:%d;",
-                       inst->parms.buffer_width);
+                       ctx->config.parm.dec.cfg.init_width);
                pbuf += sprintf(pbuf, "vp9_buf_height:%d;",
-                       inst->parms.buffer_height);
-               pbuf += sprintf(pbuf, "save_buffer_mode:%d;",
-                       inst->parms.buffer_mode);
+                       ctx->config.parm.dec.cfg.init_height);
+               pbuf += sprintf(pbuf, "save_buffer_mode:0;");
                pbuf += sprintf(pbuf, "no_head:0;");
-
-               if ((ctx->config.parm.dec.dec_parms_status &
-                       V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
-                       inst->parms.hdr.color_parms.present_flag) {
-                       pbuf += sprintf(pbuf, "mG.x:%d;",
-                               inst->parms.hdr.color_parms.primaries[0][0]);
-                       pbuf += sprintf(pbuf, "mG.y:%d;",
-                               inst->parms.hdr.color_parms.primaries[0][1]);
-                       pbuf += sprintf(pbuf, "mB.x:%d;",
-                               inst->parms.hdr.color_parms.primaries[1][0]);
-                       pbuf += sprintf(pbuf, "mB.y:%d;",
-                               inst->parms.hdr.color_parms.primaries[1][1]);
-                       pbuf += sprintf(pbuf, "mR.x:%d;",
-                               inst->parms.hdr.color_parms.primaries[2][0]);
-                       pbuf += sprintf(pbuf, "mR.y:%d;",
-                               inst->parms.hdr.color_parms.primaries[2][1]);
-                       pbuf += sprintf(pbuf, "mW.x:%d;",
-                               inst->parms.hdr.color_parms.white_point[0]);
-                       pbuf += sprintf(pbuf, "mW.y:%d;",
-                               inst->parms.hdr.color_parms.white_point[1]);
-                       pbuf += sprintf(pbuf, "mMaxDL:%d;",
-                               inst->parms.hdr.color_parms.luminance[0] / 1000);
-                       pbuf += sprintf(pbuf, "mMinDL:%d;",
-                               inst->parms.hdr.color_parms.luminance[1]);
-                       pbuf += sprintf(pbuf, "mMaxCLL:%d;",
-                               inst->parms.hdr.color_parms.content_light_level.max_content);
-                       pbuf += sprintf(pbuf, "mMaxFALL:%d;",
-                               inst->parms.hdr.color_parms.content_light_level.max_pic_average);
-               }
-
                ctx->config.length = pbuf - ctx->config.buf;
+       } else {
+               ctx->config.parm.dec.cfg.double_write_mode = 16;
+               ctx->config.length = vdec_config_default_parms(ctx->config.buf);
        }
 
-       inst->vdec.config = ctx->config;
+       if ((ctx->config.parm.dec.parms_status &
+               V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
+               inst->parms.hdr.color_parms.present_flag) {
+               u8 *pbuf = ctx->config.buf + ctx->config.length;
+
+               pbuf += sprintf(pbuf, "mG.x:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
+               pbuf += sprintf(pbuf, "mG.y:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+               pbuf += sprintf(pbuf, "mB.x:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+               pbuf += sprintf(pbuf, "mB.y:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+               pbuf += sprintf(pbuf, "mR.x:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+               pbuf += sprintf(pbuf, "mR.y:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+               pbuf += sprintf(pbuf, "mW.x:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+               pbuf += sprintf(pbuf, "mW.y:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+               pbuf += sprintf(pbuf, "mMaxDL:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.luminance[0] / 1000);
+               pbuf += sprintf(pbuf, "mMinDL:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+               pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+               pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+                       ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+               ctx->config.length      = pbuf - ctx->config.buf;
+               inst->parms.hdr         = ctx->config.parm.dec.hdr;
+               inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+       }
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_COMMON;
+       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_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
@@ -267,20 +265,24 @@ static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
        /* init vfm */
        inst->vfm.ctx           = ctx;
        inst->vfm.ada_ctx       = &inst->vdec;
-       vcodec_vfm_init(&inst->vfm);
+       ret = vcodec_vfm_init(&inst->vfm);
+       if (ret) {
+               pr_err("%s, init vfm failed.\n", __func__);
+               goto err;
+       }
 
        /* probe info from the stream */
        inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
        if (!inst->vsi) {
                ret = -ENOMEM;
-               goto error_free_inst;
+               goto err;
        }
 
        /* alloc the header buffer to be used cache sps or spp etc.*/
        inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
        if (!inst->vsi) {
                ret = -ENOMEM;
-               goto error_free_vsi;
+               goto err;
        }
 
        init_completion(&inst->comp);
@@ -294,17 +296,21 @@ static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
        ret = video_decoder_init(&inst->vdec);
        if (ret) {
                aml_vcodec_err(inst, "vdec_vp9 init err=%d", ret);
-               goto error_free_inst;
+               goto err;
        }
 
        //dump_init();
 
        return 0;
-
-error_free_vsi:
-       kfree(inst->vsi);
-error_free_inst:
-       kfree(inst);
+err:
+       if (inst)
+               vcodec_vfm_release(&inst->vfm);
+       if (inst && inst->vsi && inst->vsi->header_buf)
+               kfree(inst->vsi->header_buf);
+       if (inst && inst->vsi)
+               kfree(inst->vsi);
+       if (inst)
+               kfree(inst);
        *h_vdec = 0;
 
        return ret;
@@ -320,9 +326,9 @@ static int refer_buffer_num(int level_idc, int poc_cnt,
 
 static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
 {
-       u32 valid_dw_mode = inst->parms.double_write_mode;
-       int w = inst->parms.buffer_width;
-       int h = inst->parms.buffer_height;
+       u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
+       int w = inst->parms.cfg.init_width;
+       int h = inst->parms.cfg.init_height;
        u32 dw = 0x1; /*1:1*/
 
        switch (valid_dw_mode) {
@@ -379,8 +385,8 @@ static void fill_vdec_params(struct vdec_vp9_inst *inst,
        struct vdec_pic_info *pic = &inst->vsi->pic;
        struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
        struct v4l2_rect *rect = &inst->vsi->crop;
-       int dw = inst->parms.double_write_mode;
-       int margin = inst->parms.buffer_margin;
+       int dw = inst->parms.cfg.double_write_mode;
+       int margin = inst->parms.cfg.ref_buf_margin;
 
        /* fill visible area size that be used for EGL. */
        pic->visible_width      = vdec_pic_scale(inst, vp9_ctx->render_width, dw);
@@ -402,12 +408,15 @@ static void fill_vdec_params(struct vdec_vp9_inst *inst,
        /* calc DPB size */
        dec->dpb_sz = 5 + margin;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_PICINFO;
+       inst->parms.ps.visible_width    = pic->visible_width;
+       inst->parms.ps.visible_height   = pic->visible_height;
+       inst->parms.ps.coded_width      = pic->coded_width;
+       inst->parms.ps.coded_height     = pic->coded_height;
+       inst->parms.ps.dpb_size         = dec->dpb_sz;
+       inst->parms.parms_status        |= V4L2_CONFIG_PARM_DECODE_PSINFO;
 
        aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
-               inst->ctx->id, inst->parms.double_write_mode,
-               pic->coded_width, pic->coded_height,
+               inst->ctx->id, dw, pic->coded_width, pic->coded_height,
                pic->visible_width, pic->visible_height,
                dec->dpb_sz - margin, margin);
 }
@@ -719,9 +728,18 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
  static void get_param_config_info(struct vdec_vp9_inst *inst,
        struct aml_dec_params *parms)
  {
-       *parms = inst->parms;
-
-       aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+                parms->cfg = inst->parms.cfg;
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+                parms->ps = inst->parms.ps;
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+                parms->hdr = inst->parms.hdr;
+        if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+                parms->cnt = inst->parms.cnt;
+
+        parms->parms_status |= inst->parms.parms_status;
+
+        aml_vcodec_debug(inst, "parms status: %u", parms->parms_status);
  }
 
 static int vdec_vp9_get_param(unsigned long h_vdec,
@@ -772,16 +790,16 @@ static void set_param_write_sync(struct vdec_vp9_inst *inst)
        complete(&inst->comp);
 }
 
-static void set_param_pic_info(struct vdec_vp9_inst *inst,
-       struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_vp9_inst *inst,
+       struct aml_vdec_ps_infos *ps)
 {
        struct vdec_pic_info *pic = &inst->vsi->pic;
        struct vdec_vp9_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      = info->visible_width;
-       pic->visible_height     = info->visible_height;
+       pic->visible_width      = ps->visible_width;
+       pic->visible_height     = ps->visible_height;
 
        /* calc visible ares. */
        rect->left              = 0;
@@ -790,35 +808,46 @@ static void set_param_pic_info(struct vdec_vp9_inst *inst,
        rect->height            = pic->visible_height;
 
        /* config canvas size that be used for decoder. */
-       pic->coded_width        = info->coded_width;
-       pic->coded_height       = info->coded_height;
+       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;
 
        /* calc DPB size */
-       dec->dpb_sz = 5;
+       dec->dpb_sz             = 5;
 
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_PICINFO;
+       inst->parms.ps  = *ps;
+       inst->parms.parms_status |=
+               V4L2_CONFIG_PARM_DECODE_PSINFO;
 
        /*wake up*/
        complete(&inst->comp);
 
        pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
-               info->visible_width, info->visible_height,
-               info->coded_width, info->coded_height,
-               info->dpb_size);
+               ps->visible_width, ps->visible_height,
+               ps->coded_width, ps->coded_height,
+               ps->dpb_size);
 }
 
 static void set_param_hdr_info(struct vdec_vp9_inst *inst,
        struct aml_vdec_hdr_infos *hdr)
 {
-       inst->parms.hdr = *hdr;
-       inst->parms.dec_parms_status |=
-               V4L2_CONFIG_PARM_DECODE_HDRINFO;
+       if ((inst->parms.parms_status &
+               V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+               inst->parms.hdr = *hdr;
+               inst->parms.parms_status |=
+                       V4L2_CONFIG_PARM_DECODE_HDRINFO;
+               aml_vdec_dispatch_event(inst->ctx,
+                       V4L2_EVENT_SRC_CH_HDRINFO);
+               pr_info("VP9 set HDR infos\n");
+       }
+}
 
-       //pr_info("VP9 set HDR infos\n");
+static void set_param_post_event(struct vdec_vp9_inst *inst, u32 *event)
+{
+               aml_vdec_dispatch_event(inst->ctx, *event);
+               pr_info("VP9 post event: %d\n", *event);
 }
 
 static int vdec_vp9_set_param(unsigned long h_vdec,
@@ -837,13 +866,17 @@ static int vdec_vp9_set_param(unsigned long h_vdec,
                set_param_write_sync(inst);
                break;
 
-       case SET_PARAM_PIC_INFO:
-               set_param_pic_info(inst, in);
+       case SET_PARAM_PS_INFO:
+               set_param_ps_info(inst, in);
                break;
 
        case SET_PARAM_HDR_INFO:
                set_param_hdr_info(inst, in);
                break;
+
+       case SET_PARAM_POST_EVENT:
+               set_param_post_event(inst, in);
+               break;
        default:
                aml_vcodec_err(inst, "invalid set parameter type=%d", type);
                ret = -EINVAL;
index 8b029fece3570c53a09721f461cbc600d70f6bd7..d3ccef21fa72182c47105fb000ed8852e7fe8d12 100644 (file)
@@ -73,12 +73,13 @@ enum vdec_get_param_type {
 };
 
 /*
- * SET_PARAM_PIC_INFO         : set picture info, data parsed from ucode.
+ * SET_PARAM_PS_INFO          : set picture parms, data parsed from ucode.
  */
 enum vdec_set_param_type {
        SET_PARAM_WRITE_FRAME_SYNC,
-       SET_PARAM_PIC_INFO,
-       SET_PARAM_HDR_INFO
+       SET_PARAM_PS_INFO,
+       SET_PARAM_HDR_INFO,
+       SET_PARAM_POST_EVENT
 };
 
 /**
index 29c30157cef9d94f776d61d9099580e578cbe17e..38321bb4bd0272fd032fade0e54d90d773d4a1f9 100644 (file)
@@ -2748,18 +2748,12 @@ int notify_v4l_eos(struct vdec_s *vdec)
 {
        struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
        struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-       struct vframe_s *vf = NULL;
+       struct vframe_s *vf = &hw->vframe_dummy;
+       struct vdec_v4l2_buffer *fb = NULL;
        int index = INVALID_IDX;
        ulong expires;
 
        if (hw->is_used_v4l && hw->eos) {
-               if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
-                       dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
-                               "%s fatal error, no available buffer slot.\n",
-                               __func__);
-                       return -1;
-               }
-
                expires = jiffies + msecs_to_jiffies(2000);
                while (INVALID_IDX == (index = get_free_buf_idx(vdec))) {
                        if (time_after(jiffies, expires))
@@ -2767,14 +2761,17 @@ int notify_v4l_eos(struct vdec_s *vdec)
                }
 
                if (index == INVALID_IDX) {
-                       pr_err("[%d] EOS get free buff fail.\n", ctx->id);
-                       return -1;
+                       if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
+                               pr_err("[%d] EOS get free buff fail.\n", ctx->id);
+                               return -1;
+                       }
                }
 
                vf->type                |= VIDTYPE_V4L_EOS;
                vf->timestamp           = ULONG_MAX;
-               vf->v4l_mem_handle      = hw->buffer_spec[index].cma_alloc_addr;
                vf->flag                = VFRAME_FLAG_EMPTY_FRAME_V4L;
+               vf->v4l_mem_handle      = (index == INVALID_IDX) ? (ulong)fb :
+                                       hw->buffer_spec[index].cma_alloc_addr;
 
                kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
 
@@ -7836,15 +7833,15 @@ static void vh264_work_implement(struct vdec_h264_hw_s *hw,
                                (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
 
                        if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
-                               struct aml_vdec_pic_infos info;
+                               struct aml_vdec_ps_infos ps;
 
-                               info.visible_width      = hw->frame_width;
-                               info.visible_height     = hw->frame_height;
-                               info.coded_width        = ALIGN(hw->frame_width, 64);
-                               info.coded_height       = ALIGN(hw->frame_height, 64);
-                               info.dpb_size           = hw->dpb.mDPB.size;
+                               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->dpb.mDPB.size;
                                hw->v4l_params_parsed   = true;
-                               vdec_v4l_set_pic_infos(ctx, &info);
+                               vdec_v4l_set_ps_infos(ctx, &ps);
                        }
                }
 
@@ -8204,20 +8201,20 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
                        get_used_buf_count(hw) >=
                        run_ready_max_buf_num)
                        ret = 0;
-
-               if (hw->is_used_v4l) {
-                       struct aml_vcodec_ctx *ctx =
-                               (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
-                       if (ctx->param_sets_from_ucode &&
-                               !ctx->v4l_codec_ready &&
-                               hw->v4l_params_parsed) {
-                               ret = 0; /*the params has parsed.*/
-                       } else if (!ctx->v4l_codec_dpb_ready)
-                               ret = 0;
-               }
        }
 #endif
+       if (hw->is_used_v4l) {
+               struct aml_vcodec_ctx *ctx =
+                       (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
+
+               if (ctx->param_sets_from_ucode &&
+                       !ctx->v4l_codec_ready &&
+                       hw->v4l_params_parsed) {
+                       ret = 0; /*the params has parsed.*/
+               } else if (!ctx->v4l_codec_dpb_ready)
+                       ret = 0;
+       }
+
        if (ret)
                not_run_ready[DECODE_ID(hw)] = 0;
        else
index 86055bfedb8825454ef87231cf458b3c1e9a4207..9189564dabab8eb100d15279d29f1d01d99d527c 100644 (file)
@@ -8997,18 +8997,12 @@ static int notify_v4l_eos(struct vdec_s *vdec)
 {
        struct hevc_state_s *hw = (struct hevc_state_s *)vdec->private;
        struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-       struct vframe_s *vf = NULL;
+       struct vframe_s *vf = &hw->vframe_dummy;
+       struct vdec_v4l2_buffer *fb = NULL;
        int index = INVALID_IDX;
        ulong expires;
 
        if (hw->is_used_v4l && hw->eos) {
-               if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
-                       hevc_print(hw, 0,
-                               "%s fatal error, no available buffer slot.\n",
-                               __func__);
-                       return -1;
-               }
-
                expires = jiffies + msecs_to_jiffies(2000);
                while (INVALID_IDX == (index = get_free_buf_idx(hw))) {
                        if (time_after(jiffies, expires))
@@ -9016,15 +9010,17 @@ static int notify_v4l_eos(struct vdec_s *vdec)
                }
 
                if (index == INVALID_IDX) {
-                       pr_err("[%d] EOS get free buff fail.\n", ctx->id);
-                       return -1;
+                       if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
+                               pr_err("[%d] EOS get free buff fail.\n", ctx->id);
+                               return -1;
+                       }
                }
 
                vf->type                |= VIDTYPE_V4L_EOS;
                vf->timestamp           = ULONG_MAX;
-               vf->v4l_mem_handle      = hw->m_BUF[index].v4l_ref_buf_addr;
                vf->flag                = VFRAME_FLAG_EMPTY_FRAME_V4L;
-
+               vf->v4l_mem_handle      = (index == INVALID_IDX) ? (ulong)fb :
+                                       hw->m_BUF[index].v4l_ref_buf_addr;
                kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
                vf_notify_receiver(vdec->vf_provider_name,
                        VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
@@ -10042,18 +10038,18 @@ force_output:
                                        (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
 
                                if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) {
-                                       struct aml_vdec_pic_infos info;
+                                       struct aml_vdec_ps_infos ps;
 
                                        hevc->frame_width       = hevc->param.p.pic_width_in_luma_samples;
                                        hevc->frame_height      = hevc->param.p.pic_height_in_luma_samples;
-                                       info.visible_width      = hevc->frame_width;
-                                       info.visible_height     = hevc->frame_height;
-                                       info.coded_width        = ALIGN(hevc->frame_width, 32);
-                                       info.coded_height       = ALIGN(hevc->frame_height, 32);
-                                       info.dpb_size           = get_work_pic_num(hevc);
+                                       ps.visible_width        = hevc->frame_width;
+                                       ps.visible_height       = hevc->frame_height;
+                                       ps.coded_width          = ALIGN(hevc->frame_width, 32);
+                                       ps.coded_height         = ALIGN(hevc->frame_height, 32);
+                                       ps.dpb_size             = get_work_pic_num(hevc);
                                        hevc->v4l_params_parsed = true;
                                        /*notice the v4l2 codec.*/
-                                       vdec_v4l_set_pic_infos(ctx, &info);
+                                       vdec_v4l_set_ps_infos(ctx, &ps);
                                }
                        }
 
index 5ebb6befd1340102e551f0596ea52837252bd06e..1ac107ff57547700a73bd2b36099a89c1be6b8c5 100644 (file)
@@ -292,15 +292,15 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq)
                        (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
 
                if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
-                       struct aml_vdec_pic_infos info;
+                       struct aml_vdec_ps_infos ps;
 
-                       info.visible_width      = hw->frame_width;
-                       info.visible_height     = hw->frame_height;
-                       info.coded_width        = ALIGN(hw->frame_width, 64);
-                       info.coded_height       = ALIGN(hw->frame_height, 64);
-                       info.dpb_size           = MAX_BMMU_BUFFER_NUM - 1;
+                       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             = MAX_BMMU_BUFFER_NUM - 1;
                        hw->v4l_params_parsed   = true;
-                       vdec_v4l_set_pic_infos(ctx, &info);
+                       vdec_v4l_set_ps_infos(ctx, &ps);
                }
 
                if (!ctx->v4l_codec_ready)
index 7033fa6b423166899b46ed5582c357efd5a84f28..6095f6845cac3694c1ad108fd229abbdc01b0020 100644 (file)
@@ -1627,15 +1627,15 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq)
                                (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
 
                        if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
-                               struct aml_vdec_pic_infos info;
+                               struct aml_vdec_ps_infos ps;
 
-                               info.visible_width      = hw->frame_width;
-                               info.visible_height     = hw->frame_height;
-                               info.coded_width        = ALIGN(hw->frame_width, 64);
-                               info.coded_height       = ALIGN(hw->frame_height, 64);
-                               info.dpb_size           = MAX_BMMU_BUFFER_NUM - 1;
+                               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             = MAX_BMMU_BUFFER_NUM - 1;
                                hw->v4l_params_parsed   = true;
-                               vdec_v4l_set_pic_infos(ctx, &info);
+                               vdec_v4l_set_ps_infos(ctx, &ps);
                        }
 
                        if (!ctx->v4l_codec_ready)
index 50b10c6006c3dd0639f39e9273a9b010feb615b4..e552855bab28b0f55874d2572564e108b2572046 100644 (file)
@@ -950,15 +950,15 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq)
                                (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
 
                        if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
-                               struct aml_vdec_pic_infos info;
+                               struct aml_vdec_ps_infos ps;
 
-                               info.visible_width      = hw->frame_width;
-                               info.visible_height     = hw->frame_height;
-                               info.coded_width        = ALIGN(hw->frame_width, 64);
-                               info.coded_height       = ALIGN(hw->frame_height, 64);
-                               info.dpb_size           = MAX_BMMU_BUFFER_NUM - 1;
+                               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             = MAX_BMMU_BUFFER_NUM - 1;
                                hw->v4l_params_parsed   = true;
-                               vdec_v4l_set_pic_infos(ctx, &info);
+                               vdec_v4l_set_ps_infos(ctx, &ps);
                        }
 
                        if (!ctx->v4l_codec_ready)
index f712696f042a090a9206f82d8f4a9572dd7fb753..19be6247a3e704da419169fb6fb6896eb5e44831 100644 (file)
@@ -15,8 +15,8 @@ int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx,
 }
 EXPORT_SYMBOL(vdec_v4l_get_buffer);
 
-int vdec_v4l_set_pic_infos(struct aml_vcodec_ctx *ctx,
-       struct aml_vdec_pic_infos *info)
+int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx,
+       struct aml_vdec_ps_infos *ps)
 {
        int ret = 0;
 
@@ -24,11 +24,11 @@ int vdec_v4l_set_pic_infos(struct aml_vcodec_ctx *ctx,
                return -EIO;
 
        ret = ctx->dec_if->set_param(ctx->drv_handle,
-               SET_PARAM_PIC_INFO, info);
+               SET_PARAM_PS_INFO, ps);
 
        return ret;
 }
-EXPORT_SYMBOL(vdec_v4l_set_pic_infos);
+EXPORT_SYMBOL(vdec_v4l_set_ps_infos);
 
 int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx,
        struct aml_vdec_hdr_infos *hdr)
@@ -45,6 +45,20 @@ int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx,
 }
 EXPORT_SYMBOL(vdec_v4l_set_hdr_infos);
 
+int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event)
+{
+       int ret = 0;
+
+       if (ctx->drv_handle == 0)
+               return -EIO;
+
+       ret = ctx->dec_if->set_param(ctx->drv_handle,
+               SET_PARAM_POST_EVENT, &event);
+
+       return ret;
+}
+EXPORT_SYMBOL(vdec_v4l_post_evet);
+
 int vdec_v4l_write_frame_sync(struct aml_vcodec_ctx *ctx)
 {
        int ret = 0;
index b26cf51d4722a3c9e94c1c3a24b565e0821676fb..13f3543daada222c38aa029ea80518bd3aba217f 100644 (file)
@@ -8,9 +8,9 @@ int vdec_v4l_get_buffer(
        struct aml_vcodec_ctx *ctx,
        struct vdec_v4l2_buffer **out);
 
-int vdec_v4l_set_pic_infos(
+int vdec_v4l_set_ps_infos(
        struct aml_vcodec_ctx *ctx,
-       struct aml_vdec_pic_infos *info);
+       struct aml_vdec_ps_infos *ps);
 
 int vdec_v4l_set_hdr_infos(
        struct aml_vcodec_ctx *ctx,
@@ -19,4 +19,8 @@ int vdec_v4l_set_hdr_infos(
 int vdec_v4l_write_frame_sync(
        struct aml_vcodec_ctx *ctx);
 
+int vdec_v4l_post_evet(
+       struct aml_vcodec_ctx *ctx,
+       u32 event);
+
 #endif
index a59ee93af83e0a58495a72a08ea05d896010d6c0..3cafea2625b665005e1b13ba1f6ce7af764d24fc 100644 (file)
@@ -1189,6 +1189,7 @@ struct VP9Decoder_s {
        struct vframe_qos_s vframe_qos;
        u32 mem_map_mode;
        u32 dynamic_buf_num_margin;
+       struct vframe_s vframe_dummy;
 };
 
 static int vp9_print(struct VP9Decoder_s *pbi,
@@ -6816,6 +6817,9 @@ static void vvp9_vf_put(struct vframe_s *vf, void *op_arg)
        struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg;
        uint8_t index = vf->index & 0xff;
 
+       if (vf == (&pbi->vframe_dummy))
+               return;
+
        kfifo_put(&pbi->newframe_q, (const struct vframe_s *)vf);
        pbi->vf_put_count++;
        if (index < pbi->used_buf_num) {
@@ -7256,18 +7260,12 @@ static int notify_v4l_eos(struct vdec_s *vdec)
 {
        struct VP9Decoder_s *hw = (struct VP9Decoder_s *)vdec->private;
        struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-       struct vframe_s *vf = NULL;
+       struct vframe_s *vf = &hw->vframe_dummy;
+       struct vdec_v4l2_buffer *fb = NULL;
        int index = INVALID_IDX;
        ulong expires;
 
        if (hw->is_used_v4l && hw->eos) {
-               if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
-                       vp9_print(hw, 0,
-                               "%s fatal error, no available buffer slot.\n",
-                               __func__);
-                       return -1;
-               }
-
                expires = jiffies + msecs_to_jiffies(2000);
                while (INVALID_IDX == (index = get_free_fb(hw))) {
                        if (time_after(jiffies, expires))
@@ -7275,14 +7273,17 @@ static int notify_v4l_eos(struct vdec_s *vdec)
                }
 
                if (index == INVALID_IDX) {
-                       pr_err("[%d] EOS get free buff fail.\n", ctx->id);
-                       return -1;
+                       if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
+                               pr_err("[%d] EOS get free buff fail.\n", ctx->id);
+                               return -1;
+                       }
                }
 
                vf->type                |= VIDTYPE_V4L_EOS;
                vf->timestamp           = ULONG_MAX;
-               vf->v4l_mem_handle      = hw->m_BUF[index].v4l_ref_buf_addr;
                vf->flag                = VFRAME_FLAG_EMPTY_FRAME_V4L;
+               vf->v4l_mem_handle      = (index == INVALID_IDX) ? (ulong)fb :
+                                       hw->m_BUF[index].v4l_ref_buf_addr;
 
                kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
                vf_notify_receiver(vdec->vf_provider_name,
@@ -8297,15 +8298,15 @@ static irqreturn_t vvp9_isr_thread_fn(int irq, void *data)
                pbi->frame_width = vp9_param.p.width;
                pbi->frame_height = vp9_param.p.height;
                if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) {
-                       struct aml_vdec_pic_infos info;
+                       struct aml_vdec_ps_infos ps;
 
-                       info.visible_width      = pbi->frame_width;
-                       info.visible_height     = pbi->frame_height;
-                       info.coded_width        = ALIGN(pbi->frame_width, 32);
-                       info.coded_height       = ALIGN(pbi->frame_height, 32);
-                       info.dpb_size           = pbi->used_buf_num;
+                       ps.visible_width        = pbi->frame_width;
+                       ps.visible_height       = pbi->frame_height;
+                       ps.coded_width          = ALIGN(pbi->frame_width, 32);
+                       ps.coded_height         = ALIGN(pbi->frame_height, 32);
+                       ps.dpb_size             = pbi->used_buf_num;
                        pbi->v4l_params_parsed  = true;
-                       vdec_v4l_set_pic_infos(ctx, &info);
+                       vdec_v4l_set_ps_infos(ctx, &ps);
                }
        }