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

Reply via email to