summaryrefslogtreecommitdiff
authorNanxin Qin <nanxin.qin@amlogic.com>2019-11-24 09:40:53 (GMT)
committer Zhi Zhou <zhi.zhou@amlogic.com>2019-11-27 16:02:59 (GMT)
commit8e9fb3123465caf8757d5ae2a3f670901a7de5d1 (patch)
treeb3e729f52bf31a29511a9001d45ac2adb126c2aa
parent6ecf0542c8fb767509ddbde1c2c5a90ce03629a1 (diff)
downloadmedia_modules-8e9fb3123465caf8757d5ae2a3f670901a7de5d1.zip
media_modules-8e9fb3123465caf8757d5ae2a3f670901a7de5d1.tar.gz
media_modules-8e9fb3123465caf8757d5ae2a3f670901a7de5d1.tar.bz2
v4l: fixed some issues for v4l codec. [1/1]
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>
Diffstat
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c2
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c100
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h10
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h68
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c11
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c23
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c148
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c143
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c8
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c8
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c8
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c207
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h7
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c57
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c34
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c14
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c14
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c14
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c22
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h8
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c37
22 files changed, 580 insertions, 364 deletions
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c
index a307a2b..7ac9ad5 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -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;
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index 7774522..f0a0d88 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -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;
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index c465857..7ca3337 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -39,15 +39,6 @@
#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_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index 21a1ab2..fb1930e 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -38,6 +38,26 @@
#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 {
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.c b/drivers/amvdec_ports/aml_vcodec_vfm.c
index e7b85fb..f5fdc7b 100644
--- a/drivers/amvdec_ports/aml_vcodec_vfm.c
+++ b/drivers/amvdec_ports/aml_vcodec_vfm.c
@@ -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);
}
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.h b/drivers/amvdec_ports/aml_vcodec_vfm.h
index 9aaf266..141e9a7 100644
--- a/drivers/amvdec_ports/aml_vcodec_vfm.h
+++ b/drivers/amvdec_ports/aml_vcodec_vfm.h
@@ -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);
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c
index d5d1d91..8963afd 100644
--- a/drivers/amvdec_ports/decoder/aml_h264_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.c
@@ -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;
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index 7bf4d5e..ea1d0f8 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -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;
diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
index fb3fce7..1b06d77 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -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;
diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
index 09bfd5e..0db4eca 100644
--- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -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:
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
index cf69aa9..5d5ca07 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
@@ -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:
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
index a78c904..ab428af 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
@@ -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:
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index 6aa8bd8..54a6e17 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -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;
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h
index 8b029fe..d3ccef2 100644
--- a/drivers/amvdec_ports/vdec_drv_if.h
+++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -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
};
/**
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
index 29c3015..38321bb 100644
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -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
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c
index 86055bf..9189564 100644
--- a/drivers/frame_provider/decoder/h265/vh265.c
+++ b/drivers/frame_provider/decoder/h265/vh265.c
@@ -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);
}
}
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
index 5ebb6be..1ac107f 100644
--- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
+++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
@@ -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)
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
index 7033fa6..6095f68 100644
--- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
+++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
@@ -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)
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
index 50b10c6..e552855 100644
--- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
+++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
@@ -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)
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 f712696..19be624 100644
--- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
+++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
@@ -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;
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 b26cf51..13f3543 100644
--- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
+++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
@@ -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
diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c
index a59ee93..3cafea2 100644
--- a/drivers/frame_provider/decoder/vp9/vvp9.c
+++ b/drivers/frame_provider/decoder/vp9/vvp9.c
@@ -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);
}
}