author | Peng Yixin <yixin.peng@amlogic.com> | 2020-03-18 07:35:45 (GMT) |
---|---|---|
committer | Yixin Peng <yixin.peng@amlogic.com> | 2020-03-30 08:22:27 (GMT) |
commit | ad9d8329172b01ceeb135c4cabd804c99223a49b (patch) | |
tree | 2f06cd3af62ff709ab4e27889364b728a46296fc | |
parent | 196b18397ef5ea8a40f235b2f6636106a5774581 (diff) | |
download | media_modules-ad9d8329172b01ceeb135c4cabd804c99223a49b.zip media_modules-ad9d8329172b01ceeb135c4cabd804c99223a49b.tar.gz media_modules-ad9d8329172b01ceeb135c4cabd804c99223a49b.tar.bz2 |
v4l: Resolve resolutions change at the end of a file [1/1]
PD#SWPL-23321
Problem:
Resolutions change at the end of a file, it cause playback stuck or
exit playback.
Solution:
Add eos events to distinguish between resolution change event.
Verify:
u212
Change-Id: Iec972284d7a0f3ad6cfac6375efa16e1b5c7b87e
Signed-off-by: Peng Yixin <yixin.peng@amlogic.com>
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_adapt.c | 4 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_dec.c | 48 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_dec_drv.c | 1 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_drv.h | 5 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/vmh264.c | 11 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c | 3 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c | 3 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c | 3 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c | 10 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/vp9/vvp9.c | 19 |
10 files changed, 34 insertions, 73 deletions
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c index d179a3a..ab50642 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.c +++ b/drivers/amvdec_ports/aml_vcodec_adapt.c @@ -729,8 +729,8 @@ int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *mode) int ret = 0; if (vdec) { - vdec_set_eos(vdec, false); - + if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed) + vdec_set_eos(vdec, false); if (*mode == V4L_RESET_MODE_NORMAL && vdec->input.have_frame_num == 0) { v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index 99ce5d2..cd6acf8 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c @@ -207,7 +207,8 @@ void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes) struct v4l2_event event = {0}; if (ctx->receive_cmd_stop && - !ctx->q_data[AML_Q_DATA_SRC].resolution_changed) { + changes != V4L2_EVENT_SRC_CH_RESOLUTION && + changes != V4L2_EVENT_SEND_EOS) { ctx->state = AML_STATE_ABORT; ATRACE_COUNTER("v4l2_state", ctx->state); changes = V4L2_EVENT_REQUEST_EXIT; @@ -223,6 +224,9 @@ void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes) event.type = V4L2_EVENT_SOURCE_CHANGE; event.u.src_change.changes = changes; break; + case V4L2_EVENT_SEND_EOS: + event.type = V4L2_EVENT_EOS; + break; default: v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "unsupport dispatch event %x\n", changes); @@ -527,7 +531,6 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f } if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { - dstbuf->lastframe = true; dstbuf->vb.flags = V4L2_BUF_FLAG_LAST; if (dstbuf->frame_buffer.num_planes == 1) { vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0); @@ -548,6 +551,25 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f dstbuf->vb.vb2_buf.index, dstbuf->vb.vb2_buf.state); + if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { + if (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; + ctx->reset_flag = V4L_RESET_MODE_LIGHT; + + /* + * After all buffers containing decoded frames from + * before the resolution change point ready to be + * dequeued on the CAPTURE queue, the driver sends a + * V4L2_EVENT_SOURCE_CHANGE event for source change + * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper + * layer will get new information from cts->picinfo. + */ + aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION); + } else + aml_vdec_dispatch_event(ctx, V4L2_EVENT_SEND_EOS); + } + if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) { /* binding vframe handle. */ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR; @@ -569,24 +591,6 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f } mutex_unlock(&ctx->state_lock); - 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; - ctx->reset_flag = V4L_RESET_MODE_LIGHT; - - /* - * After all buffers containing decoded frames from - * before the resolution change point ready to be - * dequeued on the CAPTURE queue, the driver sends a - * V4L2_EVENT_SOURCE_CHANGE event for source change - * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper - * layer will get new information from cts->picinfo. - */ - aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION); - } - ctx->decoded_frame_cnt++; } @@ -645,8 +649,6 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx) if (ctx->state == AML_STATE_PROBE) { ctx->state = AML_STATE_READY; ATRACE_COUNTER("v4l2_state", ctx->state); - ctx->v4l_codec_ready = true; - wake_up_interruptible(&ctx->wq); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_READY)\n"); } @@ -924,7 +926,6 @@ void wait_vcodec_ending(struct aml_vcodec_ctx *ctx) /* flush worker. */ flush_workqueue(dev->decode_workqueue); - ctx->v4l_codec_ready = false; ctx->v4l_codec_dpb_ready = false; /* stop decoder. */ @@ -1153,7 +1154,6 @@ static int vidioc_decoder_streamon(struct file *file, void *priv, (ctx->reset_flag == V4L_RESET_MODE_LIGHT)) { ctx->state = AML_STATE_RESET; ATRACE_COUNTER("v4l2_state", ctx->state); - ctx->v4l_codec_ready = false; ctx->v4l_codec_dpb_ready = false; v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c index 710e13c..b9febb6 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c +++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c @@ -82,7 +82,6 @@ static int fops_vcodec_open(struct file *file) mutex_init(&ctx->state_lock); mutex_init(&ctx->lock); spin_lock_init(&ctx->slock); - init_waitqueue_head(&ctx->wq); init_completion(&ctx->comp); ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0; diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h index aaac607..f66052f 100644 --- a/drivers/amvdec_ports/aml_vcodec_drv.h +++ b/drivers/amvdec_ports/aml_vcodec_drv.h @@ -58,6 +58,9 @@ #define V4L2_EVENT_REQUEST_RESET (1 << 8) #define V4L2_EVENT_REQUEST_EXIT (1 << 9) +/* eos event */ +#define V4L2_EVENT_SEND_EOS (1 << 16) + /* v4l buffer pool */ #define V4L_CAP_BUFF_MAX (32) #define V4L_CAP_BUFF_INVALID (0) @@ -454,9 +457,7 @@ struct aml_vcodec_ctx { int buf_used_count; bool receive_cmd_stop; bool param_sets_from_ucode; - bool v4l_codec_ready; bool v4l_codec_dpb_ready; - wait_queue_head_t wq; spinlock_t slock; struct v4l2_config_parm config; bool is_stream_off; diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c index 9af897c..ed1a76c 100644 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c @@ -5834,17 +5834,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) unsigned short *p = (unsigned short *)hw->lmem_addr; reset_process_time(hw); - 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) { - //amvdec_stop(); - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } #ifdef DETECT_WRONG_MULTI_SLICE hw->cur_picture_slice_count++; if (hw->multi_slice_pic_flag == 1 && diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c index 4146c49..eab36e5 100644 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c @@ -318,9 +318,6 @@ static irqreturn_t vmjpeg_isr_thread_fn(struct vdec_s *vdec, int irq) hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; } if (hw->is_used_v4l) { diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index ba4e5c9..8e93c20 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -1816,9 +1816,6 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; } new_pic->buffer_info = info; diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index c55d8da..6b904e0 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -999,9 +999,6 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; } if (hw->vmpeg4_amstream_dec_info.rate == 0) { diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c index d057eed..e133b93 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c @@ -137,11 +137,11 @@ int vdec_v4l_res_ch_event(struct aml_vcodec_ctx *ctx) aml_vdec_pic_info_update(ctx); mutex_lock(&ctx->state_lock); - if (ctx->state == AML_STATE_ACTIVE) { - ctx->state = AML_STATE_FLUSHING;/*prepare flushing*/ - //ATRACE_COUNTER("v4l2_state", ctx->state); - pr_err("vcodec state (AML_STATE_FLUSHING-RESCHG)\n"); - } + + ctx->state = AML_STATE_FLUSHING;/*prepare flushing*/ + + pr_info("[%d]: vcodec state (AML_STATE_FLUSHING-RESCHG)\n", ctx->id); + mutex_unlock(&ctx->state_lock); ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true; diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c index 7075cd8..21bf5ad 100644 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/frame_provider/decoder/vp9/vvp9.c @@ -9680,25 +9680,6 @@ static void vp9_work(struct work_struct *work) return; } - if (pbi->dec_result == DEC_V4L2_CONTINUE_DECODING) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - - if (ctx->param_sets_from_ucode) { - reset_process_time(pbi); - if (wait_event_interruptible_timeout(ctx->wq, - ctx->v4l_codec_ready, - msecs_to_jiffies(500)) < 0) - return; - } - - continue_decoding(pbi); - pbi->postproc_done = 0; - pbi->process_busy = 0; - - return; - } - if (((pbi->dec_result == DEC_RESULT_GET_DATA) || (pbi->dec_result == DEC_RESULT_GET_DATA_RETRY)) && (hw_to_vdec(pbi)->next_status != |