v4l/libv4l: allow opening device by name

- Allows using non-default device names such as /dev/v4l/by-path/pci-0000:00:1d.0-usb-0:1.1:1.0-video-index0
This commit is contained in:
Dustin Spicuzza 2016-04-12 01:00:37 -04:00
parent 92387b1ef8
commit e489f29d0f
4 changed files with 81 additions and 34 deletions

View File

@ -292,6 +292,11 @@ CV_IMPL CvCapture * cvCreateFileCaptureWithPreference (const char * filename, in
result = cvCreateFileCapture_VFW (filename);
if (apiPreference) break;
#endif
#if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
if (!result)
result = cvCreateCameraCapture_V4L(filename);
if (apiPreference) break;
#endif
case CV_CAP_MSMF:
#ifdef HAVE_MSMF

View File

@ -350,6 +350,7 @@ typedef struct CvCaptureCAM_V4L
}
CvCaptureCAM_V4L;
static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (const char* deviceName);
static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture );
static int icvGrabFrameCAM_V4L( CvCaptureCAM_V4L* capture );
@ -416,7 +417,7 @@ static void icvInitCapture_V4L() {
}; /* End icvInitCapture_V4L */
static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
static int try_init_v4l(CvCaptureCAM_V4L* capture, const char *deviceName)
{
@ -460,7 +461,7 @@ static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
}
static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName)
static int try_init_v4l2(CvCaptureCAM_V4L* capture, const char *deviceName)
{
// if detect = -1 then unable to open device
@ -662,7 +663,7 @@ static inline int channels_for_mode(int mode)
}
}
static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName)
static int _capture_V4L2 (CvCaptureCAM_V4L *capture, const char *deviceName)
{
int detect_v4l2 = 0;
@ -870,7 +871,7 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName)
}; /* End _capture_V4L2 */
static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName)
static int _capture_V4L (CvCaptureCAM_V4L *capture, const char *deviceName)
{
int detect_v4l = 0;
@ -1041,17 +1042,6 @@ static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index)
fprintf( stderr, "VIDEOIO ERROR: V4L: index %d is not correct!\n",index);
return NULL; /* Did someone ask for not correct video source number? */
}
/* Allocate memory for this humongus CvCaptureCAM_V4L structure that contains ALL
the handles for V4L processing */
CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L));
if (!capture) {
fprintf( stderr, "VIDEOIO ERROR: V4L: Could not allocate memory for capture process.\n");
return NULL;
}
#ifdef USE_TEMP_BUFFER
capture->buffers[MAX_V4L_BUFFERS].start = NULL;
#endif
/* Select camera, or rather, V4L video source */
if (index<0) { // Asking for the first device available
@ -1065,9 +1055,26 @@ static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index)
}
/* Print the CameraNumber at the end of the string with a width of one character */
sprintf(deviceName, "/dev/video%1d", index);
return icvCaptureFromCAM_V4L(deviceName);
}
static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (const char* deviceName)
{
/* Allocate memory for this humongus CvCaptureCAM_V4L structure that contains ALL
the handles for V4L processing */
CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L));
if (!capture) {
fprintf( stderr, "VIDEOIO ERROR: V4L: Could not allocate memory for capture process.\n");
return NULL;
}
#ifdef USE_TEMP_BUFFER
capture->buffers[MAX_V4L_BUFFERS].start = NULL;
#endif
/* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */
memset(capture,0,sizeof(CvCaptureCAM_V4L));
/* Present the routines needed for V4L funtionality. They are inserted as part of
the standard set of cv calls promoting transparency. "Vector Table" insertion. */
capture->FirstCapture = 1;
@ -1905,6 +1912,7 @@ public:
virtual ~CvCaptureCAM_V4L_CPP() { close(); }
virtual bool open( int index );
virtual bool open( const char* deviceName );
virtual void close();
virtual double getProperty(int) const;
@ -1923,6 +1931,13 @@ bool CvCaptureCAM_V4L_CPP::open( int index )
return captureV4L != 0;
}
bool CvCaptureCAM_V4L_CPP::open( const char* deviceName )
{
close();
captureV4L = icvCaptureFromCAM_V4L(deviceName);
return captureV4L != 0;
}
void CvCaptureCAM_V4L_CPP::close()
{
if( captureV4L )
@ -1963,4 +1978,15 @@ CvCapture* cvCreateCameraCapture_V4L( int index )
return 0;
}
CvCapture* cvCreateCameraCapture_V4L( const char * deviceName )
{
CvCaptureCAM_V4L_CPP* capture = new CvCaptureCAM_V4L_CPP;
if( capture->open( deviceName ))
return (CvCapture*)capture;
delete capture;
return 0;
}
#endif

