[FFmpeg-cvslog] lavd/v4l2: select input immediately after opening the device

Giorgio Vazzana git at videolan.org
Sun Jan 27 18:41:13 CET 2013


ffmpeg | branch: master | Giorgio Vazzana <mywing81 at gmail.com> | Sat Jan 26 13:37:37 2013 +0100| [93d319a5826a2e682fbc4a7457bca2f7462a829b] | committer: Stefano Sabatini

lavd/v4l2: select input immediately after opening the device

After opening the device, the first thing we should do is selecting the
input. This is because the image formats (VIDIOC_ENUM_FMT ioctl) and the
standards (VIDIOC_ENUMSTD ioctl) supported may depend on the selected
input ([1] and [2]).

[1] http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-enum-fmt.html
[2] http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-enumstd.html

Signed-off-by: Stefano Sabatini <stefasab at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=93d319a5826a2e682fbc4a7457bca2f7462a829b
---

 libavdevice/v4l2.c |   37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index d1d0562..f6b72bd 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -112,6 +112,7 @@ struct video_data {
     void **buf_start;
     unsigned int *buf_len;
     char *standard;
+    v4l2_std_id std_id;
     int channel;
     char *pixel_format; /**< Set by a private option. */
     int list_format;    /**< Set by a private option. */
@@ -655,7 +656,6 @@ static void mmap_close(struct video_data *s)
 static int v4l2_set_parameters(AVFormatContext *s1)
 {
     struct video_data *s = s1->priv_data;
-    struct v4l2_input input = { 0 };
     struct v4l2_standard standard = { 0 };
     struct v4l2_streamparm streamparm = { 0 };
     struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
@@ -671,22 +671,6 @@ static int v4l2_set_parameters(AVFormatContext *s1)
         return ret;
     }
 
-    /* set tv video input */
-    input.index = s->channel;
-    if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
-        av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
-        return AVERROR(EIO);
-    }
-
-    av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
-            s->channel, input.name);
-    if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
-        av_log(s1, AV_LOG_ERROR,
-               "The V4L2 driver ioctl set input(%d) failed\n",
-                s->channel);
-        return AVERROR(EIO);
-    }
-
     if (s->standard) {
         av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
                s->standard);
@@ -807,6 +791,7 @@ static int v4l2_read_header(AVFormatContext *s1)
     uint32_t desired_format;
     enum AVCodecID codec_id = AV_CODEC_ID_NONE;
     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
+    struct v4l2_input input = { 0 };
 
     st = avformat_new_stream(s1, NULL);
     if (!st)
@@ -816,6 +801,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 = errno;
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", strerror(errno));
+        return AVERROR(res);
+    }
+
+    input.index = s->channel;
+    if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
+        res = errno;
+        av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMINPUT): %s\n", strerror(errno));
+        return AVERROR(res);
+    }
+    s->std_id = input.std;
+    av_log(s1, AV_LOG_DEBUG, "input_channel: %d, input_name: %s\n",
+           s->channel, input.name);
+
     if (s->list_format) {
         list_formats(s1, s->fd, s->list_format);
         return AVERROR_EXIT;



More information about the ffmpeg-cvslog mailing list