diff --git a/modules/videoio/include/opencv2/videoio.hpp b/modules/videoio/include/opencv2/videoio.hpp index 6daccc543..f37a8036c 100644 --- a/modules/videoio/include/opencv2/videoio.hpp +++ b/modules/videoio/include/opencv2/videoio.hpp @@ -90,7 +90,10 @@ enum { CAP_ANY = 0, // autodetect CAP_INTELPERC = 1500, // Intel Perceptual Computing SDK CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) CAP_OPENNI2_ASUS = 1610, // OpenNI2 (for Asus Xtion and Occipital Structure sensors) - CAP_GPHOTO2 = 1700 // gPhoto2 connection + CAP_GPHOTO2 = 1700, // gPhoto2 connection + CAP_GSTREAMER = 1800, // GStreamer + CAP_FFMPEG = 1900, // FFMPEG + CAP_IMAGES = 2000 // OpenCV Image Sequence (e.g. img_%02d.jpg) }; // generic properties (based on DC1394 properties) @@ -398,10 +401,19 @@ public: CV_WRAP VideoCapture(const String& filename); /** @overload - @param device id of the opened video capturing device (i.e. a camera index). If there is a single - camera connected, just pass 0. + @param filename name of the opened video file (eg. video.avi) or image sequence (eg. + img_%02d.jpg, which will read samples like img_00.jpg, img_01.jpg, img_02.jpg, ...) + + @param apiPreference preferred Capture API to use. Can be used to enforce a specific reader + implementation if multiple are available: e.g. CAP_FFMPEG or CAP_IMAGES */ - CV_WRAP VideoCapture(int device); + CV_WRAP VideoCapture(const String& filename, int apiPreference); + + /** @overload + @param index = camera_id + domain_offset (CAP_*). id of the video capturing device to open. If there is a single + camera connected, just pass 0. Advanced Usage: to open Camera 1 using the MS Media Foundation API: index = 1 + CAP_MSMF + */ + CV_WRAP VideoCapture(int index); virtual ~VideoCapture(); @@ -415,9 +427,10 @@ public: CV_WRAP virtual bool open(const String& filename); /** @overload - @param device id of the opened video capturing device (i.e. a camera index). + @param index = camera_id + domain_offset (CAP_*). id of the video capturing device to open. If there is a single + camera connected, just pass 0. Advanced Usage: to open Camera 1 using the MS Media Foundation API: index = 1 + CAP_MSMF */ - CV_WRAP virtual bool open(int device); + CV_WRAP virtual bool open(int index); /** @brief Returns true if video capturing has been initialized already. @@ -541,6 +554,18 @@ public: */ CV_WRAP virtual double get(int propId) const; + /** @overload + + @param filename name of the opened video file (eg. video.avi) or image sequence (eg. + img_%02d.jpg, which will read samples like img_00.jpg, img_01.jpg, img_02.jpg, ...) + + @param apiPreference preferred Capture API to use. Can be used to enforce a specific reader + implementation if multiple are available: e.g. CAP_FFMPEG or CAP_IMAGES + + The methods first call VideoCapture::release to close the already opened file or camera. + */ + CV_WRAP virtual bool open(const String& filename, int apiPreference); + protected: Ptr cap; Ptr icap; diff --git a/modules/videoio/include/opencv2/videoio/videoio_c.h b/modules/videoio/include/opencv2/videoio/videoio_c.h index b8973850c..0365b9223 100644 --- a/modules/videoio/include/opencv2/videoio/videoio_c.h +++ b/modules/videoio/include/opencv2/videoio/videoio_c.h @@ -63,6 +63,9 @@ typedef struct CvCapture CvCapture; /* start capturing frames from video file */ CVAPI(CvCapture*) cvCreateFileCapture( const char* filename ); +/* start capturing frames from video file. allows specifying a preferred API to use */ +CVAPI(CvCapture*) cvCreateFileCaptureWithPreference( const char* filename , int apiPreference); + enum { CV_CAP_ANY =0, // autodetect @@ -111,8 +114,10 @@ enum CV_CAP_INTELPERC = 1500, // Intel Perceptual Computing CV_CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) - - CV_CAP_GPHOTO2 = 1700 + CV_CAP_GPHOTO2 = 1700, + CV_CAP_GSTREAMER = 1800, // GStreamer + CV_CAP_FFMPEG = 1900, // FFMPEG + CV_CAP_IMAGES = 2000 // OpenCV Image Sequence (e.g. img_%02d.jpg) }; /* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */ diff --git a/modules/videoio/src/cap.cpp b/modules/videoio/src/cap.cpp index f2b5a4a30..d2da6edfe 100644 --- a/modules/videoio/src/cap.cpp +++ b/modules/videoio/src/cap.cpp @@ -126,289 +126,221 @@ CV_IMPL int cvGetCaptureDomain( CvCapture* capture) */ CV_IMPL CvCapture * cvCreateCameraCapture (int index) { - int domains[] = - { -#ifdef HAVE_MSMF - CV_CAP_MSMF, -#endif -#if 1 - CV_CAP_IEEE1394, // identical to CV_CAP_DC1394 -#endif -#ifdef HAVE_TYZX - CV_CAP_STEREO, -#endif -#ifdef HAVE_PVAPI - CV_CAP_PVAPI, -#endif -#if 1 - CV_CAP_VFW, // identical to CV_CAP_V4L -#endif -#ifdef HAVE_MIL - CV_CAP_MIL, -#endif -#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) - CV_CAP_QT, -#endif -#ifdef HAVE_UNICAP - CV_CAP_UNICAP, -#endif -#ifdef HAVE_OPENNI - CV_CAP_OPENNI, -#endif -#ifdef HAVE_OPENNI2 - CV_CAP_OPENNI2, -#endif -#ifdef HAVE_XIMEA - CV_CAP_XIAPI, -#endif -#ifdef HAVE_AVFOUNDATION - CV_CAP_AVFOUNDATION, -#endif -#ifdef HAVE_GIGE_API - CV_CAP_GIGANETIX, -#endif -#ifdef HAVE_INTELPERC - CV_CAP_INTELPERC, -#endif - -1 - }; - // interpret preferred interface (0 = autodetect) int pref = (index / 100) * 100; - if (pref) - { - domains[0]=pref; - index %= 100; - domains[1]=-1; - } - // try every possibly installed camera API - for (int i = 0; domains[i] >= 0; i++) - { -#if defined(HAVE_MSMF) || \ - defined(HAVE_TYZX) || \ - defined(HAVE_VFW) || \ - defined(HAVE_LIBV4L) || \ - defined(HAVE_CAMV4L) || \ - defined(HAVE_CAMV4L2) || \ - defined(HAVE_VIDEOIO) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_DC1394_2) || \ - defined(HAVE_DC1394) || \ - defined(HAVE_CMU1394) || \ - defined(HAVE_MIL) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_UNICAP) || \ - defined(HAVE_PVAPI) || \ - defined(HAVE_OPENNI) || \ - defined(HAVE_OPENNI2) || \ - defined(HAVE_XIMEA) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_GIGE_API) || \ - defined(HAVE_INTELPERC) || \ - (0) - // local variable to memorize the captured device - CvCapture *capture; -#endif + // local variable to memorize the captured device + CvCapture *capture = 0; + + switch (pref) + { + default: + // user specified an API we do not know + // bail out to let the user know that it is not available + if (pref) break; - switch (domains[i]) - { #ifdef HAVE_MSMF - case CV_CAP_MSMF: - capture = cvCreateCameraCapture_MSMF (index); - if (capture) - return capture; - break; + case CV_CAP_MSMF: + if (!capture) + capture = cvCreateCameraCapture_MSMF(index); + if (pref) break; #endif #ifdef HAVE_TYZX - case CV_CAP_STEREO: - capture = cvCreateCameraCapture_TYZX (index); - if (capture) - return capture; - break; + case CV_CAP_STEREO: + if (!capture) + capture = cvCreateCameraCapture_TYZX(index); + if (pref) break; #endif - case CV_CAP_VFW: + case CV_CAP_VFW: #ifdef HAVE_VFW - capture = cvCreateCameraCapture_VFW (index); - if (capture) - return capture; + if (!capture) + capture = cvCreateCameraCapture_VFW(index); #endif #if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO - capture = cvCreateCameraCapture_V4L (index); - if (capture) - return capture; + if (!capture) + capture = cvCreateCameraCapture_V4L(index); #endif #ifdef HAVE_GSTREAMER + if (!capture) capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, 0); - if (capture) - return capture; - capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, 0); - if (capture) - return capture; -#endif - break; //CV_CAP_VFW - case CV_CAP_FIREWIRE: + if (!capture) + capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, 0); +#endif + if (pref) break; // CV_CAP_VFW + + case CV_CAP_FIREWIRE: #ifdef HAVE_DC1394_2 - capture = cvCreateCameraCapture_DC1394_2 (index); - if (capture) - return capture; + if (!capture) + capture = cvCreateCameraCapture_DC1394_2(index); #endif #ifdef HAVE_DC1394 - capture = cvCreateCameraCapture_DC1394 (index); - if (capture) - return capture; + if (!capture) + capture = cvCreateCameraCapture_DC1394(index); #endif #ifdef HAVE_CMU1394 - capture = cvCreateCameraCapture_CMU (index); - if (capture) - return capture; + if (!capture) + capture = cvCreateCameraCapture_CMU(index); #endif #if defined(HAVE_GSTREAMER) && 0 - //Re-enable again when gstreamer 1394 support will land in the backend code + // Re-enable again when gstreamer 1394 support will land in the backend code + if (!capture) capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0); - if (capture) - return capture; #endif - break; //CV_CAP_FIREWIRE + if (pref) break; // CV_CAP_FIREWIRE #ifdef HAVE_MIL - case CV_CAP_MIL: - capture = cvCreateCameraCapture_MIL (index); - if (capture) - return capture; - break; + case CV_CAP_MIL: + if (!capture) + capture = cvCreateCameraCapture_MIL(index); + if (pref) break; #endif #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) - case CV_CAP_QT: - capture = cvCreateCameraCapture_QT (index); - if (capture) - return capture; - break; + case CV_CAP_QT: + if (!capture) + capture = cvCreateCameraCapture_QT(index); + if (pref) break; #endif #ifdef HAVE_UNICAP - case CV_CAP_UNICAP: - capture = cvCreateCameraCapture_Unicap (index); - if (capture) - return capture; - break; + case CV_CAP_UNICAP: + if (!capture) + capture = cvCreateCameraCapture_Unicap(index); + if (pref) break; #endif #ifdef HAVE_PVAPI - case CV_CAP_PVAPI: - capture = cvCreateCameraCapture_PvAPI (index); - if (capture) - return capture; - break; + case CV_CAP_PVAPI: + if (!capture) + capture = cvCreateCameraCapture_PvAPI(index); + if (pref) break; #endif #ifdef HAVE_OPENNI - case CV_CAP_OPENNI: - capture = cvCreateCameraCapture_OpenNI (index); - if (capture) - return capture; - break; + case CV_CAP_OPENNI: + if (!capture) + capture = cvCreateCameraCapture_OpenNI(index); + if (pref) break; #endif #ifdef HAVE_OPENNI2 - case CV_CAP_OPENNI2: + case CV_CAP_OPENNI2: + if (!capture) capture = cvCreateCameraCapture_OpenNI(index); - if (capture) - return capture; - break; + if (pref) break; #endif #ifdef HAVE_XIMEA - case CV_CAP_XIAPI: - capture = cvCreateCameraCapture_XIMEA (index); - if (capture) - return capture; - break; + case CV_CAP_XIAPI: + if (!capture) + capture = cvCreateCameraCapture_XIMEA(index); + if (pref) break; #endif #ifdef HAVE_AVFOUNDATION - case CV_CAP_AVFOUNDATION: - capture = cvCreateCameraCapture_AVFoundation (index); - if (capture) - return capture; - break; + case CV_CAP_AVFOUNDATION: + if (!capture) + capture = cvCreateCameraCapture_AVFoundation(index); + if (pref) break; #endif #ifdef HAVE_GIGE_API - case CV_CAP_GIGANETIX: - capture = cvCreateCameraCapture_Giganetix (index); - if (capture) - return capture; - break; // CV_CAP_GIGANETIX + case CV_CAP_GIGANETIX: + if (!capture) + capture = cvCreateCameraCapture_Giganetix(index); + if (pref) break; // CV_CAP_GIGANETIX #endif - } } - // failed open a camera - return 0; + return capture; } /** * Videoreader dispatching method: it tries to find the first * API that can access a given filename. */ -CV_IMPL CvCapture * cvCreateFileCapture (const char * filename) +CV_IMPL CvCapture * cvCreateFileCaptureWithPreference (const char * filename, int apiPreference) { CvCapture * result = 0; + switch(apiPreference) { + default: + // user specified an API we do not know + // bail out to let the user know that it is not available + if (apiPreference) break; + #ifdef HAVE_FFMPEG - if (! result) - result = cvCreateFileCapture_FFMPEG_proxy (filename); + case CV_CAP_FFMPEG: + if (! result) + result = cvCreateFileCapture_FFMPEG_proxy (filename); + if (apiPreference) break; #endif #ifdef HAVE_VFW - if (! result) - result = cvCreateFileCapture_VFW (filename); + case CV_CAP_VFW: + if (! result) + result = cvCreateFileCapture_VFW (filename); + if (apiPreference) break; #endif + case CV_CAP_MSMF: #ifdef HAVE_MSMF - if (! result) - result = cvCreateFileCapture_MSMF (filename); + if (! result) + result = cvCreateFileCapture_MSMF (filename); #endif #ifdef HAVE_XINE - if (! result) - result = cvCreateFileCapture_XINE (filename); + if (! result) + result = cvCreateFileCapture_XINE (filename); #endif + if (apiPreference) break; #ifdef HAVE_GSTREAMER - if (! result) - result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename); + case CV_CAP_GSTREAMER: + if (! result) + result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename); + if (apiPreference) break; #endif #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) - if (! result) - result = cvCreateFileCapture_QT (filename); + case CV_CAP_QT: + if (! result) + result = cvCreateFileCapture_QT (filename); + if (apiPreference) break; #endif #ifdef HAVE_AVFOUNDATION - if (! result) - result = cvCreateFileCapture_AVFoundation (filename); + case CV_CAP_AVFOUNDATION: + if (! result) + result = cvCreateFileCapture_AVFoundation (filename); + if (apiPreference) break; #endif #ifdef HAVE_OPENNI - if (! result) - result = cvCreateFileCapture_OpenNI (filename); + case CV_CAP_OPENNI: + if (! result) + result = cvCreateFileCapture_OpenNI (filename); + if (apiPreference) break; #endif - if (! result) - result = cvCreateFileCapture_Images (filename); + case CV_CAP_IMAGES: + if (! result) + result = cvCreateFileCapture_Images (filename); + } return result; } +CV_IMPL CvCapture * cvCreateFileCapture (const char * filename) +{ + return cvCreateFileCaptureWithPreference(filename, CV_CAP_ANY); +} + /** * Videowriter dispatching method: it tries to find the first * API that can write a given stream. @@ -615,14 +547,19 @@ static Ptr IVideoWriter_create(const String& filename, int _fourcc VideoCapture::VideoCapture() {} -VideoCapture::VideoCapture(const String& filename) +VideoCapture::VideoCapture(const String& filename, int apiPreference) { - open(filename); + open(filename, apiPreference); } -VideoCapture::VideoCapture(int device) +VideoCapture::VideoCapture(const String& filename) { - open(device); + open(filename, CAP_ANY); +} + +VideoCapture::VideoCapture(int index) +{ + open(index); } VideoCapture::~VideoCapture() @@ -631,24 +568,29 @@ VideoCapture::~VideoCapture() cap.release(); } -bool VideoCapture::open(const String& filename) +bool VideoCapture::open(const String& filename, int apiPreference) { if (isOpened()) release(); icap = IVideoCapture_create(filename); if (!icap.empty()) return true; - cap.reset(cvCreateFileCapture(filename.c_str())); + cap.reset(cvCreateFileCaptureWithPreference(filename.c_str(), apiPreference)); return isOpened(); } -bool VideoCapture::open(int device) +bool VideoCapture::open(const String& filename) +{ + return open(filename, CAP_ANY); +} + +bool VideoCapture::open(int index) { if (isOpened()) release(); - icap = IVideoCapture_create(device); + icap = IVideoCapture_create(index); if (!icap.empty()) return true; - cap.reset(cvCreateCameraCapture(device)); + cap.reset(cvCreateCameraCapture(index)); return isOpened(); }