View File

@ -270,12 +270,12 @@ struct CvCaptureCAM_V4L : public CvCapture
int deviceHandle;
int bufferIndex;
int FirstCapture;
String deviceName;
char *memoryMap;
IplImage frame;
__u32 palette;
int index;
int width, height;
__u32 fps;
bool convert_rgb;
@ -298,6 +298,7 @@ struct CvCaptureCAM_V4L : public CvCapture
Range focus, brightness, contrast, saturation, hue, gain, exposure;
bool open(int _index);
bool open(const char* deviceName);
virtual double getProperty(int) const;
virtual bool setProperty(int, double);
@ -392,7 +393,7 @@ static bool try_palette_v4l2(CvCaptureCAM_V4L* capture)
return capture->palette == capture->form.fmt.pix.pixelformat;
}
static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName)
static int try_init_v4l2(CvCaptureCAM_V4L* capture, const char *deviceName)
{
// Test device for V4L2 compability
// Return value:
@ -600,10 +601,7 @@ static void v4l2_create_frame(CvCaptureCAM_V4L *capture) {
static int _capture_V4L2 (CvCaptureCAM_V4L *capture)
{
char deviceName[MAX_DEVICE_DRIVER_NAME];
/* Print the CameraNumber at the end of the string with a width of one character */
sprintf(deviceName, "/dev/video%1d", capture->index);
const char* deviceName = capture->deviceName.c_str();
if (try_init_v4l2(capture, deviceName) != 1) {
/* init of the v4l2 device is not OK */
return -1;
@ -761,17 +759,16 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture)
* this also causes buffers to be reallocated if the frame size was changed.
*/
static bool v4l2_reset( CvCaptureCAM_V4L* capture) {
int index = capture->index;
String deviceName = capture->deviceName;
icvCloseCAM_V4L(capture);
capture->index = index;
capture->deviceName = deviceName;
return _capture_V4L2(capture) == 1;
}
bool CvCaptureCAM_V4L::open(int _index)
{
int autoindex = 0;
index = -1; // set the capture to closed state
char _deviceName[MAX_DEVICE_DRIVER_NAME];
if (!numCameras)
icvInitCapture_V4L(); /* Havent called icvInitCapture yet - do it now! */
@ -796,14 +793,21 @@ bool CvCaptureCAM_V4L::open(int _index)
autoindex++;// i can recall icvOpenCAM_V4l with index=-1 for next camera
}
index = _index;
FirstCapture = 1;
width = DEFAULT_V4L_WIDTH;
height = DEFAULT_V4L_HEIGHT;
fps = DEFAULT_V4L_FPS;
convert_rgb = true;
/* Print the CameraNumber at the end of the string with a width of one character */
sprintf(_deviceName, "/dev/video%1d", _index);
return open(_deviceName);
}
return _capture_V4L2(this) == 1;
bool CvCaptureCAM_V4L::open(const char* _deviceName)
{
FirstCapture = 1;
width = DEFAULT_V4L_WIDTH;
height = DEFAULT_V4L_HEIGHT;
fps = DEFAULT_V4L_FPS;
convert_rgb = true;
deviceName = _deviceName;
return _capture_V4L2(this) == 1;
}
static int read_frame_v4l2(CvCaptureCAM_V4L* capture) {
@ -1753,7 +1757,7 @@ static int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture,
static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){
/* Deallocate space - Hopefully, no leaks */
if (capture->index > -1)
if (!capture->deviceName.empty())
{
if (capture->deviceHandle != -1)
{
@ -1782,7 +1786,7 @@ static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){
if (capture->frame.imageData)
cvFree(&capture->frame.imageData);
capture->index = -1; // flag that the capture is closed
capture->deviceName.clear(); // flag that the capture is closed
}
};
@ -1819,4 +1823,15 @@ CvCapture* cvCreateCameraCapture_V4L( int index )
return NULL;
}
CvCapture* cvCreateCameraCapture_V4L( const char * deviceName )
{
cv::CvCaptureCAM_V4L* capture = new cv::CvCaptureCAM_V4L();
if(capture->open( deviceName ))
return capture;
delete capture;
return NULL;
}
#endif

View File

@ -102,6 +102,7 @@ struct CvVideoWriter
};
CvCapture * cvCreateCameraCapture_V4L( int index );
CvCapture * cvCreateCameraCapture_V4L( const char* deviceName );
CvCapture * cvCreateCameraCapture_DC1394( int index );
CvCapture * cvCreateCameraCapture_DC1394_2( int index );
CvCapture* cvCreateCameraCapture_MIL( int index );