[vlc-devel] [PATCH] V4L2: Open devices only once.

Thierry Reding thierry.reding at avionic-design.de
Thu Aug 4 13:25:34 CEST 2011


Instead of opening the device once for probing purposes and opening it
again when it has been determined suitable, this commit takes the file
descriptor obtained during probing and passes it to the initialization
function.
---
 modules/access/v4l2.c |   92 +++++++++++++++++-------------------------------
 1 files changed, 33 insertions(+), 59 deletions(-)

diff --git a/modules/access/v4l2.c b/modules/access/v4l2.c
index 98bd116..dbc48b3 100644
--- a/modules/access/v4l2.c
+++ b/modules/access/v4l2.c
@@ -415,8 +415,8 @@ static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size
 static bool IsPixelFormatSupported( demux_t *p_demux,
                                           unsigned int i_pixelformat );
 
-static int OpenVideoDev( vlc_object_t *, demux_sys_t *, bool );
-static bool ProbeVideoDev( vlc_object_t *, demux_sys_t *,
+static int InitVideoDev( vlc_object_t *, demux_sys_t *, bool );
+static int ProbeVideoDev( vlc_object_t *, demux_sys_t *,
                                  const char *psz_device );
 
 static int ControlList( vlc_object_t *, demux_sys_t *, int , bool, bool );
@@ -645,10 +645,15 @@ static int FindMainDevice( vlc_object_t *p_this, demux_sys_t *p_sys,
     /* TODO: if using default device, loop through all /dev/video* until
      * one works */
     msg_Dbg( p_this, "opening device '%s'", p_sys->psz_device );
-    if( ProbeVideoDev( p_this, p_sys, p_sys->psz_device ) )
+    p_sys->i_fd = ProbeVideoDev( p_this, p_sys, p_sys->psz_device );
+    if( p_sys->i_fd >= 0 )
     {
         msg_Dbg( p_this, "'%s' is a video device", p_sys->psz_device );
-        p_sys->i_fd = OpenVideoDev( p_this, p_sys, b_demux );
+        if( InitVideoDev( p_this, p_sys, b_demux ) < 0 )
+        {
+            v4l2_close( p_sys->i_fd );
+            p_sys->i_fd = -1;
+        }
     }
 
     if( p_sys->i_fd < 0 ) return VLC_EGENERIC;
@@ -1823,41 +1828,18 @@ static void GetMaxDimensions( demux_t *p_demux, int i_fd,
 }
 
 /*****************************************************************************
- * OpenVideoDev: open and set up the video device and probe for capabilities
+ * InitVideoDev: set up the video device and probe for capabilities
  *****************************************************************************/
-static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
+static int InitVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
 {
-    int i_fd;
+    int i_fd = p_sys->i_fd;
     struct v4l2_cropcap cropcap;
     struct v4l2_crop crop;
     struct v4l2_format fmt;
     unsigned int i_min;
     enum v4l2_buf_type buf_type;
-    const char *psz_device = p_sys->psz_device;
     es_format_t es_fmt;
 
-    if( ( i_fd = v4l2_open( psz_device, O_RDWR ) ) < 0 )
-    {
-        msg_Err( p_obj, "cannot open device (%m)" );
-        goto open_failed;
-    }
-
-#ifdef HAVE_LIBV4L2
-    /* Note the v4l2_xxx functions are designed so that if they get passed an
-       unknown fd, the will behave exactly as their regular xxx counterparts,
-       so if v4l2_fd_open fails, we continue as normal (missing the libv4l2
-       custom cam format to normal formats conversion). Chances are big we will
-       still fail then though, as normally v4l2_fd_open only fails if the
-       device is not a v4l2 device. */
-    if( p_sys->b_libv4l2 )
-    {
-        int libv4l2_fd;
-        libv4l2_fd = v4l2_fd_open( i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION );
-        if( libv4l2_fd != -1 )
-            i_fd = libv4l2_fd;
-    }
-#endif
-
     /* Select standard */
 
     if( p_sys->i_selected_standard_id != V4L2_STD_UNKNOWN )
@@ -1865,12 +1847,12 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( v4l2_ioctl( i_fd, VIDIOC_S_STD, &p_sys->i_selected_standard_id ) < 0 )
         {
             msg_Err( p_obj, "cannot set standard (%m)" );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
         if( v4l2_ioctl( i_fd, VIDIOC_G_STD, &p_sys->i_selected_standard_id ) < 0 )
         {
             msg_Err( p_obj, "cannot get standard (%m). This should never happen!" );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
         msg_Dbg( p_obj, "Set standard to (0x%"PRIx64"):", (int64_t)p_sys->i_selected_standard_id );
         for(unsigned i_standard = 0; i_standard<p_sys->i_standard; i_standard++)
@@ -1889,7 +1871,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( p_sys->i_cur_tuner < 0 || (unsigned)p_sys->i_cur_tuner >= p_sys->i_tuner )
         {
             msg_Err( p_obj, "invalid tuner %d.", p_sys->i_cur_tuner );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
         struct v4l2_frequency frequency;
         memset( &frequency, 0, sizeof( frequency ) );
@@ -1899,7 +1881,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( v4l2_ioctl( i_fd, VIDIOC_S_FREQUENCY, &frequency ) < 0 )
         {
             msg_Err( p_obj, "cannot set tuner frequency (%m)" );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
         msg_Dbg( p_obj, "Tuner frequency set" );
     }
@@ -1910,7 +1892,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( p_sys->i_cur_tuner < 0 || (unsigned)p_sys->i_cur_tuner >= p_sys->i_tuner )
         {
             msg_Err( p_obj, "invalid tuner %d.", p_sys->i_cur_tuner );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
         struct v4l2_tuner tuner;
         memset( &tuner, 0, sizeof( tuner ) );
@@ -1919,7 +1901,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( v4l2_ioctl( i_fd, VIDIOC_S_TUNER, &tuner ) < 0 )
         {
             msg_Err( p_obj, "cannot set tuner audio mode (%m)" );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
         msg_Dbg( p_obj, "Tuner audio mode set" );
     }
@@ -1935,7 +1917,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
     if( v4l2_ioctl( i_fd, VIDIOC_S_INPUT, &p_sys->i_selected_input ) < 0 )
     {
         msg_Err( p_obj, "cannot set input (%m)" );
-        goto open_failed;
+        return VLC_EGENERIC;
     }
 
     /* Set audio input */
@@ -1971,7 +1953,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
             if( !(p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE) )
             {
                 msg_Err( p_obj, "device does not support read i/o" );
-                goto open_failed;
+                return VLC_EGENERIC;
             }
             msg_Dbg( p_obj, "using read i/o" );
             break;
@@ -1981,7 +1963,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
             if( !(p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING) )
             {
                 msg_Err( p_obj, "device does not support streaming i/o" );
-                goto open_failed;
+                return VLC_EGENERIC;
             }
             if( p_sys->io == IO_METHOD_MMAP )
                 msg_Dbg( p_obj, "using streaming i/o (mmap)" );
@@ -1991,7 +1973,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
 
         default:
             msg_Err( p_obj, "io method not supported" );
-            goto open_failed;
+            return VLC_EGENERIC;
     }
 
     /* Reset Cropping */
@@ -2028,7 +2010,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( v4l2_ioctl( i_fd, VIDIOC_G_FMT, &fmt ) < 0 )
         {
             msg_Err( p_obj, "Cannot get default width and height." );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
 
         msg_Dbg( p_obj, "found default width and height of %ux%u",
@@ -2285,8 +2267,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         break;
 
     default:
-        goto open_failed;
-        break;
+        return VLC_EGENERIC;
     }
 
     if( b_demux )
@@ -2330,7 +2311,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
             if( v4l2_ioctl( i_fd, VIDIOC_QBUF, &buf ) < 0 )
             {
                 msg_Err( p_obj, "VIDIOC_QBUF failed" );
-                goto open_failed;
+                return VLC_EGENERIC;
             }
         }
 
@@ -2338,7 +2319,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( v4l2_ioctl( i_fd, VIDIOC_STREAMON, &buf_type ) < 0 )
         {
             msg_Err( p_obj, "VIDIOC_STREAMON failed" );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
 
         break;
@@ -2358,7 +2339,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
             if( v4l2_ioctl( i_fd, VIDIOC_QBUF, &buf ) < 0 )
             {
                 msg_Err( p_obj, "VIDIOC_QBUF failed" );
-                goto open_failed;
+                return VLC_EGENERIC;
             }
         }
 
@@ -2366,14 +2347,13 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         if( v4l2_ioctl( i_fd, VIDIOC_STREAMON, &buf_type ) < 0 )
         {
             msg_Err( p_obj, "VIDIOC_STREAMON failed" );
-            goto open_failed;
+            return VLC_EGENERIC;
         }
 
         break;
 
     default:
-        goto open_failed;
-        break;
+        return VLC_EGENERIC;
     }
 
     /* report fps */
@@ -2382,18 +2362,14 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
         msg_Dbg( p_obj, "User set fps=%f", p_sys->f_fps );
     }
 
-    return i_fd;
-
-open_failed:
-    if( i_fd >= 0 ) v4l2_close( i_fd );
-    return -1;
+    return VLC_SUCCESS;
 
 }
 
 /*****************************************************************************
  * ProbeVideoDev: probe video for capabilities
  *****************************************************************************/
-static bool ProbeVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys,
+static int ProbeVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys,
                                  const char *psz_device )
 {
     int i_fd;
@@ -2751,14 +2727,12 @@ static bool ProbeVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys,
         }
     }
 
-
-    if( i_fd >= 0 ) v4l2_close( i_fd );
-    return true;
+    return i_fd;
 
 open_failed:
 
     if( i_fd >= 0 ) v4l2_close( i_fd );
-    return false;
+    return -1;
 
 }
 
-- 
1.7.6




More information about the vlc-devel mailing list