1*4882a593SmuzhiyunFrom 81471d8195f3da907205ec7384bccfe9c8f846fd Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: "vicent.chi" <vicent.chi@rock-chips.com>
3*4882a593SmuzhiyunDate: Thu, 31 Oct 2019 11:46:12 +0800
4*4882a593SmuzhiyunSubject: [PATCH 3/7] libv4l: add V4L2_MEMORY_DMABUF memory support
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunSigned-off-by: vicent.chi <vicent.chi@rock-chips.com>
7*4882a593Smuzhiyun---
8*4882a593Smuzhiyun lib/libv4l2/libv4l2-priv.h |  1 +
9*4882a593Smuzhiyun lib/libv4l2/libv4l2.c      | 23 +++++++++++++++++++++--
10*4882a593Smuzhiyun 2 files changed, 22 insertions(+), 2 deletions(-)
11*4882a593Smuzhiyun
12*4882a593Smuzhiyundiff --git a/lib/libv4l2/libv4l2-priv.h b/lib/libv4l2/libv4l2-priv.h
13*4882a593Smuzhiyunindex 1924c91..30dd1bc 100644
14*4882a593Smuzhiyun--- a/lib/libv4l2/libv4l2-priv.h
15*4882a593Smuzhiyun+++ b/lib/libv4l2/libv4l2-priv.h
16*4882a593Smuzhiyun@@ -104,6 +104,7 @@ struct v4l2_dev_info {
17*4882a593Smuzhiyun 	void *plugin_library;
18*4882a593Smuzhiyun 	void *dev_ops_priv;
19*4882a593Smuzhiyun 	const struct libv4l_dev_ops *dev_ops;
20*4882a593Smuzhiyun+	int has_dmabuf_memory;
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* From v4l2-plugin.c */
24*4882a593Smuzhiyundiff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c
25*4882a593Smuzhiyunindex 0c02bec..0b17888 100644
26*4882a593Smuzhiyun--- a/lib/libv4l2/libv4l2.c
27*4882a593Smuzhiyun+++ b/lib/libv4l2/libv4l2.c
28*4882a593Smuzhiyun@@ -543,7 +543,7 @@ static int v4l2_deactivate_read_stream(int index)
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun static int v4l2_needs_conversion(int index)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun-	if (devices[index].convert == NULL)
33*4882a593Smuzhiyun+	if (devices[index].convert == NULL || devices[index].has_dmabuf_memory)
34*4882a593Smuzhiyun 		return 0;
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun 	return v4lconvert_needs_conversion(devices[index].convert,
37*4882a593Smuzhiyun@@ -1305,12 +1305,18 @@ no_capture_request:
38*4882a593Smuzhiyun 		struct v4l2_requestbuffers *req = arg;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun 		/* IMPROVEME (maybe?) add support for userptr's? */
41*4882a593Smuzhiyun-		if (req->memory != V4L2_MEMORY_MMAP) {
42*4882a593Smuzhiyun+		if (req->memory != V4L2_MEMORY_MMAP && req->memory != V4L2_MEMORY_DMABUF) {
43*4882a593Smuzhiyun 			errno = EINVAL;
44*4882a593Smuzhiyun 			result = -1;
45*4882a593Smuzhiyun 			break;
46*4882a593Smuzhiyun 		}
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun+		if (req->memory == V4L2_MEMORY_DMABUF) {
49*4882a593Smuzhiyun+			devices[index].has_dmabuf_memory = 1;
50*4882a593Smuzhiyun+			V4L2_LOG("memory type is V4L2_MEMORY_DMABUF, "
51*4882a593Smuzhiyun+			         "buf conversion and mmap emulation are disabled\n");
52*4882a593Smuzhiyun+		}
53*4882a593Smuzhiyun+
54*4882a593Smuzhiyun 		result = v4l2_check_buffer_change_ok(index);
55*4882a593Smuzhiyun 		if (result)
56*4882a593Smuzhiyun 			break;
57*4882a593Smuzhiyun@@ -1563,6 +1569,14 @@ ssize_t v4l2_read(int fd, void *dest, size_t n)
58*4882a593Smuzhiyun 		goto leave;
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun+	if (!(devices[index].flags & V4L2_USE_READ_FOR_READ) &&
62*4882a593Smuzhiyun+	    devices[index].has_dmabuf_memory) {
63*4882a593Smuzhiyun+		V4L2_PERROR("memory type is V4L2_MEMORY_DMABUF, "
64*4882a593Smuzhiyun+		            "no support v4l2 read\n");
65*4882a593Smuzhiyun+		errno = EINVAL;
66*4882a593Smuzhiyun+		return -1;
67*4882a593Smuzhiyun+	}
68*4882a593Smuzhiyun+
69*4882a593Smuzhiyun 	/* Since we need to do conversion try to use mmap (streaming) mode under
70*4882a593Smuzhiyun 	   the hood as that safes a memcpy for each frame read.
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun@@ -1627,6 +1641,7 @@ void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd,
73*4882a593Smuzhiyun 	void *result;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun 	index = v4l2_get_index(fd);
76*4882a593Smuzhiyun+
77*4882a593Smuzhiyun 	if (index != -1 && devices[index].dev_ops->mmap) {
78*4882a593Smuzhiyun 		pthread_mutex_lock(&devices[index].stream_lock);
79*4882a593Smuzhiyun 		result = devices[index].dev_ops->mmap(
80*4882a593Smuzhiyun@@ -1637,6 +1652,10 @@ void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd,
81*4882a593Smuzhiyun 		return result;
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun+        if (index != -1 && devices[index].has_dmabuf_memory) {
85*4882a593Smuzhiyun+                return (void *)SYS_MMAP(start, length, prot, flags, fd, offset);
86*4882a593Smuzhiyun+        }
87*4882a593Smuzhiyun+
88*4882a593Smuzhiyun 	if (index == -1 ||
89*4882a593Smuzhiyun 			/* Check if the mmap data matches our answer to QUERY_BUF. If it doesn't,
90*4882a593Smuzhiyun 			   let the kernel handle it (to allow for mmap-based non capture use) */
91*4882a593Smuzhiyun--
92*4882a593Smuzhiyun2.20.1
93*4882a593Smuzhiyun
94