[vlc-commits] Only open video device once

Rémi Denis-Courmont git at videolan.org
Mon Sep 5 18:49:45 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Sep  5 19:38:37 2011 +0300| [e07059b020218e03b2c51075c48c90ba40fa052e] | committer: Rémi Denis-Courmont

Only open video device once

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e07059b020218e03b2c51075c48c90ba40fa052e
---

 modules/access/v4l2/video.c |  119 ++++++++++++++++++-------------------------
 1 files changed, 50 insertions(+), 69 deletions(-)

diff --git a/modules/access/v4l2/video.c b/modules/access/v4l2/video.c
index 60be848..d3b6a63 100644
--- a/modules/access/v4l2/video.c
+++ b/modules/access/v4l2/video.c
@@ -419,7 +419,7 @@ static ssize_t AccessReadStream( access_t * p_access, uint8_t * p_buffer, size_t
 static block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys );
 static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size_t );
 
-static int OpenVideoDev( vlc_object_t *, demux_sys_t *, bool );
+static int OpenVideo( vlc_object_t *, demux_sys_t *, bool );
 
 static const struct
 {
@@ -507,25 +507,7 @@ static int DemuxOpen( vlc_object_t *p_this )
     if( p_sys == NULL ) return VLC_ENOMEM;
 
     ParseMRL( p_this, p_demux->psz_location );
-
-#ifdef HAVE_LIBV4L2
-    p_sys->i_fd = -1;
-    if( !var_InheritBool( p_this, CFG_PREFIX "use-libv4l2" ) )
-    {
-        p_sys->b_libv4l2 = false;
-#endif
-        msg_Dbg( p_this, "Trying direct kernel v4l2" );
-        p_sys->i_fd = OpenVideoDev( p_this, p_sys, true );
-#ifdef HAVE_LIBV4L2
-    }
-
-    if( p_sys->i_fd == -1 )
-    {
-        p_sys->b_libv4l2 = true;
-        msg_Dbg( p_this, "Trying libv4l2 wrapper" );
-        p_sys->i_fd = OpenVideoDev( p_this, p_sys, true );
-    }
-#endif
+    p_sys->i_fd = OpenVideo( p_this, p_sys, true );
     if( p_sys->i_fd == -1 )
     {
         free( p_sys );
@@ -672,24 +654,7 @@ static int AccessOpen( vlc_object_t * p_this )
     p_access->p_sys = (access_sys_t*)p_sys;
 
     ParseMRL( p_this, p_access->psz_location );
-
-#ifdef HAVE_LIBV4L2
-    p_sys->i_fd = -1;
-    if( !var_InheritBool( p_this, CFG_PREFIX "use-libv4l2" ) )
-    {
-        p_sys->b_libv4l2 = false;
-#endif
-        msg_Dbg( p_this, "Trying direct kernel v4l2" );
-        p_sys->i_fd = OpenVideoDev( p_this, p_sys, false );
-#ifdef HAVE_LIBV4L2
-    }
-    if( p_sys->i_fd == -1 )
-    {
-        p_sys->b_libv4l2 = true;
-        msg_Dbg( p_this, "Trying libv4l2 wrapper" );
-        p_sys->i_fd = OpenVideoDev( p_this, p_sys, false );
-    }
-#endif
+    p_sys->i_fd = OpenVideo( p_this, p_sys, false );
     if( p_sys->i_fd == -1 )
     {
         free( p_sys );
@@ -1312,50 +1277,66 @@ static void GetMaxDimensions( demux_t *p_demux, int i_fd,
 #endif
 }
 
+static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
+                      bool b_demux );
+
 /**
  * Opens and sets up a video device
  * \return file descriptor or -1 on error
  */
-static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
+static int OpenVideo( vlc_object_t *obj, demux_sys_t *sys, bool b_demux )
 {
-    struct v4l2_cropcap cropcap;
-    struct v4l2_crop crop;
-    struct v4l2_format fmt;
-    unsigned int i_min;
-    enum v4l2_buf_type buf_type;
-    es_format_t es_fmt;
-    struct v4l2_fmtdesc *codecs = NULL;
-
-    char *path = var_InheritString( p_obj, CFG_PREFIX"dev" );
+    char *path = var_InheritString( obj, CFG_PREFIX"dev" );
     if( unlikely(path == NULL) )
         return -1; /* probably OOM */
 
-    msg_Dbg( p_obj, "opening device '%s'", path );
+    msg_Dbg( obj, "opening device '%s'", path );
 
-    int i_fd = vlc_open( path, O_RDWR );
-    if( i_fd == -1 )
+    int fd = vlc_open( path, O_RDWR );
+    if( fd == -1 )
     {
-        msg_Err( p_obj, "cannot open device '%s': %m", path );
+        msg_Err( obj, "cannot open device '%s': %m", path );
         free( path );
         return -1;
     }
     free( path );
-
 #ifdef HAVE_LIBV4L2
+    if( !var_InheritBool( obj, CFG_PREFIX "use-libv4l2" ) )
+    {
+        msg_Dbg( obj, "trying kernel V4L2" );
+        if( InitVideo( obj, fd, sys, b_demux ) == 0 )
+            return fd;
+    }
+    msg_Dbg( obj, "trying library V4L2" );
     /* 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, 0 );
-        if( libv4l2_fd != -1 )
-            i_fd = libv4l2_fd;
-    }
+    int libfd = v4l2_fd_open( fd, 0 );
+    if( libfd == -1 )
+        goto error;
+    fd = libfd;
 #endif
+    if( InitVideo( obj, fd, sys, b_demux ) )
+        goto error;
+
+    return fd;
+error:
+    close( fd );
+    return -1;
+}
+
+static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
+                      bool b_demux )
+{
+    struct v4l2_cropcap cropcap;
+    struct v4l2_crop crop;
+    struct v4l2_format fmt;
+    unsigned int i_min;
+    enum v4l2_buf_type buf_type;
+    es_format_t es_fmt;
 
     /* Get device capabilites */
     struct v4l2_capability cap;
@@ -1387,7 +1368,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
     else
     {
         msg_Err( p_obj, "no supported I/O method" );
-        goto error;
+        return -1;
     }
 
     /* Now, enumerate all the video inputs. This is useless at the moment
@@ -1413,7 +1394,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, &index ) < 0 )
         {
             msg_Err( p_obj, "cannot set input %u: %m", index );
-            goto error;
+            return -1;
         }
         msg_Dbg( p_obj, "input set to %u", index );
     }
@@ -1441,7 +1422,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
          || v4l2_ioctl( i_fd, VIDIOC_G_STD, &std ) < 0 )
         {
             msg_Err( p_obj, "cannot set standard 0x%"PRIx64": %m", std );
-            goto error;
+            return -1;
         }
         msg_Dbg( p_obj, "standard set to 0x%"PRIx64":", std );
         bottom_first = std == V4L2_STD_NTSC;
@@ -1476,7 +1457,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
             if( v4l2_ioctl( i_fd, VIDIOC_S_AUDIO, &audio ) < 0 )
             {
                 msg_Err( p_obj, "cannot set audio input %"PRIu32": %m", idx );
-                goto error;
+                return -1;
             }
             msg_Dbg( p_obj, "audio input set to %"PRIu32, idx );
         }
@@ -1529,7 +1510,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 error;
+                return -1;
             }
             msg_Dbg( p_obj, "tuner frequency set" );
         }
@@ -1547,13 +1528,14 @@ 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 error;
+                return -1;
             }
             msg_Dbg( p_obj, "tuner audio mode set" );
         }
     }
 
     /* Probe for available chromas */
+    struct v4l2_fmtdesc *codecs = NULL;
     uint_fast32_t ncodec = 0;
     if( cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
     {
@@ -1577,7 +1559,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
             if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FMT, &codecs[i] ) < 0 )
             {
                 msg_Err( p_obj, "cannot get codec description: %m" );
-                return -1;
+                goto error;
             }
 
             /* only print if vlc supports the format */
@@ -2034,10 +2016,9 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
 
         p_sys->p_es = es_out_Add( p_demux->out, &es_fmt );
     }
-    return i_fd;
+    return 0;
 
 error:
-    v4l2_close( i_fd );
     free( codecs );
     return -1;
 }



More information about the vlc-commits mailing list