Message ID | 20200429212942.28797-1-andriy.gelman@gmail.com |
---|---|
State | Accepted |
Commit | e3b49aaa4eed7955e243b110e1209960ba5aaf74 |
Headers | show |
Series | [FFmpeg-devel,1/2] avcodec/v4l2_context: Drop empty packet while draining | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
> From: Andriy Gelman <andriy.gelman@gmail.com> > > v4l2_m2m devices may send an empty packet/frame while draining to indicate > that all capture buffers have been flushed. > > Currently, the empty packet/frame is not handled correctly: > When encoding, the empty packet is forwarded to the muxer, usually creating > warnings. > When decoding, a reference to the memory is created anyway.. Since in the > past this memory contained a decoded frame, it results in an extra frame being > decoded. > > This commit discards the empty packet/frame. > > References: > linux/Documentation/media/uapi/v4l/dev-decoder.rst: > > "The last buffer may be empty (with :c:type:`v4l2_buffer` bytesused = 0) > and in that case it must be ignored by the client, as it does not > contain a decoded frame." > > linux/Documentation/media/uapi/media/v4l/vidioc-encoder-cmd.rst: > > "...This buffer may be empty, indicated by the > driver setting the ``bytesused`` field to 0." > > Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com> > --- > libavcodec/v4l2_context.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > > diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index > 6c2db5c849..f0ecc18ebd 100644 > --- a/libavcodec/v4l2_context.c > +++ b/libavcodec/v4l2_context.c > @@ -393,6 +393,15 @@ dequeue: > return NULL; > } > > + if (ctx_to_m2mctx(ctx)->draining > && !V4L2_TYPE_IS_OUTPUT(ctx->type)) { > + int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ? > + buf.m.planes[0].bytesused : buf.bytesused; > + if (bytesused == 0) { > + ctx->done = 1; > + return NULL; > + } > + } > + > avbuf = &ctx->buffers[buf.index]; > avbuf->status = V4L2BUF_AVAILABLE; > avbuf->buf = buf; > -- > 2.25.1 > Lgtm
On Thu, 30. Apr 01:39, Ming Qian wrote: > > From: Andriy Gelman <andriy.gelman@gmail.com> > > > > v4l2_m2m devices may send an empty packet/frame while draining to indicate > > that all capture buffers have been flushed. > > > > Currently, the empty packet/frame is not handled correctly: > > When encoding, the empty packet is forwarded to the muxer, usually creating > > warnings. > > When decoding, a reference to the memory is created anyway.. Since in the > > past this memory contained a decoded frame, it results in an extra frame being > > decoded. > > > > This commit discards the empty packet/frame. > > > > References: > > linux/Documentation/media/uapi/v4l/dev-decoder.rst: > > > > "The last buffer may be empty (with :c:type:`v4l2_buffer` bytesused = 0) > > and in that case it must be ignored by the client, as it does not > > contain a decoded frame." > > > > linux/Documentation/media/uapi/media/v4l/vidioc-encoder-cmd.rst: > > > > "...This buffer may be empty, indicated by the > > driver setting the ``bytesused`` field to 0." > > > > Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com> > > --- > > libavcodec/v4l2_context.c | 9 +++++++++ > > 1 file changed, 9 insertions(+) > > > > diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index > > 6c2db5c849..f0ecc18ebd 100644 > > --- a/libavcodec/v4l2_context.c > > +++ b/libavcodec/v4l2_context.c > > @@ -393,6 +393,15 @@ dequeue: > > return NULL; > > } > > > > + if (ctx_to_m2mctx(ctx)->draining > > && !V4L2_TYPE_IS_OUTPUT(ctx->type)) { > > + int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ? > > + buf.m.planes[0].bytesused : buf.bytesused; > > + if (bytesused == 0) { > > + ctx->done = 1; > > + return NULL; > > + } > > + } > > + > > avbuf = &ctx->buffers[buf.index]; > > avbuf->status = V4L2BUF_AVAILABLE; > > avbuf->buf = buf; > > -- > > 2.25.1 > > > > Lgtm > Thanks. Will apply both patches on Friday if no one objects.
On Tue, 05. May 17:29, Andriy Gelman wrote: > On Thu, 30. Apr 01:39, Ming Qian wrote: > > > From: Andriy Gelman <andriy.gelman@gmail.com> > > > > > > v4l2_m2m devices may send an empty packet/frame while draining to indicate > > > that all capture buffers have been flushed. > > > > > > Currently, the empty packet/frame is not handled correctly: > > > When encoding, the empty packet is forwarded to the muxer, usually creating > > > warnings. > > > When decoding, a reference to the memory is created anyway.. Since in the > > > past this memory contained a decoded frame, it results in an extra frame being > > > decoded. > > > > > > This commit discards the empty packet/frame. > > > > > > References: > > > linux/Documentation/media/uapi/v4l/dev-decoder.rst: > > > > > > "The last buffer may be empty (with :c:type:`v4l2_buffer` bytesused = 0) > > > and in that case it must be ignored by the client, as it does not > > > contain a decoded frame." > > > > > > linux/Documentation/media/uapi/media/v4l/vidioc-encoder-cmd.rst: > > > > > > "...This buffer may be empty, indicated by the > > > driver setting the ``bytesused`` field to 0." > > > > > > Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com> > > > --- > > > libavcodec/v4l2_context.c | 9 +++++++++ > > > 1 file changed, 9 insertions(+) > > > > > > diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index > > > 6c2db5c849..f0ecc18ebd 100644 > > > --- a/libavcodec/v4l2_context.c > > > +++ b/libavcodec/v4l2_context.c > > > @@ -393,6 +393,15 @@ dequeue: > > > return NULL; > > > } > > > > > > + if (ctx_to_m2mctx(ctx)->draining > > > && !V4L2_TYPE_IS_OUTPUT(ctx->type)) { > > > + int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ? > > > + buf.m.planes[0].bytesused : buf.bytesused; > > > + if (bytesused == 0) { > > > + ctx->done = 1; > > > + return NULL; > > > + } > > > + } > > > + > > > avbuf = &ctx->buffers[buf.index]; > > > avbuf->status = V4L2BUF_AVAILABLE; > > > avbuf->buf = buf; > > > -- > > > 2.25.1 > > > > > > > > Lgtm > > > > Thanks. > Will apply both patches on Friday if no one objects. > Applied both patches. Thanks,
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 6c2db5c849..f0ecc18ebd 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -393,6 +393,15 @@ dequeue: return NULL; } + if (ctx_to_m2mctx(ctx)->draining && !V4L2_TYPE_IS_OUTPUT(ctx->type)) { + int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ? + buf.m.planes[0].bytesused : buf.bytesused; + if (bytesused == 0) { + ctx->done = 1; + return NULL; + } + } + avbuf = &ctx->buffers[buf.index]; avbuf->status = V4L2BUF_AVAILABLE; avbuf->buf = buf;