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.q...@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@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". 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".