Commit 61bd8fb3 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] vb2: if bytesused is 0, then fill with output buffer length

The application should really always fill in bytesused for output
buffers, unfortunately the vb2 framework never checked for that.

So for single planar formats replace a bytesused of 0 by the length
of the buffer, and for multiplanar format do the same if bytesused is
0 for ALL planes.

This seems to be what the user really intended if v4l2_buffer was
just memset to 0.

I'm afraid that just checking for this and returning an error would
break too many applications. Quite a few drivers never check for bytesused
at all and just use the buffer length instead.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarPawel Osciak <pawel@osciak.com>
Acked-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 412376a1
...@@ -1208,15 +1208,30 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b ...@@ -1208,15 +1208,30 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
/* Fill in driver-provided information for OUTPUT types */ /* Fill in driver-provided information for OUTPUT types */
if (V4L2_TYPE_IS_OUTPUT(b->type)) { if (V4L2_TYPE_IS_OUTPUT(b->type)) {
bool bytesused_is_used;
/* Check if bytesused == 0 for all planes */
for (plane = 0; plane < vb->num_planes; ++plane)
if (b->m.planes[plane].bytesused)
break;
bytesused_is_used = plane < vb->num_planes;
/* /*
* Will have to go up to b->length when API starts * Will have to go up to b->length when API starts
* accepting variable number of planes. * accepting variable number of planes.
*
* If bytesused_is_used is false, then fall back to the
* full buffer size. In that case userspace clearly
* never bothered to set it and it's a safe assumption
* that they really meant to use the full plane sizes.
*/ */
for (plane = 0; plane < vb->num_planes; ++plane) { for (plane = 0; plane < vb->num_planes; ++plane) {
v4l2_planes[plane].bytesused = struct v4l2_plane *pdst = &v4l2_planes[plane];
b->m.planes[plane].bytesused; struct v4l2_plane *psrc = &b->m.planes[plane];
v4l2_planes[plane].data_offset =
b->m.planes[plane].data_offset; pdst->bytesused = bytesused_is_used ?
psrc->bytesused : psrc->length;
pdst->data_offset = psrc->data_offset;
} }
} }
...@@ -1242,9 +1257,15 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b ...@@ -1242,9 +1257,15 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
* so fill in relevant v4l2_buffer struct fields instead. * so fill in relevant v4l2_buffer struct fields instead.
* In videobuf we use our internal V4l2_planes struct for * In videobuf we use our internal V4l2_planes struct for
* single-planar buffers as well, for simplicity. * single-planar buffers as well, for simplicity.
*
* If bytesused == 0, then fall back to the full buffer size
* as that's a sensible default.
*/ */
if (V4L2_TYPE_IS_OUTPUT(b->type)) if (V4L2_TYPE_IS_OUTPUT(b->type))
v4l2_planes[0].bytesused = b->bytesused; v4l2_planes[0].bytesused =
b->bytesused ? b->bytesused : b->length;
else
v4l2_planes[0].bytesused = 0;
if (b->memory == V4L2_MEMORY_USERPTR) { if (b->memory == V4L2_MEMORY_USERPTR) {
v4l2_planes[0].m.userptr = b->m.userptr; v4l2_planes[0].m.userptr = b->m.userptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment