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.q...@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. Thanks, -- Andriy _______________________________________________ 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".