[FFmpeg-devel] [PATCH v3] avcodec/v4l2_m2m: handle the v4l2 eos event
Andriy Gelman
andriy.gelman at gmail.com
Sun Mar 29 17:49:50 EEST 2020
On Tue, 17. Mar 19:39, Ming Qian wrote:
> 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
s/dequeueed/dequeued
Also I'd change the last line to:
"If this event is received, then the capture buffers have been flushed and
avcodec_receive_packet()/avcodec_receive_frame() can return AVERROR_EOF.
Otherwise, the draining continues until all the capture buffers have been dequeued or
VIDIOC_DQBUF ioctl returns an EPIPE error.
>
> if the v4l2 m2m driver don't support V4L2_EVENT_EOS,
> just output some error message, not make it error.
Some devices may not support V4L2_EVENT_EOS. This is logged as a warning
message and not treated as a fatal error during initialization.
>
> Without this patch imx8qm often hangs at the end of encoding/decoding when
> flushing the capture buffers
>
> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> ---
> libavcodec/v4l2_context.c | 5 +++++
> libavcodec/v4l2_m2m_dec.c | 9 +++++++++
> libavcodec/v4l2_m2m_enc.c | 20 ++++++++++++++++++++
> 3 files changed, 34 insertions(+)
>
> 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;
> + }
> +
The comments above the function definition should be updated
because the function would also handle end of stream event.
> 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");
> + }
> +
Since some decoders may work fine without this event, I'd suggest to change to AV_LOG_WARNING,
and set the message as:
"the v4l2 driver does not support end of stream VIDIOC_SUBSCRIBE_EVENT\n"
> return 0;
> }
>
> diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
> index 84de63ec9d..13bd9d29f4 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;
> + }
Same here for loglevel and message.
> +
> + return 0;
> +}
> +
> static int v4l2_prepare_encoder(V4L2m2mContext *s)
> {
> AVCodecContext *avctx = s->avctx;
> @@ -164,6 +182,8 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s)
> /**
> * requirements
> */
> + v4l2_subscribe_eos_event(s);
> +
> ret = v4l2_check_b_frame_support(s);
> if (ret)
> return ret;
> --
> 2.17.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
Thanks
--
Andriy
More information about the ffmpeg-devel
mailing list