This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/tvtime.git tree:

Subject: videoinput: Add support for automatically selecting the video input 
device
Author:  Hans de Goede <[email protected]>
Date:    Sat Feb 13 16:47:29 2016 -0200

Based on the xawtv3 code to do the same. This is useful for a more
plug and play operation esp. when a usb webcam sometimes gets plugged
in which may change the video-dev enumeration order.

Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 src/tvtimeconf.c |  14 ++++--
 src/videoinput.c | 139 +++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 115 insertions(+), 38 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/tvtime.git/commit/?id=cf65071bf758df55690abd6f8f99d43694a74a12
diff --git a/src/tvtimeconf.c b/src/tvtimeconf.c
index b423b88ecce4..a634f551495b 100644
--- a/src/tvtimeconf.c
+++ b/src/tvtimeconf.c
@@ -51,6 +51,12 @@
 #define MAX_KEYSYMS 350
 #define MAX_BUTTONS 15
 
+#ifdef __linux__ /* This depends on sysfs, so it is linux only */
+#define DEFAULT_VIDEO_DEV "auto"
+#else
+#define DEFAULT_VIDEO_DEV "/dev/video0"
+#endif
+
 struct config_s
 {
     char *geometry;
@@ -616,7 +622,7 @@ static void print_usage( char **argv )
     lfputs( _("  -A, --nowidescreen         4:3 mode.\n"), stderr );
     lfputs( _("  -b, --vbidevice=DEVICE     VBI device (defaults to 
/dev/vbi0).\n"), stderr );
     lfputs( _("  -c, --channel=CHANNEL      Tune to the specified channel on 
startup.\n"), stderr );
-    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to 
/dev/video0).\n"), stderr );
+    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to " 
DEFAULT_VIDEO_DEV ").\n"), stderr );
     lfputs( _("  -f, --frequencies=NAME     The frequency table to use for the 
tuner.\n"
               "                             (defaults to us-cable).\n\n"
               "                             Valid values are:\n"
@@ -671,7 +677,7 @@ static void print_config_usage( char **argv )
     lfputs( _("  -A, --nowidescreen         4:3 mode.\n"), stderr );
     lfputs( _("  -b, --vbidevice=DEVICE     VBI device (defaults to 
/dev/vbi0).\n"), stderr );
     lfputs( _("  -c, --channel=CHANNEL      Tune to the specified channel on 
startup.\n"), stderr );
-    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to 
/dev/video0).\n"), stderr );
+    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to " 
DEFAULT_VIDEO_DEV ").\n"), stderr );
     lfputs( _("  -f, --frequencies=NAME     The frequency table to use for the 
tuner.\n"
               "                             (defaults to us-cable).\n\n"
               "                             Valid values are:\n"
@@ -727,7 +733,7 @@ static void print_config_usage( char **argv )
 static void print_scanner_usage( char **argv )
 {
     lfprintf( stderr, _("usage: %s [OPTION]...\n\n"), argv[ 0 ]);
-    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to 
/dev/video0).\n"), stderr );
+    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to " 
DEFAULT_VIDEO_DEV ").\n"), stderr );
     lfputs( _("  -F, --configfile=FILE      Additional config file to load 
settings from.\n"), stderr );
     lfputs( _("  -h, --help                 Show this help message.\n"), 
stderr );
     lfputs( _("  -i, --input=INPUTNUM       video4linux input number (defaults 
to 0).\n"), stderr );
@@ -785,7 +791,7 @@ config_t *config_new( void )
 
     ct->inputwidth = 720;
     ct->inputnum = 0;
-    ct->v4ldev = strdup( "/dev/video0" );
+    ct->v4ldev = strdup( DEFAULT_VIDEO_DEV );
     ct->norm = strdup( "ntsc" );
     ct->freq = strdup( "us-cable" );
     temp_dirname = getenv( "HOME" );
diff --git a/src/videoinput.c b/src/videoinput.c
index 2650ac7285fb..f8939c07879e 100644
--- a/src/videoinput.c
+++ b/src/videoinput.c
@@ -19,6 +19,7 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -38,6 +39,7 @@
 #include <linux/videodev2.h>
 #include "videoinput.h"
 #include "mixer.h"
+#include "get_media_devices.h"
 
 /**
  * How long to wait when we lose a signal, or acquire a signal.
@@ -319,11 +321,59 @@ int videoinput_buffer_invalid( videoinput_t *vidin, int 
frameid )
     return vidin->capbuffers[ frameid ].free;
 }
 
+int videoinput_open_v4l_device( videoinput_t *vidin, const char *path,
+                               int caps, const char *type)
+{
+    struct v4l2_capability caps_v4l2;
+    int fd;
+
+    /* First, open the device. */
+    fd = open( path, O_RDWR );
+    if( fd == -1 ) {
+       fprintf( stderr, "videoinput: Cannot open device %s: %s\n",
+                path, strerror( errno ) );
+    }
+
+    /**
+     * Next, ask for its capabilities.  This will also confirm it's a V4L2
+     * device.
+     */
+    if( ioctl( fd, VIDIOC_QUERYCAP, &caps_v4l2 ) < 0 ) {
+       /* Can't get V4L2 capabilities, maybe this is a V4L1 device? */
+       fprintf( stderr, "videoinput: %s: V4L1 devices not supported\n", path );
+       close( fd );
+       return -1;
+    }
+
+    if( (caps_v4l2.capabilities & caps) != caps ) {
+       if( vidin->verbose ) {
+           fprintf( stderr, "videoinput: %s: does not have %s caps\n",
+                    path, type );
+       }
+       close( fd );
+       return -1;
+    }
+
+    if( vidin->verbose ) {
+       fprintf( stderr, "videoinput: Using video4linux2 driver '%s', card '%s' 
(bus %s).\n"
+                        "videoinput: Version is %u, capabilities %x.\n",
+                caps_v4l2.driver, caps_v4l2.card, caps_v4l2.bus_info,
+                caps_v4l2.version, caps_v4l2.capabilities );
+    }
+    vidin->isv4l2 = 1;
+    snprintf( vidin->drivername, sizeof( vidin->drivername ), "%s [%s/%s/%u]",
+             caps_v4l2.driver, caps_v4l2.card,
+             caps_v4l2.bus_info, caps_v4l2.version );
+    snprintf( vidin->shortdriver, sizeof( vidin->shortdriver ), "%s",
+             caps_v4l2.driver );
+
+    return fd;
+}
+
 videoinput_t *videoinput_new( config_t *cfg, int norm, int verbose,
                              char *error_string )
 {
     videoinput_t *vidin = malloc( sizeof( videoinput_t ) );
-    struct v4l2_capability caps_v4l2;
     struct v4l2_input in;
     int i;
 
@@ -379,44 +429,65 @@ videoinput_t *videoinput_new( config_t *cfg, int norm, 
int verbose,
     memset( vidin->drivername, 0, sizeof( vidin->drivername ) );
     memset( vidin->shortdriver, 0, sizeof( vidin->shortdriver ) );
 
-    /* First, open the device. */
-    vidin->grab_fd = open( v4l_device, O_RDWR );
-    if( vidin->grab_fd < 0 ) {
-        fprintf( stderr, "videoinput: Cannot open capture device %s: %s\n",
-                 v4l_device, strerror( errno ) );
-        sprintf( error_string, "%s", strerror( errno ) );
-        free( vidin );
-        return 0;
-    }
+    vidin->grab_fd = -1;
 
-    /**
-     * Next, ask for its capabilities.  This will also confirm it's a V4L2 
-     * device. 
-     */
-    if( ioctl( vidin->grab_fd, VIDIOC_QUERYCAP, &caps_v4l2 ) < 0 ) {
-        /* Can't get V4L2 capabilities, maybe this is a V4L1 device? */
-       fprintf(stderr, "V4L1 devices not supported\n");
-       sprintf( error_string, "V4L1 devices not supported" );
-       close( vidin->grab_fd );
+#ifdef __linux__ /* Because this depends on get_media_devices.c */
+    if( !strcmp( v4l_device, "auto") ) {
+       char path[PATH_MAX];
+       const char *type;
+       int caps;
+       void *md;
+
+       md = discover_media_devices();
+       if( !md ) {
+           sprintf( error_string, "Cannot enumerate video devices" );
+           free( vidin );
+           return 0;
+        }
+
+       /* Step 1: try TV cards first */
+       type = "analog TV";
+       caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER;
+retry:
+       v4l_device = NULL;
+       while( 1 ) {
+           v4l_device = get_associated_device( md, v4l_device, MEDIA_V4L_VIDEO,
+                                               NULL, NONE );
+           if( !v4l_device )
+               break; /* No more video devices to try */
+           snprintf( path, PATH_MAX, "/dev/%s", v4l_device );
+           if( verbose )
+               fprintf(stderr, "videoinput-auto: trying: %s... \n", path);
+           vidin->grab_fd = videoinput_open_v4l_device( vidin, path, caps,
+                                                        type );
+           if( vidin->grab_fd != -1 ) {
+               fprintf( stderr, "videoinput-auto: using %s device %s\n",
+                        type, path);
+               break;
+           }
+       }
+
+       /* Step 2: try grabber devices and webcams */
+       if( vidin->grab_fd == -1 &&
+               caps == (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER) ) {
+           type = "capture";
+           caps = V4L2_CAP_VIDEO_CAPTURE;
+           goto retry;
+       }
+
+       free_media_devices(md);
+    } else
+#endif
+       vidin->grab_fd = videoinput_open_v4l_device( vidin, v4l_device,
+                                                    V4L2_CAP_VIDEO_CAPTURE,
+                                                    "capture" );
+
+    if( vidin->grab_fd == -1 ) {
+       sprintf( error_string, "Cannot open/use video device %s", v4l_device );
        free( vidin );
        return 0;
-    } else {
-        if( vidin->verbose ) {
-            fprintf( stderr, "videoinput: Using video4linux2 driver '%s', card 
'%s' (bus %s).\n"
-                             "videoinput: Version is %u, capabilities %x.\n",
-                     caps_v4l2.driver, caps_v4l2.card, caps_v4l2.bus_info,
-                     caps_v4l2.version, caps_v4l2.capabilities );
-        }
-        vidin->isv4l2 = 1;
-        snprintf( vidin->drivername, sizeof( vidin->drivername ),
-                  "%s [%s/%s/%u]",
-                  caps_v4l2.driver, caps_v4l2.card,
-                  caps_v4l2.bus_info, caps_v4l2.version );
-        snprintf( vidin->shortdriver, sizeof( vidin->shortdriver ),
-                  "%s", caps_v4l2.driver );
     }
 
-
     vidin->numinputs = 0;
     in.index = vidin->numinputs;
 

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to