[media] v4l: vb2: add buffer exporting via dmabuf
authorTomasz Stanislawski <t.stanislaws@samsung.com>
Thu, 14 Jun 2012 14:32:24 +0000 (11:32 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 25 Nov 2012 19:21:00 +0000 (17:21 -0200)
This patch adds extension to videobuf2-core. It allow to export an mmap buffer
as a DMABUF file descriptor.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/v4l2-core/v4l2-mem2mem.c
drivers/media/v4l2-core/videobuf2-core.c
include/media/v4l2-mem2mem.h
include/media/videobuf2-core.h

index 017fed8ad2abef60562d1564a4d1071139bbff4c..438ea45d10749750a2941474265b0e72ea75f239 100644 (file)
@@ -368,6 +368,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
 
+/**
+ * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
+ * the type
+ */
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+                 struct v4l2_exportbuffer *eb)
+{
+       struct vb2_queue *vq;
+
+       vq = v4l2_m2m_get_vq(m2m_ctx, eb->type);
+       return vb2_expbuf(vq, eb);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
 /**
  * v4l2_m2m_streamon() - turn on streaming for a video queue
  */
index 613dea16a30470067338ad69833bac83a96bf585..9f81be23a81f06a1d527ac792071e1b7a6154979 100644 (file)
@@ -1750,6 +1750,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
        return -EINVAL;
 }
 
+/**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q:         videobuf2 queue
+ * @eb:                export buffer structure passed from userspace to vidioc_expbuf
+ *             handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+       struct vb2_buffer *vb = NULL;
+       struct vb2_plane *vb_plane;
+       int ret;
+       struct dma_buf *dbuf;
+
+       if (q->memory != V4L2_MEMORY_MMAP) {
+               dprintk(1, "Queue is not currently set up for mmap\n");
+               return -EINVAL;
+       }
+
+       if (!q->mem_ops->get_dmabuf) {
+               dprintk(1, "Queue does not support DMA buffer exporting\n");
+               return -EINVAL;
+       }
+
+       if (eb->flags & ~O_CLOEXEC) {
+               dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+               return -EINVAL;
+       }
+
+       if (eb->type != q->type) {
+               dprintk(1, "qbuf: invalid buffer type\n");
+               return -EINVAL;
+       }
+
+       if (eb->index >= q->num_buffers) {
+               dprintk(1, "buffer index out of range\n");
+               return -EINVAL;
+       }
+
+       vb = q->bufs[eb->index];
+
+       if (eb->plane >= vb->num_planes) {
+               dprintk(1, "buffer plane out of range\n");
+               return -EINVAL;
+       }
+
+       vb_plane = &vb->planes[eb->plane];
+
+       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+       if (IS_ERR_OR_NULL(dbuf)) {
+               dprintk(1, "Failed to export buffer %d, plane %d\n",
+                       eb->index, eb->plane);
+               return -EINVAL;
+       }
+
+       ret = dma_buf_fd(dbuf, eb->flags);
+       if (ret < 0) {
+               dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+                       eb->index, eb->plane, ret);
+               dma_buf_put(dbuf);
+               return ret;
+       }
+
+       dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+               eb->index, eb->plane, ret);
+       eb->fd = ret;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
 /**
  * vb2_mmap() - map video buffers into application address space
  * @q:         videobuf2 queue
@@ -2456,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
 
+int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p)
+{
+       struct video_device *vdev = video_devdata(file);
+
+       if (vb2_queue_is_busy(vdev, file))
+               return -EBUSY;
+       return vb2_expbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
+
 /* v4l2_file_operations helpers */
 
 int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
index 131cc4a53675eb97f14c7cd4c5355e06640200d7..7e82d2b193d5625702594fe59f1484e1b09c3d06 100644 (file)
@@ -111,6 +111,9 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
 int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                   struct v4l2_buffer *buf);
 
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+                  struct v4l2_exportbuffer *eb);
+
 int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                      enum v4l2_buf_type type);
 int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
index 24b9c90194f285faa57b42243cdb459330124921..9cfd4ee9e56f1eb7dec09704b15a4fabcbb976a4 100644 (file)
@@ -81,6 +81,7 @@ struct vb2_fileio_data;
 struct vb2_mem_ops {
        void            *(*alloc)(void *alloc_ctx, unsigned long size);
        void            (*put)(void *buf_priv);
+       struct dma_buf *(*get_dmabuf)(void *buf_priv);
 
        void            *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
                                        unsigned long size, int write);
@@ -363,6 +364,7 @@ int __must_check vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
 
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
@@ -472,6 +474,8 @@ int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
 int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p);
 int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i);
 int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i);
+int vb2_ioctl_expbuf(struct file *file, void *priv,
+       struct v4l2_exportbuffer *p);
 
 /* struct v4l2_file_operations helpers */