[FFmpeg-devel] [PATCH v4] avcodec/v4l2_m2m: handle the v4l2 eos event
Andriy Gelman
andriy.gelman at gmail.com
Sat Apr 11 18:20:57 EEST 2020
On Wed, 08. Apr 20:51, Andriy Gelman wrote:
> On Wed, 01. Apr 10:38, 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 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.
> >
> > 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 | 6 ++++++
> > libavcodec/v4l2_m2m_dec.c | 8 ++++++++
> > libavcodec/v4l2_m2m_enc.c | 19 +++++++++++++++++++
> > 3 files changed, 33 insertions(+)
> >
> > diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
> > index 8110bbb555..6b1f65fe4c 100644
> > --- a/libavcodec/v4l2_context.c
> > +++ b/libavcodec/v4l2_context.c
> > @@ -154,6 +154,7 @@ static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_upd
> > }
> >
> > /**
> > + * handle resolution change event and end of stream event
> > * returns 1 if reinit was successful, negative if it failed
> > * returns 0 if reinit was not executed
> > */
> > @@ -171,6 +172,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..9989649784 100644
> > --- a/libavcodec/v4l2_m2m_dec.c
> > +++ b/libavcodec/v4l2_m2m_dec.c
> > @@ -123,6 +123,14 @@ 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_WARNING,
> > + "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..78cf9ba47a 100644
> > --- a/libavcodec/v4l2_m2m_enc.c
> > +++ b/libavcodec/v4l2_m2m_enc.c
> > @@ -155,6 +155,23 @@ 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_WARNING,
> > + "the v4l2 driver does not support end of stream VIDIOC_SUBSCRIBE_EVENT\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > static int v4l2_prepare_encoder(V4L2m2mContext *s)
> > {
> > AVCodecContext *avctx = s->avctx;
> > @@ -164,6 +181,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.26.0
> >
>
> lgtm
> Tested on RPi4 and Odroid XU4.
>
Would anyone object if I push this on Tuesday?
(I would align the commit message before pushing)
Thanks,
--
Andriy
More information about the ffmpeg-devel
mailing list