summaryrefslogtreecommitdiff
authorPeng 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)
commitad9d8329172b01ceeb135c4cabd804c99223a49b (patch)
tree2f06cd3af62ff709ab4e27889364b728a46296fc
parent196b18397ef5ea8a40f235b2f6636106a5774581 (diff)
downloadmedia_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>
Diffstat
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c4
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c48
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c1
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h5
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c11
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c3
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c3
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c3
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c10
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c19
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 !=