core/vidl/vidl_v4l2_devices.cxx
Go to the documentation of this file.
00001 // This is core/vidl/vidl_v4l2_devices.cxx
00002 #include "vidl_v4l2_devices.h"
00003 //:
00004 // \file
00005 //
00006 // \author Antonio Garrido
00007 // \verbatim
00008 //  Modifications
00009 //   15 Apr 2008 Created (A. Garrido)
00010 //\endverbatim
00011 
00012 extern "C" { // revisar los .h
00013 
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 #include <unistd.h>
00017 #include <dirent.h>
00018 };
00019 
00020 #include <vcl_cstdio.h> // for std::perror()
00021 #include <vcl_cstring.h>
00022 #include <vcl_iostream.h>
00023 #include "vidl_pixel_format.h"
00024 
00025 
00026 // ----------------- local functions ---------------
00027 namespace
00028 {
00029   inline bool is_directory(const char *dir)
00030   {
00031     struct stat s;
00032     return lstat(dir, &s) == 0 && S_ISDIR(s.st_mode);
00033   }
00034   inline bool is_video_device(const char *file)
00035   {
00036     struct stat s;
00037     bool isvd=(lstat(file, &s) == 0 &&
00038                S_ISCHR(s.st_mode) && // is character device
00039                ((int)((unsigned short)(s.st_rdev)>> 8) == 81) && // major number 81
00040                ((int)((unsigned short)(s.st_rdev) & 0xC0) ==0)   // minor in [0,63]
00041            );
00042 #if 0
00043     vcl_cout << file << ": ";
00044     if (lstat(file, &s) == 0) vcl_cout << "lstat ok, ";
00045     if (S_ISCHR(s.st_mode)) vcl_cout << "ISCHR ok, ";
00046     vcl_cout <<  "rdev:" << (s.st_rdev)<< "Major: "<< ((unsigned short)(s.st_rdev)>> 8);
00047     if ((int)((unsigned short)(s.st_rdev)>> 8) == 81) vcl_cout <<" major number 81, ";
00048     if ((int)((unsigned short)(s.st_rdev) & 0xFF) >=0) vcl_cout << " minor >0, ";
00049     if ((int)((unsigned short)(s.st_rdev) & 0xFF) <=63) vcl_cout << " minor <64.";
00050     if (isvd) vcl_cout << " Is video device"; else vcl_cout << " discarded";
00051     vcl_cout << vcl_endl;
00052 #endif // 0
00053     return isvd;
00054   }
00055 }
00056 // --------------- end local functions --------------------
00057 
00058 
00059 vidl_v4l2_devices& vidl_v4l2_devices::all()
00060 {
00061   static vidl_v4l2_devices instance;
00062   return instance;
00063 }
00064 
00065 
00066 void vidl_v4l2_devices::load_devices(const char *dirname)
00067 {
00068   //vcl_cerr << "Directory: " << dirname << vcl_endl;
00069   DIR *dp;
00070   struct dirent *ep;
00071   dp = opendir(dirname);
00072   char filename[200];
00073   if (dp != NULL)
00074   {
00075     while ((ep = readdir(dp))) {
00076       vcl_strcpy(filename,dirname);
00077       vcl_strcat(filename,"/");
00078       vcl_strcat(filename,ep->d_name);
00079       if (is_directory(filename) && ep->d_name[0]!='.')
00080         load_devices(filename);
00081       else  if (is_video_device(filename)) {
00082         //vcl_cerr<< filename << "  is video device\n";
00083         vidl_v4l2_device_sptr aux= new vidl_v4l2_device(filename);
00084         //vecdev.push_back(aux);
00085         if (aux->n_inputs()>0) vecdev.push_back(aux);
00086         else vcl_cerr << "No inputs in device " << filename << vcl_endl;
00087       }
00088       //else puts("  is not video device");
00089     }
00090     closedir(dp);
00091   }
00092   else
00093     vcl_perror("Couldn't open the directory");
00094 }
00095 
00096 
00097 vidl_v4l2_devices::vidl_v4l2_devices()
00098 {
00099   // /sys/class/video4linux kernel 2.6?
00100   // /proc/video/dev kernel 2.4?
00101   // /dev/video0 to /dev/video63 (conventionally) v4l2 specification
00102   const char *dir;
00103   //if (!is_directory(dir="/sys/class/video4linux"))// kernel 2.6
00104   //if (!is_directory(dir="/proc/video/dev")) // kernel 2.4
00105   if (!is_directory(dir= "/dev")) // v4l2 specification
00106     return;
00107 
00108   load_devices(dir);
00109 }
00110