@@ -171,6 +171,11 @@ static int v4l2_handle_event(V4L2Context *ctx)
return 0;
}
+ if (evt.type == V4L2_EVENT_EOS) {
+ ctx->done = 1;
+ return 0;
+ }
+
if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
return 0;
@@ -123,6 +123,15 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s)
}
}
+ memset(&sub, 0, sizeof(sub));
+ sub.type = V4L2_EVENT_EOS;
+ ret = ioctl(s->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "the v4l2 driver does not support VIDIOC_SUBSCRIBE_EVENT\n"
+ "you must provide an eos event to finish encode\n");
+ }
+
return 0;
}
@@ -155,6 +155,24 @@ static int v4l2_check_b_frame_support(V4L2m2mContext *s)
return AVERROR_PATCHWELCOME;
}
+static int v4l2_subscribe_eos_event(V4L2m2mContext *s)
+{
+ struct v4l2_event_subscription sub;
+ int ret;
+
+ memset(&sub, 0, sizeof(sub));
+ sub.type = V4L2_EVENT_EOS;
+ ret = ioctl(s->fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "the v4l2 driver does not support VIDIOC_SUBSCRIBE_EVENT\n"
+ "you must provide an eos event to finish encode\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int v4l2_prepare_encoder(V4L2m2mContext *s)
{
AVCodecContext *avctx = s->avctx;
@@ -164,10 +182,12 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s)
/**
* requirements
*/
- ret = v4l2_check_b_frame_support(s);
+ ret = v4l2_subscribe_eos_event(s);
if (ret)
return ret;
+ v4l2_check_b_frame_support(s);
+
/**
* settingss
*/
when the last frame of capture is dequeueed, driver may send this V4L2_EVENT_EOS event, if this event is received, then we can set the capture port done if the v4l2 m2m driver don't support V4L2_EVENT_EOS, just output some error message, not make it error. Without this patch imx8qm often hangs at the end of encoding/decoding when flushing the capture buffers Signed-off-by: Ming Qian <ming.qian@nxp.com> --- libavcodec/v4l2_context.c | 5 +++++ libavcodec/v4l2_m2m_dec.c | 9 +++++++++ libavcodec/v4l2_m2m_enc.c | 22 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-)