Commit 83ae7c5a1b5b5cd4380ff70797e4c5dcfb61a70d

Authored by Tomasz Stanislawski
Committed by Mauro Carvalho Chehab
1 parent 19b6ef5164

[media] v4l: vb2: add buffer exporting via dmabuf

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>

Showing 4 changed files with 103 additions and 0 deletions Side-by-side Diff

drivers/media/v4l2-core/v4l2-mem2mem.c
... ... @@ -369,6 +369,19 @@
369 369 EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
370 370  
371 371 /**
  372 + * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
  373 + * the type
  374 + */
  375 +int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  376 + struct v4l2_exportbuffer *eb)
  377 +{
  378 + struct vb2_queue *vq;
  379 +
  380 + vq = v4l2_m2m_get_vq(m2m_ctx, eb->type);
  381 + return vb2_expbuf(vq, eb);
  382 +}
  383 +EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
  384 +/**
372 385 * v4l2_m2m_streamon() - turn on streaming for a video queue
373 386 */
374 387 int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
drivers/media/v4l2-core/videobuf2-core.c
... ... @@ -1751,6 +1751,79 @@
1751 1751 }
1752 1752  
1753 1753 /**
  1754 + * vb2_expbuf() - Export a buffer as a file descriptor
  1755 + * @q: videobuf2 queue
  1756 + * @eb: export buffer structure passed from userspace to vidioc_expbuf
  1757 + * handler in driver
  1758 + *
  1759 + * The return values from this function are intended to be directly returned
  1760 + * from vidioc_expbuf handler in driver.
  1761 + */
  1762 +int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
  1763 +{
  1764 + struct vb2_buffer *vb = NULL;
  1765 + struct vb2_plane *vb_plane;
  1766 + int ret;
  1767 + struct dma_buf *dbuf;
  1768 +
  1769 + if (q->memory != V4L2_MEMORY_MMAP) {
  1770 + dprintk(1, "Queue is not currently set up for mmap\n");
  1771 + return -EINVAL;
  1772 + }
  1773 +
  1774 + if (!q->mem_ops->get_dmabuf) {
  1775 + dprintk(1, "Queue does not support DMA buffer exporting\n");
  1776 + return -EINVAL;
  1777 + }
  1778 +
  1779 + if (eb->flags & ~O_CLOEXEC) {
  1780 + dprintk(1, "Queue does support only O_CLOEXEC flag\n");
  1781 + return -EINVAL;
  1782 + }
  1783 +
  1784 + if (eb->type != q->type) {
  1785 + dprintk(1, "qbuf: invalid buffer type\n");
  1786 + return -EINVAL;
  1787 + }
  1788 +
  1789 + if (eb->index >= q->num_buffers) {
  1790 + dprintk(1, "buffer index out of range\n");
  1791 + return -EINVAL;
  1792 + }
  1793 +
  1794 + vb = q->bufs[eb->index];
  1795 +
  1796 + if (eb->plane >= vb->num_planes) {
  1797 + dprintk(1, "buffer plane out of range\n");
  1798 + return -EINVAL;
  1799 + }
  1800 +
  1801 + vb_plane = &vb->planes[eb->plane];
  1802 +
  1803 + dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
  1804 + if (IS_ERR_OR_NULL(dbuf)) {
  1805 + dprintk(1, "Failed to export buffer %d, plane %d\n",
  1806 + eb->index, eb->plane);
  1807 + return -EINVAL;
  1808 + }
  1809 +
  1810 + ret = dma_buf_fd(dbuf, eb->flags);
  1811 + if (ret < 0) {
  1812 + dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
  1813 + eb->index, eb->plane, ret);
  1814 + dma_buf_put(dbuf);
  1815 + return ret;
  1816 + }
  1817 +
  1818 + dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
  1819 + eb->index, eb->plane, ret);
  1820 + eb->fd = ret;
  1821 +
  1822 + return 0;
  1823 +}
  1824 +EXPORT_SYMBOL_GPL(vb2_expbuf);
  1825 +
  1826 +/**
1754 1827 * vb2_mmap() - map video buffers into application address space
1755 1828 * @q: videobuf2 queue
1756 1829 * @vma: vma passed to the mmap file operation handler in the driver
... ... @@ -2455,6 +2528,16 @@
2455 2528 return vb2_streamoff(vdev->queue, i);
2456 2529 }
2457 2530 EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
  2531 +
  2532 +int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p)
  2533 +{
  2534 + struct video_device *vdev = video_devdata(file);
  2535 +
  2536 + if (vb2_queue_is_busy(vdev, file))
  2537 + return -EBUSY;
  2538 + return vb2_expbuf(vdev->queue, p);
  2539 +}
  2540 +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
2458 2541  
2459 2542 /* v4l2_file_operations helpers */
2460 2543  
include/media/v4l2-mem2mem.h
... ... @@ -111,6 +111,9 @@
111 111 int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
112 112 struct v4l2_buffer *buf);
113 113  
  114 +int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  115 + struct v4l2_exportbuffer *eb);
  116 +
114 117 int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
115 118 enum v4l2_buf_type type);
116 119 int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
include/media/videobuf2-core.h
... ... @@ -81,6 +81,7 @@
81 81 struct vb2_mem_ops {
82 82 void *(*alloc)(void *alloc_ctx, unsigned long size);
83 83 void (*put)(void *buf_priv);
  84 + struct dma_buf *(*get_dmabuf)(void *buf_priv);
84 85  
85 86 void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
86 87 unsigned long size, int write);
... ... @@ -363,6 +364,7 @@
363 364 void vb2_queue_release(struct vb2_queue *q);
364 365  
365 366 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
  367 +int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
366 368 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
367 369  
368 370 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
... ... @@ -472,6 +474,8 @@
472 474 int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p);
473 475 int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i);
474 476 int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i);
  477 +int vb2_ioctl_expbuf(struct file *file, void *priv,
  478 + struct v4l2_exportbuffer *p);
475 479  
476 480 /* struct v4l2_file_operations helpers */
477 481