summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Debski <k.debski@samsung.com>2014-07-02 17:54:34 +0200
committerKamil Debski <k.debski@samsung.com>2014-08-07 16:01:35 +0200
commit1aab95de7ce3e60d723a91707e5c7b926cfad4eb (patch)
treec0f0230f2a1611735be8e3c665cdc80ad3fa6857
parentc655913a3bdd7ef6413814482983c3beff00bdc0 (diff)
v4l2-mfc-example: Add support for DMABUF buffer sharing
This patch adds support for buffer sharing with DMABUF. Now FIMC can take DMABUF buffers from MFC and DRM. Signed-off-by: Kamil Debski <k.debski@samsung.com>
-rw-r--r--v4l2-mfc-example/args.c6
-rw-r--r--v4l2-mfc-example/common.h3
-rw-r--r--v4l2-mfc-example/drm.c28
-rw-r--r--v4l2-mfc-example/fimc.c36
-rw-r--r--v4l2-mfc-example/mfc.c53
5 files changed, 94 insertions, 32 deletions
diff --git a/v4l2-mfc-example/args.c b/v4l2-mfc-example/args.c
index e0298c0..1df7a38 100644
--- a/v4l2-mfc-example/args.c
+++ b/v4l2-mfc-example/args.c
@@ -42,6 +42,7 @@ void print_usage(char *name)
printf("\t-i <file> - Input file name\n");
printf("\t-m <device> - MFC device (e.g. /dev/video8)\n");
printf("\t-D <module>:<crtc>:<conn> - DRM module (e.g. exynos:4:17)\n");
+ printf("\t-B - use DMABUF instead of userptr for sharing buffers\n");
printf("\t-V - synchronise to vsync\n");
printf("\t\n");
printf("\tIf DRM or Frame buffer is used then FIMC should be suppplied.\n");
@@ -79,7 +80,7 @@ int parse_args(struct instance *i, int argc, char **argv)
init_to_defaults(i);
- while ((c = getopt(argc, argv, "c:d:f:i:m:VD:")) != -1) {
+ while ((c = getopt(argc, argv, "c:d:f:i:m:VD:B")) != -1) {
switch (c) {
case 'c':
i->parser.codec = get_codec(optarg);
@@ -101,6 +102,9 @@ int parse_args(struct instance *i, int argc, char **argv)
case 'V':
i->fimc.double_buf = 1;
break;
+ case 'B':
+ i->fimc.dmabuf = 1;
+ break;
case 'D':
/* Name */
tmp = optarg;
diff --git a/v4l2-mfc-example/common.h b/v4l2-mfc-example/common.h
index aff8972..ea5a9d7 100644
--- a/v4l2-mfc-example/common.h
+++ b/v4l2-mfc-example/common.h
@@ -165,6 +165,8 @@ struct instance {
int stride;
int height;
char *p[MAX_BUFS];
+ int dbuf[MAX_BUFS];
+ int dmabuf;
} fimc;
/* MFC related parameters */
@@ -193,6 +195,7 @@ struct instance {
char *cap_buf_addr[MFC_MAX_CAP_BUF][MFC_CAP_PLANES];
int cap_buf_flag[MFC_MAX_CAP_BUF];
int cap_buf_queued;
+ int dbuf[MFC_MAX_CAP_BUF][MFC_CAP_PLANES];
} mfc;
/* Parser related parameters */
diff --git a/v4l2-mfc-example/drm.c b/v4l2-mfc-example/drm.c
index 188d394..d53a0b4 100644
--- a/v4l2-mfc-example/drm.c
+++ b/v4l2-mfc-example/drm.c
@@ -78,13 +78,25 @@ int drm_open(struct instance *i, char *name)
return -1;
}
args.handle = i->drm.gem[n].handle;
- i->drm.mmap[n].handle = i->drm.gem[n].handle;
- i->drm.mmap[n].size = i->drm.gem[n].size;
- ret = ioctl(i->drm.fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &i->drm.mmap[n]);
- if (ret < 0) {
- ioctl(i->drm.fd, DRM_IOCTL_GEM_CLOSE, &args);
- err("Failed to mmap gem");
- return -1;
+
+ if (i->fimc.dmabuf) {
+ ret = drmPrimeHandleToFD(i->drm.fd, i->drm.gem[n].handle, DRM_CLOEXEC, &i->fimc.dbuf[n]);
+ if (ret < 0) {
+ ioctl(i->drm.fd, DRM_IOCTL_GEM_CLOSE, &args);
+ err("Failed to expbuf a gem object");
+ return -1;
+ }
+ } else {
+ i->drm.mmap[n].handle = i->drm.gem[n].handle;
+ i->drm.mmap[n].size = i->drm.gem[n].size;
+ ret = ioctl(i->drm.fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &i->drm.mmap[n]);
+ if (ret < 0) {
+ ioctl(i->drm.fd, DRM_IOCTL_GEM_CLOSE, &args);
+ err("Failed to mmap gem");
+ return -1;
+ }
+ i->drm.p[n] = (char *)(unsigned int)i->drm.mmap[n].mapped;
+ i->fimc.p[n] = (char *)(unsigned int)i->drm.mmap[n].mapped;
}
ret = drmModeAddFB(i->drm.fd, i->drm.width, i->drm.height, 32,
32, 4 * i->drm.width, i->drm.gem[n].handle, &fb_id);
@@ -96,8 +108,6 @@ int drm_open(struct instance *i, char *name)
return -1;
}
i->drm.fb[n] = fb_id;
- i->drm.p[n] = (char *)(unsigned int)i->drm.mmap[n].mapped;
- i->fimc.p[n] = (char *)(unsigned int)i->drm.mmap[n].mapped;
}
snprintf(mode, 32, "%dx%d", crtc->width, crtc->height);
diff --git a/v4l2-mfc-example/fimc.c b/v4l2-mfc-example/fimc.c
index 61476ba..0459c38 100644
--- a/v4l2-mfc-example/fimc.c
+++ b/v4l2-mfc-example/fimc.c
@@ -139,7 +139,11 @@ int fimc_setup_output_from_mfc(struct instance *i)
memzero(reqbuf);
reqbuf.count = i->mfc.cap_buf_cnt;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- reqbuf.memory = V4L2_MEMORY_USERPTR;
+ if (i->fimc.dmabuf) {
+ reqbuf.memory = V4L2_MEMORY_DMABUF;
+ } else {
+ reqbuf.memory = V4L2_MEMORY_USERPTR;
+ }
ret = ioctl(i->fimc.fd, VIDIOC_REQBUFS, &reqbuf);
if (ret) {
@@ -183,8 +187,12 @@ int fimc_setup_capture(struct instance *i)
memzero(reqbuf);
reqbuf.count = i->fimc.buffers;
+ dbg("reqbuf.count = %d", reqbuf.count);
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- reqbuf.memory = V4L2_MEMORY_USERPTR;
+ if (i->fimc.dmabuf && i->drm.enabled)
+ reqbuf.memory = V4L2_MEMORY_DMABUF;
+ else
+ reqbuf.memory = V4L2_MEMORY_USERPTR;
ret = ioctl(i->fimc.fd, VIDIOC_REQBUFS, &reqbuf);
if (ret) {
@@ -224,18 +232,25 @@ int fimc_dec_queue_buf_out_from_mfc(struct instance *i, int n)
memzero(buf);
memzero(planes);
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- buf.memory = V4L2_MEMORY_USERPTR;
buf.index = n;
buf.m.planes = planes;
buf.length = MFC_CAP_PLANES;
buf.m.planes[0].bytesused = i->mfc.cap_buf_size[0];
buf.m.planes[0].length = i->mfc.cap_buf_size[0];
- buf.m.planes[0].m.userptr = (unsigned long)i->mfc.cap_buf_addr[n][0];
buf.m.planes[1].bytesused = i->mfc.cap_buf_size[1];
buf.m.planes[1].length = i->mfc.cap_buf_size[1];
- buf.m.planes[1].m.userptr = (unsigned long)i->mfc.cap_buf_addr[n][1];
+
+ if (i->fimc.dmabuf) {
+ buf.memory = V4L2_MEMORY_DMABUF;
+ buf.m.planes[0].m.fd = i->mfc.dbuf[n][0];
+ buf.m.planes[1].m.fd = i->mfc.dbuf[n][1];
+ } else {
+ buf.memory = V4L2_MEMORY_USERPTR;
+ buf.m.planes[0].m.userptr = (unsigned long)i->mfc.cap_buf_addr[n][0];
+ buf.m.planes[1].m.userptr = (unsigned long)i->mfc.cap_buf_addr[n][1];
+ }
ret = ioctl(i->fimc.fd, VIDIOC_QBUF, &buf);
@@ -258,19 +273,24 @@ int fimc_dec_queue_buf_cap(struct instance *i, int n)
memzero(buf);
memzero(planes);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- buf.memory = V4L2_MEMORY_USERPTR;
buf.index = n;
buf.m.planes = planes;
buf.length = FIMC_CAP_PLANES;
buf.m.planes[0].bytesused = i->fimc.size;
buf.m.planes[0].length = i->fimc.size;
- buf.m.planes[0].m.userptr = (unsigned long)i->fimc.p[n];
+ if (i->fimc.dmabuf && i->drm.enabled) {
+ buf.memory = V4L2_MEMORY_DMABUF;
+ buf.m.planes[0].m.fd = i->fimc.dbuf[n];
+ } else {
+ buf.memory = V4L2_MEMORY_USERPTR;
+ buf.m.planes[0].m.userptr = (unsigned long)i->fimc.p[n];
+ }
ret = ioctl(i->fimc.fd, VIDIOC_QBUF, &buf);
if (ret) {
- err("Failed to queue buffer (index=%d) on OUTPUT", n);
+ err("Failed to queue buffer (index=%d) on CAPTURE", n);
return -1;
}
diff --git a/v4l2-mfc-example/mfc.c b/v4l2-mfc-example/mfc.c
index 89aa22d..1f279a1 100644
--- a/v4l2-mfc-example/mfc.c
+++ b/v4l2-mfc-example/mfc.c
@@ -248,6 +248,7 @@ int mfc_dec_setup_capture(struct instance *i, int extra_buf)
struct v4l2_plane planes[MFC_CAP_PLANES];
struct v4l2_control ctrl;
struct v4l2_crop crop;
+ struct v4l2_exportbuffer expbuf;
int ret;
int n;
@@ -325,20 +326,44 @@ int mfc_dec_setup_capture(struct instance *i, int extra_buf)
return -1;
}
- i->mfc.cap_buf_off[n][0] = buf.m.planes[0].m.mem_offset;
- i->mfc.cap_buf_off[n][1] = buf.m.planes[1].m.mem_offset;
-
- i->mfc.cap_buf_addr[n][0] = mmap(NULL, buf.m.planes[0].length,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- i->mfc.fd, buf.m.planes[0].m.mem_offset);
- i->mfc.cap_buf_addr[n][1] = mmap(NULL, buf.m.planes[1].length,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- i->mfc.fd, buf.m.planes[1].m.mem_offset);
-
- if (i->mfc.cap_buf_addr[n][0] == MAP_FAILED ||
- i->mfc.cap_buf_addr[n][1] == MAP_FAILED) {
- err("Failed to MMAP MFC CAPTURE buffer");
- return -1;
+ if (i->fimc.dmabuf) {
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.index = n;
+ expbuf.plane = 0;
+ expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(i->mfc.fd, VIDIOC_EXPBUF, &expbuf);
+ if (ret != 0) {
+ err("Failed to export buffer\n");
+ return -1;
+ }
+ i->mfc.dbuf[n][0] = expbuf.fd;
+
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.index = n;
+ expbuf.plane = 1;
+ expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(i->mfc.fd, VIDIOC_EXPBUF, &expbuf);
+ if (ret != 0) {
+ err("Failed to export buffer\n");
+ return -1;
+ }
+ i->mfc.dbuf[n][1] = expbuf.fd;
+ } else {
+ i->mfc.cap_buf_off[n][0] = buf.m.planes[0].m.mem_offset;
+ i->mfc.cap_buf_off[n][1] = buf.m.planes[1].m.mem_offset;
+
+ i->mfc.cap_buf_addr[n][0] = mmap(NULL, buf.m.planes[0].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ i->mfc.fd, buf.m.planes[0].m.mem_offset);
+ i->mfc.cap_buf_addr[n][1] = mmap(NULL, buf.m.planes[1].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ i->mfc.fd, buf.m.planes[1].m.mem_offset);
+
+ if (i->mfc.cap_buf_addr[n][0] == MAP_FAILED ||
+ i->mfc.cap_buf_addr[n][1] == MAP_FAILED) {
+ err("Failed to MMAP MFC CAPTURE buffer");
+ return -1;
+ }
}
}