lavd/v4l2: honor previously selected input channel
authorGiorgio Vazzana <mywing81@gmail.com>
Tue, 19 Mar 2013 18:09:38 +0000 (19:09 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 23 Mar 2013 12:43:56 +0000 (13:43 +0100)
An input channel could have been previously set with another application, like
v4l2-ctl, so if no input channel is specified use the previosly selected one.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
doc/indevs.texi
libavdevice/v4l2.c

index cc5d666..63104e2 100644 (file)
@@ -640,7 +640,8 @@ list of the supported standards, use the @option{list_standards}
 option.
 
 @item channel
-Set the input channel number. Default to 0.
+Set the input channel number. Default to -1, which means using the
+previously selected channel.
 
 @item video_size
 Set the video frame size. The argument must be a string in the form
index 2d7773a..c041424 100644 (file)
@@ -894,14 +894,24 @@ static int v4l2_read_header(AVFormatContext *s1)
     if (s->fd < 0)
         return s->fd;
 
-    /* set tv video input */
-    av_log(s1, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
-    if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
-        res = AVERROR(errno);
-        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", av_err2str(res));
-        return res;
+    if (s->channel != -1) {
+        /* set video input */
+        av_log(s1, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
+        if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
+            res = AVERROR(errno);
+            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", av_err2str(res));
+            return res;
+        }
+    } else {
+        /* get current video input */
+        if (v4l2_ioctl(s->fd, VIDIOC_G_INPUT, &s->channel) < 0) {
+            res = AVERROR(errno);
+            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_INPUT): %s\n", av_err2str(res));
+            return res;
+        }
     }
 
+    /* enum input */
     input.index = s->channel;
     if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
         res = AVERROR(errno);
@@ -909,7 +919,7 @@ static int v4l2_read_header(AVFormatContext *s1)
         return res;
     }
     s->std_id = input.std;
-    av_log(s1, AV_LOG_DEBUG, "input_channel: %d, input_name: %s\n",
+    av_log(s1, AV_LOG_DEBUG, "Current input_channel: %d, input_name: %s\n",
            s->channel, input.name);
 
     if (s->list_format) {
@@ -1045,7 +1055,7 @@ static int v4l2_read_close(AVFormatContext *s1)
 
 static const AVOption options[] = {
     { "standard",     "set TV standard, used only by analog frame grabber",       OFFSET(standard),     AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,       DEC },
-    { "channel",      "set TV channel, used only by frame grabber",               OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = 0 },    0, INT_MAX, DEC },
+    { "channel",      "set TV channel, used only by frame grabber",               OFFSET(channel),      AV_OPT_TYPE_INT,    {.i64 = -1 },  -1, INT_MAX, DEC },
     { "video_size",   "set frame size",                                           OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL},  0, 0,   DEC },
     { "pixel_format", "set preferred pixel format",                               OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },
     { "input_format", "set preferred pixel format (for raw video) or codec name", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       DEC },