[RFC 2/3] media: Allow drivers to overwrite vb2_queue.buf_ops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The 'struct vb2_queue.buf_ops' operations are described as
'driver specific callbacks' in the 'struct vb2_buf_ops' documentation
but are actually not overridable by drivers.

Allow driver to override the operations by:

1) Exporting core helper function with the vb2_buf_ naming
2) Conditionally set 'struct vb2_queue.buf_ops' in
   'vb2_queue_init_name()' only if the driver has not set it already
   at queue initialization time

As the videobuf2 framework assumes all the operations to be available,
drivers that are willing to ovveride vb2_queue.buf_ops shall

1) Populate all members of 'struct vb2_buf_ops'
2) Call the core helper as part of their implementations, before or
   after the driver-specific bits
---
 .../media/common/videobuf2/videobuf2-v4l2.c   | 34 +++++++++++--------
 include/media/videobuf2-core.h                |  7 ++++
 include/media/videobuf2-v4l2.h                |  8 +++++
 3 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index c575198e8354..30e04ed2e3a5 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -83,10 +83,11 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer
 	return 0;
 }
 
-static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb)
+int vb2_buf_verify_planes_array(struct vb2_buffer *vb, const void *pb)
 {
 	return __verify_planes_array(vb, pb);
 }
+EXPORT_SYMBOL_GPL(vb2_buf_verify_planes_array);
 
 /*
  * __verify_length() - Verify that the bytesused value for each plane fits in
@@ -129,16 +130,17 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 }
 
 /*
- * __init_vb2_v4l2_buffer() - initialize the vb2_v4l2_buffer struct
+ * vb2_buf_init_buffer() - initialize the vb2_v4l2_buffer struct
  */
-static void __init_vb2_v4l2_buffer(struct vb2_buffer *vb)
+void vb2_buf_init_buffer(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 
 	vbuf->request_fd = -1;
 }
+EXPORT_SYMBOL_GPL(vb2_buf_init_buffer);
 
-static void __copy_timestamp(struct vb2_buffer *vb, const void *pb)
+void vb2_buf_copy_timestamp(struct vb2_buffer *vb, const void *pb)
 {
 	const struct v4l2_buffer *b = pb;
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -156,6 +158,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const void *pb)
 			vbuf->timecode = b->timecode;
 	}
 };
+EXPORT_SYMBOL_GPL(vb2_buf_copy_timestamp);
 
 static void vb2_warn_zero_bytesused(struct vb2_buffer *vb)
 {
@@ -473,10 +476,10 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md
 }
 
 /*
- * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
+ * vb2_buf_fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
  * returned to userspace
  */
-static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
+void vb2_buf_fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
 {
 	struct v4l2_buffer *b = pb;
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -579,13 +582,14 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
 		b->request_fd = vbuf->request_fd;
 	}
 }
+EXPORT_SYMBOL_GPL(vb2_buf_fill_v4l2_buffer);
 
 /*
- * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
+ * vb2_buf_fill_vb2_buffer() - fill a vb2_buffer with information provided in a
  * v4l2_buffer by the userspace. It also verifies that struct
  * v4l2_buffer has a valid number of planes.
  */
-static int __fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes)
+int vb2_buf_fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	unsigned int plane;
@@ -603,13 +607,14 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(vb2_buf_fill_vb2_buffer);
 
 static const struct vb2_buf_ops v4l2_buf_ops = {
-	.verify_planes_array	= __verify_planes_array_core,
-	.init_buffer		= __init_vb2_v4l2_buffer,
-	.fill_user_buffer	= __fill_v4l2_buffer,
-	.fill_vb2_buffer	= __fill_vb2_buffer,
-	.copy_timestamp		= __copy_timestamp,
+	.verify_planes_array	= vb2_buf_verify_planes_array,
+	.init_buffer		= vb2_buf_init_buffer,
+	.fill_user_buffer	= vb2_buf_fill_v4l2_buffer,
+	.fill_vb2_buffer	= vb2_buf_fill_vb2_buffer,
+	.copy_timestamp		= vb2_buf_copy_timestamp,
 };
 
 struct vb2_buffer *vb2_find_buffer(struct vb2_queue *q, u64 timestamp)
@@ -921,7 +926,8 @@ int vb2_queue_init_name(struct vb2_queue *q, const char *name)
 	if (q->buf_struct_size == 0)
 		q->buf_struct_size = sizeof(struct vb2_v4l2_buffer);
 
-	q->buf_ops = &v4l2_buf_ops;
+	if (!q->buf_ops)
+		q->buf_ops = &v4l2_buf_ops;
 	q->is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type);
 	q->is_output = V4L2_TYPE_IS_OUTPUT(q->type);
 	q->copy_timestamp = (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK)
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 8b86996b2719..6f8df9acf6a2 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -455,6 +455,13 @@ struct vb2_ops {
 /**
  * struct vb2_buf_ops - driver-specific callbacks.
  *
+ * These operations are called by the videobuf2 framework unconditionally.
+ * Drivers are allowed to override some of the operations but shall:
+ *
+ * a) Populate all the members of this structure
+ * b) Call the generic core helper as part of their own implementations (see
+ *    vb2_buf_* helpers in videobuf2-v4l2.h)
+ *
  * @verify_planes_array: Verify that a given user space structure contains
  *			enough planes for the buffer. This is called
  *			for each dequeued buffer.
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 5a845887850b..7c6cea933e28 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -383,6 +383,14 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq);
  */
 void vb2_ops_wait_finish(struct vb2_queue *vq);
 
+/* struct vb2_buf_ops helpers */
+
+int vb2_buf_verify_planes_array(struct vb2_buffer *vb, const void *pb);
+void vb2_buf_init_buffer(struct vb2_buffer *vb);
+void vb2_buf_fill_v4l2_buffer(struct vb2_buffer *vb, void *pb);
+int vb2_buf_fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes);
+void vb2_buf_copy_timestamp(struct vb2_buffer *vb, const void *pb);
+
 struct media_request;
 int vb2_request_validate(struct media_request *req);
 void vb2_request_queue(struct media_request *req);
-- 
2.45.1





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux