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.q...@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(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 8110bbb555..c10862aa12 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -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; diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c index d666edffe4..7a4d2a43cb 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -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; } diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 5b954f4435..849d28e9a8 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -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 */ -- 2.17.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".