This is an automatic generated email to let you know that the following patch were queued at the http://git.linuxtv.org/v4l-utils.git tree:
Subject: v4l2-ctl: add support for streaming. Author: Hans Verkuil <[email protected]> Date: Fri Jul 27 14:37:35 2012 +0200 Adds video capture streaming support, either discarding the data or writing it file or stdout. Signed-off-by: Hans Verkuil <[email protected]> (cherry picked from commit 917aef4b423d7a814272826ff7fc60f280847927) Signed-off-by: Gregor Jasny <[email protected]> utils/v4l2-ctl/v4l2-ctl-common.cpp | 1 + utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 147 ++++++++++++++++++++++++++++++++- utils/v4l2-ctl/v4l2-ctl.cpp | 10 ++ utils/v4l2-ctl/v4l2-ctl.h | 7 ++- 4 files changed, 160 insertions(+), 5 deletions(-) --- http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=9b9c16f17ea070ef01e242c12abf5cffb7525df2 diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp index af0c3ea..208d354 100644 --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp @@ -65,6 +65,7 @@ void common_usage(void) " --help-overlay overlay format options\n" " --help-selection crop/selection options\n" " --help-stds standards and other video timings options\n" + " --help-streaming streaming options\n" " --help-tuner tuner/modulator options\n" " --help-vbi VBI format options\n" " --help-vidcap video capture format options\n" diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index a0ecf3d..f5b0921 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -11,6 +11,7 @@ #include <errno.h> #include <sys/ioctl.h> #include <sys/time.h> +#include <sys/mman.h> #include <dirent.h> #include <math.h> @@ -20,9 +21,29 @@ #include "v4l2-ctl.h" +static unsigned stream_count; +static unsigned stream_skip; +static unsigned reqbufs_count = 3; +static char *file; + void streaming_usage(void) { printf("\nVideo Streaming options:\n" + " --stream-count=<count>\n" + " stream <count> buffers. The default is to keep streaming\n" + " forever. This count does not include the number of initial\n" + " skipped buffers as is passed by --stream-skip.\n" + " --stream-skip=<count>\n" + " skip the first <count> buffers. The default is 0.\n" + " --stream-to=<file> stream to this file. The default is to discard the\n" + " data. If <file> is '-', then the data is written to stdout\n" + " and the --silent option is turned on automatically.\n" + " --stream-mmap=<count>\n" + " capture video using mmap() [VIDIOC_(D)QBUF]\n" + " count: the number of buffers to allocate. The default is 3.\n" + " --stream-user=<count>\n" + " capture video using user pointers [VIDIOC_(D)QBUF]\n" + " count: the number of buffers to allocate. The default is 3.\n" " --list-buffers list all video buffers [VIDIOC_QUERYBUF]\n" " --list-buffers-mplane\n" " list all multi-planar video buffers [VIDIOC_QUERYBUF]\n" @@ -119,7 +140,7 @@ static void list_buffers(int fd, unsigned buftype) buf.m.planes = planes; memset(planes, 0, sizeof(planes)); } - if (ioctl(fd, VIDIOC_QUERYBUF, &buf)) + if (test_ioctl(fd, VIDIOC_QUERYBUF, &buf)) break; if (i == 0) printf("VIDIOC_QUERYBUF:\n"); @@ -130,15 +151,133 @@ static void list_buffers(int fd, unsigned buftype) void streaming_cmd(int ch, char *optarg) { switch (ch) { + case OptStreamCount: + stream_count = strtoul(optarg, 0L, 0); + break; + case OptStreamSkip: + stream_skip = strtoul(optarg, 0L, 0); + break; + case OptStreamTo: + file = optarg; + if (strcmp(file, "-")) + options[OptSilent] = true; + break; + case OptStreamMmap: + case OptStreamUser: + if (optarg) { + reqbufs_count = strtoul(optarg, 0L, 0); + if (reqbufs_count == 0) + reqbufs_count = 3; + } + break; } } void streaming_set(int fd) { -} + if (options[OptStreamMmap] || options[OptStreamUser]) { + struct v4l2_requestbuffers reqbufs; + bool is_mmap = options[OptStreamMmap]; + FILE *fout = NULL; -void streaming_get(int fd) -{ + memset(&reqbufs, 0, sizeof(reqbufs)); + reqbufs.count = reqbufs_count; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + reqbufs.memory = is_mmap ? V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR; + + if (file) { + if (!strcmp(file, "-")) + fout = stdout; + else + fout = fopen(file, "w+"); + } + + if (doioctl(fd, VIDIOC_REQBUFS, &reqbufs)) + return; + + void *buffers[reqbufs.count]; + + for (unsigned i = 0; i < reqbufs.count; i++) { + struct v4l2_buffer buf; + + memset(&buf, 0, sizeof(buf)); + buf.type = reqbufs.type; + buf.memory = reqbufs.memory; + buf.index = i; + if (doioctl(fd, VIDIOC_QUERYBUF, &buf)) + return; + if (is_mmap) { + buffers[i] = mmap(NULL, buf.length, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); + + if (buffers[i] == MAP_FAILED) { + fprintf(stderr, "mmap failed\n"); + return; + } + } else { + buffers[i] = calloc(1, buf.length); + buf.m.userptr = (unsigned long)buffers[i]; + } + if (doioctl(fd, VIDIOC_QBUF, &buf)) + return; + } + + int type = reqbufs.type; + if (doioctl(fd, VIDIOC_STREAMON, &type)) + return; + + for (;;) { + struct v4l2_buffer buf; + int ret; + + memset(&buf, 0, sizeof(buf)); + buf.type = reqbufs.type; + buf.memory = reqbufs.memory; + + ret = test_ioctl(fd, VIDIOC_DQBUF, &buf); + if (ret < 0 && errno == EAGAIN) + continue; + if (ret < 0) { + if (!options[OptSilent]) + printf("%s: failed: %s\n", "VIDIOC_DQBUF", strerror(errno)); + return; + } + if (fout == NULL) { + printf("."); + fflush(stdout); + } else if (!stream_skip) { + fwrite(buffers[buf.index], 1, buf.length, fout); + } + if (doioctl(fd, VIDIOC_QBUF, &buf)) + return; + if (stream_skip) { + stream_skip--; + continue; + } + if (stream_count == 0) + continue; + if (--stream_count == 0) + break; + } + doioctl(fd, VIDIOC_STREAMOFF, &type); + + for (unsigned i = 0; i < reqbufs.count; i++) { + struct v4l2_buffer buf; + + memset(&buf, 0, sizeof(buf)); + buf.type = reqbufs.type; + buf.memory = reqbufs.memory; + buf.index = i; + if (doioctl(fd, VIDIOC_QUERYBUF, &buf)) + return; + if (is_mmap) + munmap(buffers[i], buf.length); + else + free(buffers[i]); + } + if (fout) + fclose(fout); + } } void streaming_list(int fd) diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index 507eefc..b9e89bf 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -83,6 +83,7 @@ static struct option long_options[] = { {"help-vbi", no_argument, 0, OptHelpVbi}, {"help-selection", no_argument, 0, OptHelpSelection}, {"help-misc", no_argument, 0, OptHelpMisc}, + {"help-streaming", no_argument, 0, OptHelpStreaming}, {"help-all", no_argument, 0, OptHelpAll}, {"wrapper", no_argument, 0, OptUseWrapper}, {"get-output", no_argument, 0, OptGetOutput}, @@ -192,6 +193,11 @@ static struct option long_options[] = { {"list-buffers-sliced-vbi", no_argument, 0, OptListBuffersSlicedVbi}, {"list-buffers-vbi-out", no_argument, 0, OptListBuffersVbiOut}, {"list-buffers-sliced-vbi-out", no_argument, 0, OptListBuffersSlicedVbiOut}, + {"stream-count", required_argument, 0, OptStreamCount}, + {"stream-skip", required_argument, 0, OptStreamSkip}, + {"stream-to", required_argument, 0, OptStreamTo}, + {"stream-mmap", optional_argument, 0, OptStreamMmap}, + {"stream-user", optional_argument, 0, OptStreamUser}, {0, 0, 0, 0} }; @@ -800,6 +806,9 @@ int main(int argc, char **argv) case OptHelpMisc: misc_usage(); return 0; + case OptHelpStreaming: + streaming_usage(); + return 0; case OptHelpAll: usage_all(); return 0; @@ -950,6 +959,7 @@ int main(int argc, char **argv) vbi_set(fd); selection_set(fd); misc_set(fd); + streaming_set(fd); /* Get options */ diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h index 4d0fc4f..7d5d889 100644 --- a/utils/v4l2-ctl/v4l2-ctl.h +++ b/utils/v4l2-ctl/v4l2-ctl.h @@ -139,6 +139,11 @@ enum Option { OptListBuffersSlicedVbi, OptListBuffersVbiOut, OptListBuffersSlicedVbiOut, + OptStreamCount, + OptStreamSkip, + OptStreamTo, + OptStreamMmap, + OptStreamUser, OptHelpTuner, OptHelpIO, OptHelpStds, @@ -148,6 +153,7 @@ enum Option { OptHelpVbi, OptHelpSelection, OptHelpMisc, + OptHelpStreaming, OptHelpAll, OptLast = 256 }; @@ -265,7 +271,6 @@ void misc_get(int fd); void streaming_usage(void); void streaming_cmd(int ch, char *optarg); void streaming_set(int fd); -void streaming_get(int fd); void streaming_list(int fd); #endif _______________________________________________ linuxtv-commits mailing list [email protected] http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits
