summaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-04-07 08:57:48 -0300
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-04-16 18:43:13 -0300
commit61bd8fb37db948154ae01c8ed43a86633ae1d2be (patch)
tree90f96b0caa8834d2f9fcc2c5b8714106045fdecf /drivers/media/v4l2-core
parent412376a1532a9eb3eb66c9d07175f21cdbebdc09 (diff)
[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: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Pawel Osciak <pawel@osciak.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index b20e0fbc762..2e96f3535e2 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -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)) {
/* Fill in driver-provided information for OUTPUT types */
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
* 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) {
- v4l2_planes[plane].bytesused =
- b->m.planes[plane].bytesused;
- v4l2_planes[plane].data_offset =
- b->m.planes[plane].data_offset;
+ struct v4l2_plane *pdst = &v4l2_planes[plane];
+ struct v4l2_plane *psrc = &b->m.planes[plane];
+
+ 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
* so fill in relevant v4l2_buffer struct fields instead.
* In videobuf we use our internal V4l2_planes struct for
* 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))
- 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) {
v4l2_planes[0].m.userptr = b->m.userptr;