OptVerbose = 'v',
OptSetVbiDevice = 'V',
OptUseWrapper = 'w',
+ OptSetExpBufDevice = 128,
OptLast = 256
};
{"device", required_argument, 0, OptSetDevice},
{"radio-device", required_argument, 0, OptSetRadioDevice},
{"vbi-device", required_argument, 0, OptSetVbiDevice},
+ {"expbuf-device", required_argument, 0, OptSetExpBufDevice},
{"help", no_argument, 0, OptHelp},
{"verbose", no_argument, 0, OptVerbose},
{"no-warnings", no_argument, 0, OptNoWarnings},
{"set-input", required_argument, 0, OptSetInput},
{"set-output", required_argument, 0, OptSetOutput},
{"set-freq", required_argument, 0, OptSetFreq},
- {"streaming", no_argument, 0, OptStreaming},
+ {"streaming", optional_argument, 0, OptStreaming},
{0, 0, 0, 0}
};
printf(" if <dev> starts with a digit, then /dev/radio<dev> is used.\n");
printf(" -V, --vbi-device=<dev> use device <dev> as the vbi device.\n");
printf(" if <dev> starts with a digit, then /dev/vbi<dev> is used.\n");
+ printf(" --expbuf-device=<dev> use device <dev> to obtain DMABUF handles.\n");
+ printf(" if <dev> starts with a digit, then /dev/video<dev> is used.\n");
+ printf(" only /dev/videoX devices are supported.\n");
printf(" -i, --set-input select input for streaming tests (default is 0).\n");
printf(" -o, --set-output select output for streaming tests (default is 0).\n");
printf(" -f, --set-freq select frequency in MHz (kHz for radio) for streaming tests.\n");
- printf(" -s, --streaming enable the streaming tests. Requires a valid input/output and\n");
- printf(" frequency (when dealing with a tuner).\n");
+ printf(" -s, --streaming=<count> enable the streaming tests. Set <count> to the number of\n");
+ printf(" frames to stream (default 100). Requires a valid input/output\n");
+ printf(" and frequency (when dealing with a tuner). For DMABUF testing\n");
+ printf(" --expbuf-device needs to be set as well.\n");
printf(" -h, --help display this help message.\n");
printf(" -n, --no-warnings turn off warning messages.\n");
printf(" -T, --trace trace all called ioctls.\n");
struct node radio_node2 = { -1, true };
struct node vbi_node = { -1 };
struct node vbi_node2 = { -1 };
+ struct node expbuf_node = { -1 };
/* command args */
int ch;
const char *device = NULL;
- const char *video_device = NULL; /* -d device */
+ const char *video_device = NULL; /* -d device */
const char *radio_device = NULL; /* -r device */
const char *vbi_device = NULL; /* -V device */
- struct v4l2_capability vcap; /* list_cap */
+ const char *expbuf_device = NULL; /* --expbuf-device device */
+ struct v4l2_capability vcap; /* list_cap */
+ unsigned frame_count = 100;
char short_options[26 * 2 * 2 + 1];
int idx = 0;
vbi_device = newdev;
}
break;
+ case OptSetExpBufDevice:
+ expbuf_device = optarg;
+ if (expbuf_device[0] >= '0' && expbuf_device[0] <= '9' && strlen(expbuf_device) <= 3) {
+ static char newdev[20];
+
+ sprintf(newdev, "/dev/video%s", expbuf_device);
+ expbuf_device = newdev;
+ }
+ break;
case OptSetInput:
select_input = strtoul(optarg, NULL, 0);
break;
case OptSetOutput:
select_output = strtoul(optarg, NULL, 0);
break;
+ case OptStreaming:
+ if (optarg)
+ frame_count = strtoul(optarg, NULL, 0);
+ break;
case OptSetFreq:
select_freq = strtod(optarg, NULL);
break;
exit(1);
}
+ if (expbuf_device && (expbuf_node.fd = test_open(expbuf_device, O_RDWR)) < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n", expbuf_device,
+ strerror(errno));
+ exit(1);
+ }
+
if (video_node.fd >= 0) {
node.fd = video_node.fd;
device = video_device;
printf("Buffer ioctls:\n");
printf("\ttest VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: %s\n", ok(testReqBufs(&node)));
+ printf("\ttest VIDIOC_EXPBUF: %s\n", ok(testExpBuf(&node)));
if (options[OptStreaming]) {
if (options[OptSetInput])
doioctl(&node, VIDIOC_S_INPUT, &select_input);
// Reopen to clear the 'file I/O' mode of the filehandle,
// preventing VIDIOC_REQBUFS from working (will return -EBUSY).
reopen(&node);
- printf("\ttest MMAP: %s\n", ok(testMmap(&node)));
- printf("\ttest USERPTR: %s\n", ok(testUserPtr(&node)));
+ printf("\ttest MMAP: %s\n", ok(testMmap(&node, frame_count)));
+ printf("\ttest USERPTR: %s\n", ok(testUserPtr(&node, frame_count)));
+ if (options[OptSetExpBufDevice] ||
+ !(node.valid_memorytype & (1 << V4L2_MEMORY_DMABUF)))
+ printf("\ttest DMABUF: %s\n", ok(testDmaBuf(&expbuf_node, &node, frame_count)));
+ else if (!options[OptSetExpBufDevice])
+ printf("\ttest DMABUF: Cannot test, specify --expbuf-device\n");
}
printf("\n");
VIDIOC_CROPCAP, VIDIOC_G/S_CROP, VIDIOC_G/S_SELECTION
VIDIOC_S_FBUF/OVERLAY
- VIDIOC_EXPBUF
*/
/* Final test report */
mmap(start, length, prot, flags, fd, offset);
}
-static void *ptrs[VIDEO_MAX_FRAME];
+static void *ptrs[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
+static int dmabufs[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
static struct v4l2_format cur_fmt;
static int last_seq;
static unsigned last_field;
}
static int checkQueryBuf(struct node *node, const struct v4l2_buffer &buf,
- __u32 type, __u32 memory, unsigned index, enum QueryBufMode mode,
- unsigned count)
+ __u32 type, __u32 memory, unsigned index, enum QueryBufMode mode)
{
unsigned timestamp = buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MASK;
unsigned frame_types = 0;
struct v4l2_plane *vp = buf.m.planes + p;
if (buf.memory == V4L2_MEMORY_USERPTR)
- fail_on_test((void *)vp->m.userptr != ptrs[buf.index]);
+ fail_on_test((void *)vp->m.userptr != ptrs[buf.index][p]);
+ else if (buf.memory == V4L2_MEMORY_DMABUF)
+ fail_on_test(vp->m.fd != dmabufs[buf.index][p]);
fail_on_test(vp->data_offset + vp->bytesused > vp->length);
}
} else {
if (buf.memory == V4L2_MEMORY_USERPTR)
- fail_on_test((void *)buf.m.userptr != ptrs[buf.index]);
+ fail_on_test((void *)buf.m.userptr != ptrs[buf.index][0]);
+ else if (buf.memory == V4L2_MEMORY_DMABUF)
+ fail_on_test(buf.m.fd != dmabufs[buf.index][0]);
}
}
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
if (V4L2_TYPE_IS_MULTIPLANAR(type))
fail_on_test(buf.m.planes != planes);
- fail_on_test(checkQueryBuf(node, buf, type, buf.memory, i, Unqueued, 0));
+ fail_on_test(checkQueryBuf(node, buf, type, buf.memory, i, Unqueued));
}
buf.index = count;
ret = doioctl(node, VIDIOC_QUERYBUF, &buf);
fail_on_test(bufs.type != i);
fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
fail_on_test(testQueryBuf(node, i, bufs.count));
+ node->valid_memorytype |= 1 << V4L2_MEMORY_MMAP;
}
if (userptr_valid) {
fail_on_test(bufs.type != i);
fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
fail_on_test(testQueryBuf(node, i, bufs.count));
+ node->valid_memorytype |= 1 << V4L2_MEMORY_USERPTR;
}
if (dmabuf_valid) {
fail_on_test(bufs.type != i);
fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
fail_on_test(testQueryBuf(node, i, bufs.count));
+ node->valid_memorytype |= 1 << V4L2_MEMORY_DMABUF;
}
if (can_rw) {
buf.length = VIDEO_MAX_PLANES;
}
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued, 0));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued));
// Try a random offset
- ptrs[i] = test_mmap(NULL, buf.length,
+ ptrs[i][0] = test_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, buf.m.offset + 0xdeadbeef);
- fail_on_test(ptrs[i] != MAP_FAILED);
+ fail_on_test(ptrs[i][0] != MAP_FAILED);
// Now with the proper offset
- ptrs[i] = test_mmap(NULL, buf.length,
+ ptrs[i][0] = test_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, buf.m.offset);
- fail_on_test(ptrs[i] == MAP_FAILED);
+ fail_on_test(ptrs[i][0] == MAP_FAILED);
ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf);
fail_on_test(ret && ret != ENOTTY);
if (ret == 0) {
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared, 0));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared));
}
fail_on_test(doioctl(node, VIDIOC_QBUF, &buf));
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Queued, 0));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Queued));
}
return 0;
}
buf.length = VIDEO_MAX_PLANES;
}
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- munmap(ptrs[i], buf.length);
+ munmap(ptrs[i][0], buf.length);
}
return 0;
}
static int captureBufs(struct node *node, const struct v4l2_requestbuffers &bufs,
- unsigned count, bool use_poll)
+ unsigned frame_count, bool use_poll)
{
int fd_flags = fcntl(node->fd, F_GETFL);
struct v4l2_buffer buf;
+ unsigned count = frame_count;
int ret;
if (use_poll)
buf.index, buf.sequence, field2s(buf.field).c_str(),
buf.timestamp.tv_sec, buf.timestamp.tv_usec);
fail_on_test(ret);
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, buf.index, Dequeued, 100 - count));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, buf.index, Dequeued));
if (!show_info) {
- printf("\r\tFrame #%03d%s", 100 - count, use_poll ? " (polling)" : "");
+ printf("\r\tFrame #%03d%s", frame_count - count, use_poll ? " (polling)" : "");
fflush(stdout);
}
fail_on_test(doioctl(node, VIDIOC_QBUF, &buf));
return 0;
}
-int testMmap(struct node *node)
+int testMmap(struct node *node, unsigned frame_count)
{
struct v4l2_requestbuffers bufs;
struct v4l2_create_buffers cbufs;
fail_on_test(doioctl(node, VIDIOC_STREAMON, &bufs.type));
fail_on_test(doioctl(node, VIDIOC_STREAMON, &bufs.type));
- fail_on_test(captureBufs(node, bufs, 100, false));
- fail_on_test(captureBufs(node, bufs, 100, true));
+ fail_on_test(captureBufs(node, bufs, frame_count, false));
+ fail_on_test(captureBufs(node, bufs, frame_count, true));
fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
fail_on_test(releaseMmap(node, bufs));
buf.length = VIDEO_MAX_PLANES;
}
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued, 0));
- ptrs[i] = malloc(buf.length);
- fail_on_test(ptrs[i] == NULL);
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued));
+ ptrs[i][0] = malloc(buf.length);
+ fail_on_test(ptrs[i][0] == NULL);
ret = ENOTTY;
// Try to use VIDIOC_PREPARE_BUF for every other buffer
ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf);
fail_on_test(!ret);
- buf.m.userptr = (unsigned long)ptrs[i] + buf.length / 2;
+ buf.m.userptr = (unsigned long)ptrs[i][0] + buf.length / 2;
ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf);
fail_on_test(!ret);
- buf.m.userptr = (unsigned long)ptrs[i];
+ buf.m.userptr = (unsigned long)ptrs[i][0];
ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf);
fail_on_test(ret && ret != ENOTTY);
if (ret == 0) {
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared, 0));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared));
}
}
if (ret == ENOTTY) {
ret = doioctl(node, VIDIOC_QBUF, &buf);
fail_on_test(!ret);
- buf.m.userptr = (unsigned long)ptrs[i] + buf.length / 2;
+ buf.m.userptr = (unsigned long)ptrs[i][0] + buf.length / 2;
ret = doioctl(node, VIDIOC_QBUF, &buf);
fail_on_test(!ret);
- buf.m.userptr = (unsigned long)ptrs[i];
+ buf.m.userptr = (unsigned long)ptrs[i][0];
}
fail_on_test(doioctl(node, VIDIOC_QBUF, &buf));
fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
- fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Queued, 0));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Queued));
}
return 0;
}
static int releaseUserPtr(struct node *node, struct v4l2_requestbuffers &bufs)
{
for (unsigned i = 0; i < bufs.count; i++)
- free(ptrs[i]);
+ free(ptrs[i][0]);
return 0;
}
-int testUserPtr(struct node *node)
+int testUserPtr(struct node *node, unsigned frame_count)
{
struct v4l2_requestbuffers bufs;
bool can_stream = node->caps & V4L2_CAP_STREAMING;
fail_on_test(doioctl(node, VIDIOC_STREAMON, &bufs.type));
fail_on_test(doioctl(node, VIDIOC_STREAMON, &bufs.type));
- fail_on_test(captureBufs(node, bufs, 100, false));
- fail_on_test(captureBufs(node, bufs, 100, true));
+ fail_on_test(captureBufs(node, bufs, frame_count, false));
+ fail_on_test(captureBufs(node, bufs, frame_count, true));
fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
fail_on_test(releaseUserPtr(node, bufs));
fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
return 0;
}
+
+int testExpBuf(struct node *node)
+{
+ struct v4l2_requestbuffers bufs;
+ struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ struct v4l2_buffer buf;
+ int err = 0;
+
+ if (!(node->caps & V4L2_CAP_VIDEO_CAPTURE))
+ return 0;
+ if (!(node->valid_memorytype & (1 << V4L2_MEMORY_MMAP)))
+ return ENOTTY;
+
+ memset(&bufs, 0, sizeof(bufs));
+ bufs.count = 1;
+ bufs.memory = V4L2_MEMORY_MMAP;
+ bufs.type = V4L2_CAP_VIDEO_CAPTURE;
+ fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
+
+ memset(ptrs, 0, sizeof(ptrs));
+
+ for (unsigned i = 0; i < bufs.count; i++) {
+ struct v4l2_exportbuffer expbuf;
+
+ memset(&buf, 0, sizeof(buf));
+ buf.type = bufs.type;
+ buf.memory = bufs.memory;
+ buf.index = i;
+ if (V4L2_TYPE_IS_MULTIPLANAR(bufs.type)) {
+ buf.m.planes = planes;
+ buf.length = VIDEO_MAX_PLANES;
+ }
+ fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
+
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.type = bufs.type;
+ expbuf.index = i;
+ expbuf.flags = O_RDWR;
+ err = doioctl(node, VIDIOC_EXPBUF, &expbuf);
+ if (err == ENOTTY)
+ break;
+
+ dmabufs[i][0] = buf.m.fd = expbuf.fd;
+
+ ptrs[i][0] = mmap(NULL, buf.length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, expbuf.fd, 0);
+ if (ptrs[i][0] == MAP_FAILED) {
+ close(dmabufs[i][0]);
+ ptrs[i][0] = NULL;
+ fail("mmap on DMABUF file descriptor failed\n");
+ err = ENOMEM;
+ break;
+ }
+ }
+
+ for (unsigned i = 0; i < bufs.count; i++) {
+ for (unsigned p = 0; p < VIDEO_MAX_PLANES; p++) {
+ if (ptrs[i][p]) {
+ if (V4L2_TYPE_IS_MULTIPLANAR(bufs.type))
+ munmap(ptrs[i][p], planes[p].length);
+ else
+ munmap(ptrs[i][p], buf.length);
+ close(dmabufs[i][p]);
+ }
+ }
+ }
+
+ bufs.count = 0;
+ fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
+ return err;
+}
+
+static int setupDmaBuf(struct node *expbuf_node, struct node *node,
+ struct v4l2_requestbuffers &bufs)
+{
+ struct v4l2_requestbuffers expbuf_bufs;
+ struct v4l2_plane expbuf_planes[VIDEO_MAX_PLANES];
+ struct v4l2_buffer expbuf_buf;
+
+ memset(&expbuf_bufs, 0, sizeof(expbuf_bufs));
+ expbuf_bufs.count = bufs.count;
+ expbuf_bufs.memory = V4L2_MEMORY_MMAP;
+ expbuf_bufs.type = bufs.type;
+ fail_on_test(doioctl(expbuf_node, VIDIOC_REQBUFS, &expbuf_bufs));
+ fail_on_test(expbuf_bufs.count < bufs.count);
+
+ memset(&expbuf_buf, 0, sizeof(expbuf_buf));
+ expbuf_buf.type = expbuf_bufs.type;
+ expbuf_buf.memory = expbuf_bufs.memory;
+ if (V4L2_TYPE_IS_MULTIPLANAR(expbuf_bufs.type)) {
+ expbuf_buf.m.planes = expbuf_planes;
+ expbuf_buf.length = VIDEO_MAX_PLANES;
+ }
+ fail_on_test(doioctl(expbuf_node, VIDIOC_QUERYBUF, &expbuf_buf));
+
+ for (unsigned i = 0; i < bufs.count; i++) {
+ struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ struct v4l2_buffer buf;
+ struct v4l2_exportbuffer expbuf;
+ int ret;
+
+ memset(&buf, 0, sizeof(buf));
+ buf.type = bufs.type;
+ buf.memory = bufs.memory;
+ buf.index = i;
+ if (V4L2_TYPE_IS_MULTIPLANAR(bufs.type)) {
+ buf.m.planes = planes;
+ buf.length = VIDEO_MAX_PLANES;
+ }
+ fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued));
+ fail_on_test(expbuf_buf.length < buf.length);
+ if (V4L2_TYPE_IS_MULTIPLANAR(bufs.type))
+ for (unsigned p = 0; p < buf.length; p++)
+ fail_on_test(expbuf_planes[p].length < planes[p].length);
+
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.type = bufs.type;
+ expbuf.index = i;
+ expbuf.flags = O_RDWR;
+ fail_on_test(doioctl(expbuf_node, VIDIOC_EXPBUF, &expbuf));
+
+ dmabufs[i][0] = buf.m.fd = expbuf.fd;
+
+ ptrs[i][0] = mmap(NULL, buf.length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, expbuf.fd, 0);
+ fail_on_test(ptrs[i][0] == MAP_FAILED);
+
+ ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf);
+ fail_on_test(ret && ret != ENOTTY);
+ if (ret == 0) {
+ fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared));
+ }
+
+ fail_on_test(doioctl(node, VIDIOC_QBUF, &buf));
+ fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
+ fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Queued));
+ }
+ return 0;
+}
+
+static int releaseDmaBuf(struct node *expbuf_node, struct node *node,
+ struct v4l2_requestbuffers &bufs)
+{
+ for (unsigned i = 0; i < bufs.count; i++) {
+ struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ struct v4l2_buffer buf;
+
+ memset(&buf, 0, sizeof(buf));
+ buf.type = bufs.type;
+ buf.memory = bufs.memory;
+ buf.index = i;
+ if (V4L2_TYPE_IS_MULTIPLANAR(bufs.type)) {
+ buf.m.planes = planes;
+ buf.length = VIDEO_MAX_PLANES;
+ }
+ fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf));
+ munmap(ptrs[i][0], buf.length);
+ close(dmabufs[i][0]);
+ }
+ return 0;
+}
+
+int testDmaBuf(struct node *expbuf_node, struct node *node, unsigned frame_count)
+{
+ struct v4l2_requestbuffers bufs;
+ bool can_stream = node->caps & V4L2_CAP_STREAMING;
+ int ret;
+
+ if (!(node->caps & V4L2_CAP_VIDEO_CAPTURE))
+ return 0;
+
+ memset(&bufs, 0, sizeof(bufs));
+ bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ bufs.memory = V4L2_MEMORY_DMABUF;
+ ret = doioctl(node, VIDIOC_REQBUFS, &bufs);
+ if (ret) {
+ fail_on_test(ret != EINVAL);
+ return ENOTTY;
+ }
+ fail_on_test(!can_stream);
+
+ bufs.count = 1;
+ fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
+ fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
+ last_seq = -1;
+ field_nr = 1;
+ last_field = cur_fmt.fmt.pix.field;
+
+ fail_on_test(setupDmaBuf(expbuf_node, node, bufs));
+
+ fail_on_test(doioctl(node, VIDIOC_STREAMON, &bufs.type));
+ fail_on_test(doioctl(node, VIDIOC_STREAMON, &bufs.type));
+ fail_on_test(captureBufs(node, bufs, frame_count, false));
+ fail_on_test(captureBufs(node, bufs, frame_count, true));
+ fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
+ fail_on_test(doioctl(node, VIDIOC_STREAMOFF, &bufs.type));
+ fail_on_test(releaseDmaBuf(expbuf_node, node, bufs));
+ bufs.count = 0;
+ fail_on_test(doioctl(node, VIDIOC_REQBUFS, &bufs));
+
+ struct v4l2_requestbuffers expbuf_bufs;
+
+ memset(&expbuf_bufs, 0, sizeof(expbuf_bufs));
+ expbuf_bufs.memory = V4L2_MEMORY_MMAP;
+ expbuf_bufs.type = bufs.type;
+ fail_on_test(doioctl(expbuf_node, VIDIOC_REQBUFS, &expbuf_bufs));
+ return 0;
+}