Skip to content

Commit 599a2f9

Browse files
committed
Add support for selecting memory type (MMAP or DMABUF)
Enable configuring vcam device memory type via user-space tool and driver. Users can now specify whether to use MMAP or DMABUF for buffer management.
1 parent 8d41b00 commit 599a2f9

File tree

6 files changed

+53
-10
lines changed

6 files changed

+53
-10
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ After running `make`, you should be able to generate the following files:
2727

2828
Before loading this kernel module, you have to satisfy its dependency:
2929
```shell
30-
$ sudo modprobe -a videobuf2_vmalloc videobuf2_v4l2
30+
$ sudo modprobe -a videobuf2_vmalloc videobuf2_v4l2 videobuf2-dma-contig
3131
```
3232

3333
The module can be loaded to Linux kernel by runnning the command:
@@ -56,7 +56,7 @@ $ sudo ./vcam-util -l
5656
You should get:
5757
```
5858
Available virtual V4L2 compatible devices:
59-
1. fbX(640,480,rgb24) -> /dev/video0
59+
1. fbX(640,480,rgb24,mmap) -> /dev/video0
6060
```
6161

6262
You can use this command to check if the driver is ok:

control.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ static int control_iocontrol_get_device(struct vcam_device_spec *dev_spec)
7373
dev_spec->width = dev->fb_spec.xres_virtual;
7474
dev_spec->height = dev->fb_spec.yres_virtual;
7575
dev_spec->pix_fmt = dev->fb_spec.pix_fmt;
76+
dev_spec->mem_type = dev->fb_spec.mem_type;
7677
dev_spec->cropratio = dev->fb_spec.cropratio;
7778

7879
strncpy((char *) &dev_spec->fb_node, (const char *) vcamfb_get_devnode(dev),
@@ -174,6 +175,7 @@ static struct vcam_device_spec default_vcam_spec = {
174175
.height = 480,
175176
.cropratio = {.numerator = 3, .denominator = 4},
176177
.pix_fmt = VCAM_PIXFMT_RGB24,
178+
.mem_type = VCAM_MEMORY_MMAP,
177179
};
178180

179181
int request_vcam_device(struct vcam_device_spec *dev_spec)

device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ struct vcam_device {
8989
struct v4l2_pix_format output_format;
9090
struct v4l2_pix_format input_format;
9191

92+
/* Memory type */
93+
memtype_t mem_type;
94+
9295
/* Conversion switches */
9396
bool conv_pixfmt_on;
9497
bool conv_res_on;

vcam-util.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010

1111
#include "vcam.h"
1212

13-
static const char *short_options = "hcm:r:ls:p:d:";
13+
static const char *short_options = "hcm:r:ls:p:d:t:";
1414

1515
const struct option long_options[] = {
16-
{"help", 0, NULL, 'h'}, {"create", 0, NULL, 'c'},
17-
{"modify", 1, NULL, 'm'}, {"list", 0, NULL, 'l'},
18-
{"size", 1, NULL, 's'}, {"pixfmt", 1, NULL, 'p'},
19-
{"device", 1, NULL, 'd'}, {"remove", 1, NULL, 'r'},
20-
{NULL, 0, NULL, 0}};
16+
{"help", 0, NULL, 'h'}, {"create", 0, NULL, 'c'},
17+
{"modify", 1, NULL, 'm'}, {"list", 0, NULL, 'l'},
18+
{"size", 1, NULL, 's'}, {"pixfmt", 1, NULL, 'p'},
19+
{"device", 1, NULL, 'd'}, {"remove", 1, NULL, 'r'},
20+
{"memtype", 1, NULL, 't'}, {NULL, 0, NULL, 0}};
2121

2222
const char *help =
2323
" -h --help Print this informations.\n"
@@ -37,6 +37,7 @@ const char *help =
3737
"and apply with crop ratio.\n"
3838
"\n"
3939
" -p --pixfmt pix_fmt Specify pixel format (rgb24,yuyv).\n"
40+
" -t --memtype mem_type Specify memory type (mmap,dmabuf).\n"
4041
" -d --device /dev/* Control device node.\n";
4142

4243
enum ACTION { ACTION_NONE, ACTION_CREATE, ACTION_DESTROY, ACTION_MODIFY };
@@ -45,6 +46,7 @@ struct vcam_device_spec device_template = {
4546
.width = 640,
4647
.height = 480,
4748
.pix_fmt = VCAM_PIXFMT_RGB24,
49+
.mem_type = VCAM_MEMORY_MMAP,
4850
.video_node = "",
4951
.fb_node = "",
5052
};
@@ -102,6 +104,14 @@ int determine_pixfmt(char *pixfmt_str)
102104
return -1;
103105
}
104106

107+
int determine_memtype(char *memtype_str)
108+
{
109+
if (!strncmp(memtype_str, "mmap", 4))
110+
return VCAM_MEMORY_MMAP;
111+
if (!strncmp(memtype_str, "dmabuf", 6))
112+
return VCAM_MEMORY_DMABUF;
113+
return -1;
114+
}
105115
int create_device(struct vcam_device_spec *dev)
106116
{
107117
int fd = open(ctl_path, O_RDWR);
@@ -118,6 +128,9 @@ int create_device(struct vcam_device_spec *dev)
118128
if (!dev->pix_fmt)
119129
dev->pix_fmt = device_template.pix_fmt;
120130

131+
if (!dev->mem_type)
132+
dev->mem_type = device_template.mem_type;
133+
121134
int res = ioctl(fd, VCAM_IOCTL_CREATE_DEVICE, dev);
122135
if (res) {
123136
fprintf(stderr, "Failed to create a new device.\n");
@@ -170,6 +183,9 @@ int modify_device(struct vcam_device_spec *dev)
170183
if (!dev->pix_fmt)
171184
dev->pix_fmt = orig_dev.pix_fmt;
172185

186+
if (!dev->mem_type)
187+
dev->mem_type = orig_dev.mem_type;
188+
173189
if (!dev->cropratio.numerator || !dev->cropratio.denominator)
174190
dev->cropratio = orig_dev.cropratio;
175191

@@ -195,10 +211,11 @@ int list_devices()
195211
printf("Available virtual V4L2 compatible devices:\n");
196212
while (!ioctl(fd, VCAM_IOCTL_GET_DEVICE, &dev)) {
197213
dev.idx++;
198-
printf("%d. %s(%d,%d,%d/%d,%s) -> %s\n", dev.idx, dev.fb_node,
214+
printf("%d. %s(%d,%d,%d/%d,%s,%s) -> %s\n", dev.idx, dev.fb_node,
199215
dev.width, dev.height, dev.cropratio.numerator,
200216
dev.cropratio.denominator,
201217
dev.pix_fmt == VCAM_PIXFMT_RGB24 ? "rgb24" : "yuyv",
218+
dev.mem_type == VCAM_MEMORY_MMAP ? "mmap" : "dmabuf",
202219
dev.video_node);
203220
}
204221
close(fd);
@@ -258,6 +275,16 @@ int main(int argc, char *argv[])
258275
dev.pix_fmt = (char) tmp;
259276
printf("Setting pixel format to %s.\n", optarg);
260277
break;
278+
case 't':
279+
tmp = determine_memtype(optarg);
280+
if (tmp < 0) {
281+
fprintf(stderr, "Failed to recognize memory type %s.\n",
282+
optarg);
283+
exit(-1);
284+
}
285+
dev.mem_type = (char) tmp;
286+
printf("Setting memory type to %s.\n", optarg);
287+
break;
261288
case 'd':
262289
printf("Using device %s.\n", optarg);
263290
strncpy(ctl_path, optarg, sizeof(ctl_path) - 1);

vcam.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define VCAM_IOCTL_MODIFY_SETTING 0x555
1111

1212
typedef enum { VCAM_PIXFMT_RGB24 = 0x01, VCAM_PIXFMT_YUYV = 0x02 } pixfmt_t;
13+
typedef enum { VCAM_MEMORY_MMAP = 0, VCAM_MEMORY_DMABUF = 2 } memtype_t;
1314

1415
struct crop_ratio {
1516
__u32 numerator;
@@ -27,6 +28,7 @@ struct vcam_device_spec {
2728
struct crop_ratio cropratio;
2829

2930
pixfmt_t pix_fmt;
31+
memtype_t mem_type;
3032
char video_node[64];
3133
char fb_node[64];
3234
};

videobuf.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/vmalloc.h>
55
#include <media/videobuf2-core.h>
66
#include <media/videobuf2-dma-contig.h>
7+
#include <media/videobuf2-vmalloc.h>
78

89
#include "videobuf.h"
910

@@ -153,7 +154,15 @@ int vcam_out_videobuf2_setup(struct vcam_device *dev)
153154
q->buf_struct_size = sizeof(struct vcam_out_buffer);
154155
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
155156
q->ops = &vcam_vb2_ops;
156-
q->mem_ops = &vb2_dma_contig_memops;
157+
pr_info("memory type %d\n", dev->mem_type);
158+
switch (dev->mem_type) {
159+
case VCAM_MEMORY_MMAP:
160+
q->mem_ops = &vb2_vmalloc_memops;
161+
break;
162+
case VCAM_MEMORY_DMABUF:
163+
q->mem_ops = &vb2_dma_contig_memops;
164+
break;
165+
}
157166
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 8, 0)
158167
q->min_queued_buffers = 2;
159168
#else

0 commit comments

Comments
 (0)