/** @brief Returns list of available backends which works via `cv::VideoWriter()` */
CV_EXPORTS_W std::vector<VideoCaptureAPIs> getWriterBackends();
-enum Capability
-{
- Read,
- Write,
- ReadWrite
-};
-
+ /** @brief Returns true if backend is available */
-CV_EXPORTS bool hasBackend(VideoCaptureAPIs api, Capability cap = ReadWrite);
++CV_EXPORTS bool hasBackend(VideoCaptureAPIs api);
+
//! @}
}} // namespace
namespace cv {
++static bool param_VIDEOIO_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOIO_DEBUG", false);
++static bool param_VIDEOCAPTURE_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOCAPTURE_DEBUG", false);
++static bool param_VIDEOWRITER_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOWRITER_DEBUG", false);
++
++
void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCapture(&obj); }
void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
if (isOpened()) release();
- const std::vector<VideoCaptureAPIs> backends = cv::videoio_registry::getStreamBackends();
+ const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByFilename();
for (size_t i = 0; i < backends.size(); i++)
{
- const VideoCaptureAPIs id = backends[i];
- const std::string backendName = cv::videoio_registry::getBackendName(id);
- if (apiPreference == CAP_ANY || apiPreference == id)
+ const VideoBackendInfo& info = backends[i];
+ if (apiPreference == CAP_ANY || apiPreference == info.id)
{
- CvCapture* capture = NULL;
- VideoCapture_create(capture, icap, info.id, filename);
- Ptr<IBackend> factory = VideoBackendRegistry::getInstance().getBackend(id);
- if (factory)
- icap = factory->tryOpenCapture(backendName, filename, 0);
-- if (!icap.empty())
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying capture filename='%s' ...", info.name, filename.c_str()));
++ CV_Assert(!info.backendFactory.empty());
++ const Ptr<IBackend> backend = info.backendFactory->getBackend();
++ if (!backend.empty())
+ {
- if (icap->isOpened())
- return true;
- icap.release();
++ try
++ {
++ icap = backend->createCapture(filename);
++ if (!icap.empty())
++ {
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): created, isOpened=%d",
++ info.name, icap->isOpened()));
++ if (icap->isOpened())
++ return true;
++ icap.release();
++ }
++ else
++ {
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name));
++ }
++ } catch(const cv::Exception& e) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
++ } catch (const std::exception& e) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
++ } catch(...) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
++ }
+ }
- if (capture)
++ else
{
- cap.reset(capture);
- // assume it is opened
- return true;
- if (icap->isOpened())
- return true;
- icap.release();
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): backend is not available (plugin is missing, or can't be loaded due dependencies or it is not compatible)", info.name));
}
}
}
}
}
- const std::vector<VideoCaptureAPIs> backends = cv::videoio_registry::getCameraBackends();
+ const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByIndex();
for (size_t i = 0; i < backends.size(); i++)
{
- const VideoCaptureAPIs id = backends[i];
- const std::string backendName = cv::videoio_registry::getBackendName(id);
- if (apiPreference == CAP_ANY || apiPreference == id)
+ const VideoBackendInfo& info = backends[i];
+ if (apiPreference == CAP_ANY || apiPreference == info.id)
{
- CvCapture* capture = NULL;
- VideoCapture_create(capture, icap, info.id, cameraNum);
- Ptr<IBackend> factory = VideoBackendRegistry::getInstance().getBackend(id);
- if (factory)
- icap = factory->tryOpenCapture(backendName, std::string(), cameraNum);
-- if (!icap.empty())
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying capture cameraNum=%d ...", info.name, cameraNum));
++ CV_Assert(!info.backendFactory.empty());
++ const Ptr<IBackend> backend = info.backendFactory->getBackend();
++ if (!backend.empty())
{
-- if (icap->isOpened())
-- return true;
-- icap.release();
++ try
++ {
++ icap = backend->createCapture(cameraNum);
++ if (!icap.empty())
++ {
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): created, isOpened=%d",
++ info.name, icap->isOpened()));
++ if (icap->isOpened())
++ return true;
++ icap.release();
++ }
++ else
++ {
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name));
++ }
++ } catch(const cv::Exception& e) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
++ } catch (const std::exception& e) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
++ } catch(...) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
++ }
+ }
- if (capture)
++ else
+ {
- cap.reset(capture);
- // assume it is opened
- return true;
++ if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): backend is not available (plugin is missing, or can't be loaded due dependencies or it is not compatible)", info.name));
}
}
}
if (isOpened()) release();
- const std::vector<VideoCaptureAPIs> backends = cv::videoio_registry::getWriterBackends();
+ const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_Writer();
for (size_t i = 0; i < backends.size(); i++)
{
- const VideoCaptureAPIs id = backends[i];
- const std::string backendName = cv::videoio_registry::getBackendName(id);
- if (apiPreference == CAP_ANY || apiPreference == id)
+ const VideoBackendInfo& info = backends[i];
+ if (apiPreference == CAP_ANY || apiPreference == info.id)
{
- CvVideoWriter* writer_ = NULL;
- VideoWriter_create(writer_, iwriter, info.id, filename, _fourcc, fps, frameSize, isColor);
- Ptr<IBackend> factory = VideoBackendRegistry::getInstance().getBackend(id);
- if (factory)
- iwriter = factory->tryOpenWriter(backendName, filename, _fourcc, fps, frameSize, isColor);
-- if (!iwriter.empty())
++ if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying writer with filename='%s' fourcc=0x%08x fps=%g sz=%dx%d isColor=%d...",
++ info.name, filename.c_str(), (unsigned)_fourcc, fps, frameSize.width, frameSize.height, (int)isColor));
++ CV_Assert(!info.backendFactory.empty());
++ const Ptr<IBackend> backend = info.backendFactory->getBackend();
++ if (!backend.empty())
+ {
- if (iwriter->isOpened())
- return true;
- iwriter.release();
++ try
++ {
++ iwriter = backend->createWriter(filename, _fourcc, fps, frameSize, isColor);
++ if (!iwriter.empty())
++ {
++ if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): created, isOpened=%d",
++ info.name, iwriter->isOpened()));
++ if (iwriter->isOpened())
++ return true;
++ iwriter.release();
++ }
++ else
++ {
++ if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create writer", info.name));
++ }
++ } catch(const cv::Exception& e) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
++ } catch (const std::exception& e) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
++ } catch(...) {
++ CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
++ }
+ }
- if (writer_)
++ else
{
- // assume it is opened
- writer.reset(writer_);
- return true;
- if (iwriter->isOpened())
- return true;
- iwriter.release();
++ if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
++ CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): backend is not available (plugin is missing, or can't be loaded due dependencies or it is not compatible)", info.name));
}
}
}
#pragma warning(disable: 4748)
#endif
-//=================================================================
-// Private interface
-//=================================================================
+using namespace cv;
+
- namespace cv
- {
-
- static bool param_VIDEOIO_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOIO_DEBUG", false);
- static bool param_VIDEOCAPTURE_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOCAPTURE_DEBUG", false);
- static bool param_VIDEOWRITER_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOWRITER_DEBUG", false);
++namespace cv {
+
+namespace {
- #define DECLARE_BACKEND(cap, name, mode) { cap, (BackendMode)(mode), 1000, name }
-namespace cv
-{
+ #define DECLARE_DYNAMIC_BACKEND(cap, name, mode) \
+ { \
- cap, (BackendMode)(mode | MODE_DYNAMIC), 1000, name "_DYNAMIC", 0 \
++ cap, (BackendMode)(mode), 1000, name, createPluginBackendFactory(cap, name) \
+ }
+
-#define DECLARE_STATIC_BACKEND(cap, name, mode, f1, f2, f3) \
++#define DECLARE_STATIC_BACKEND(cap, name, mode, createCaptureFile, createCaptureCamera, createWriter) \
+ { \
- cap, (BackendMode)(mode), 1000, name, Ptr<StaticBackend>(new StaticBackend(f1, f2, f3)) \
++ cap, (BackendMode)(mode), 1000, name, createBackendFactory(createCaptureFile, createCaptureCamera, createWriter) \
+ }
/** Ordering guidelines:
- modern optimized, multi-platform libraries: ffmpeg, gstreamer, Media SDK
#endif
#ifdef HAVE_GPHOTO2
- DECLARE_BACKEND(CAP_GPHOTO2, "GPHOTO2", MODE_CAPTURE_ALL),
+ DECLARE_STATIC_BACKEND(CAP_GPHOTO2, "GPHOTO2", MODE_CAPTURE_ALL, createGPhoto2Capture, createGPhoto2Capture, 0),
#endif
#ifdef HAVE_XINE
- DECLARE_BACKEND(CAP_XINE, "XINE", MODE_CAPTURE_BY_FILENAME),
+ DECLARE_STATIC_BACKEND(CAP_XINE, "XINE", MODE_CAPTURE_BY_FILENAME, createXINECapture, 0, 0),
#endif
+
// dropped backends: MIL, TYZX, Android
};
for (size_t i = 0; i < backends.size(); i++)
result.push_back((VideoCaptureAPIs)backends[i].id);
return result;
-}
-std::vector<VideoCaptureAPIs> getBackends()
-{
- return toIDs(VideoBackendRegistry::getInstance().getBackends(MODE_CAPTURE_ALL + MODE_WRITER));
}
-std::vector<VideoCaptureAPIs> getCameraBackends()
+std::vector<VideoCaptureAPIs> getStreamBackends()
{
- return toIDs(VideoBackendRegistry::getInstance().getBackends(MODE_CAPTURE_BY_INDEX));
+ const std::vector<VideoBackendInfo> backends = VideoBackendRegistry::getInstance().getAvailableBackends_CaptureByFilename();
+ std::vector<VideoCaptureAPIs> result;
+ for (size_t i = 0; i < backends.size(); i++)
+ result.push_back((VideoCaptureAPIs)backends[i].id);
+ return result;
+
}
-std::vector<VideoCaptureAPIs> getStreamBackends()
+std::vector<VideoCaptureAPIs> getWriterBackends()
{
- return toIDs(VideoBackendRegistry::getInstance().getBackends(MODE_CAPTURE_BY_FILENAME));
+ const std::vector<VideoBackendInfo> backends = VideoBackendRegistry::getInstance().getAvailableBackends_Writer();
+ std::vector<VideoCaptureAPIs> result;
+ for (size_t i = 0; i < backends.size(); i++)
+ result.push_back((VideoCaptureAPIs)backends[i].id);
+ return result;
}
- } // namespace registry
-
- #define TRY_OPEN(backend_func) \
- { \
- try { \
- if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying ...\n", #backend_func)); \
- icap = backend_func; \
- if (param_VIDEOIO_DEBUG ||param_VIDEOCAPTURE_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): result=%p isOpened=%d ...\n", \
- #backend_func, icap.empty() ? NULL : icap.get(), icap.empty() ? -1: icap->isOpened())); \
- } catch(const cv::Exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", #backend_func, e.what())); \
- } catch (const std::exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", #backend_func, e.what())); \
- } catch(...) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", #backend_func)); \
- } \
- break; \
- }
-
- #define TRY_OPEN_LEGACY(backend_func) \
- { \
- try { \
- if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying ...\n", #backend_func)); \
- capture = backend_func; \
- if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): result=%p ...\n", #backend_func, capture)); \
- } catch(const cv::Exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", #backend_func, e.what())); \
- } catch (const std::exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", #backend_func, e.what())); \
- } catch(...) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", #backend_func)); \
- } \
- break; \
- }
-
-
- void VideoCapture_create(CvCapture*& capture, Ptr<IVideoCapture>& icap, VideoCaptureAPIs api, int index)
-std::vector<VideoCaptureAPIs> getWriterBackends()
++bool hasBackend(VideoCaptureAPIs api)
{
- CV_UNUSED(capture); CV_UNUSED(icap);
- switch (api)
- {
- default:
- CV_LOG_WARNING(NULL, "VideoCapture(index=" << index << ") was built without support of requested backendID=" << (int)api);
- break;
- #ifdef HAVE_GSTREAMER
- case CAP_GSTREAMER:
- TRY_OPEN(createGStreamerCapture(index));
- break;
- #endif
- #ifdef HAVE_MSMF
- case CAP_MSMF:
- TRY_OPEN(cvCreateCapture_MSMF(index));
- break;
- #endif
- #ifdef HAVE_DSHOW
- case CAP_DSHOW:
- TRY_OPEN(makePtr<VideoCapture_DShow>(index));
- break;
- #endif
- #ifdef HAVE_LIBREALSENSE
- case CAP_REALSENSE:
- TRY_OPEN(makePtr<VideoCapture_LibRealsense>(index));
- break;
- #endif
- #ifdef WINRT_VIDEO
- case CAP_WINRT:
- TRY_OPEN(makePtr<cv::VideoCapture_WinRT>(index));
- break;
- #endif
- #ifdef HAVE_GPHOTO2
- case CAP_GPHOTO2:
- TRY_OPEN(createGPhoto2Capture(index));
- break;
- #endif
- #if defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
- case CAP_V4L:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_V4L(index))
- break;
- #endif
- case CAP_FIREWIRE:
- #ifdef HAVE_DC1394_2
- TRY_OPEN_LEGACY(cvCreateCameraCapture_DC1394_2(index))
- #endif
- break; // CAP_FIREWIRE
- #ifdef HAVE_MIL
- case CAP_MIL:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_MIL(index))
- break;
- #endif
- #ifdef HAVE_PVAPI
- case CAP_PVAPI:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_PvAPI(index))
- break;
- #endif
- #ifdef HAVE_OPENNI2
- case CAP_OPENNI2:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_OpenNI2(index))
- break;
- #endif
- #ifdef HAVE_XIMEA
- case CAP_XIAPI:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_XIMEA(index))
- break;
- #endif
-
- #ifdef HAVE_AVFOUNDATION
- case CAP_AVFOUNDATION:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_AVFoundation(index))
- break;
- #endif
-
- #ifdef HAVE_ARAVIS_API
- case CAP_ARAVIS:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_Aravis(index))
- break;
- #endif
- } // switch (api)
- }
-
- void VideoCapture_create(CvCapture*& capture, Ptr<IVideoCapture>& icap, VideoCaptureAPIs api, const cv::String& filename)
- {
- CV_UNUSED(capture);
- switch (api)
- {
- default:
- CV_LOG_WARNING(NULL, "VideoCapture(filename=" << filename << ") was built without support of requested backendID=" << (int)api);
- break;
- #if defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
- case CAP_V4L:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_V4L(filename.c_str()))
- break;
- #endif
-
- #ifdef HAVE_AVFOUNDATION
- case CAP_AVFOUNDATION:
- TRY_OPEN_LEGACY(cvCreateFileCapture_AVFoundation(filename.c_str()))
- break;
- #endif
-
- #ifdef HAVE_OPENNI2
- case CAP_OPENNI2:
- TRY_OPEN_LEGACY(cvCreateFileCapture_OpenNI2(filename.c_str()))
- break;
- #endif
- #ifdef HAVE_XIMEA
- case CAP_XIAPI:
- TRY_OPEN_LEGACY(cvCreateCameraCapture_XIMEA(filename.c_str()))
- break;
- #endif
- case CAP_IMAGES:
- TRY_OPEN(createFileCapture_Images(filename))
- break;
- #ifdef HAVE_FFMPEG
- case CAP_FFMPEG:
- TRY_OPEN(cvCreateFileCapture_FFMPEG_proxy(filename))
- break;
- #endif
- #ifdef HAVE_GSTREAMER
- case CAP_GSTREAMER:
- TRY_OPEN(createGStreamerCapture(filename))
- break;
- #endif
- #ifdef HAVE_XINE
- case CAP_XINE:
- TRY_OPEN(createXINECapture(filename.c_str()))
- break;
- #endif
- #ifdef HAVE_MSMF
- case CAP_MSMF:
- TRY_OPEN(cvCreateCapture_MSMF(filename))
- break;
- #endif
- #ifdef HAVE_GPHOTO2
- case CAP_GPHOTO2:
- TRY_OPEN(createGPhoto2Capture(filename))
- break;
- #endif
- #ifdef HAVE_MFX
- case CAP_INTEL_MFX:
- TRY_OPEN(makePtr<VideoCapture_IntelMFX>(filename))
- break;
- #endif
- case CAP_OPENCV_MJPEG:
- TRY_OPEN(createMotionJpegCapture(filename))
- break;
- } // switch
- }
-
-
- void VideoWriter_create(CvVideoWriter*& writer, Ptr<IVideoWriter>& iwriter, VideoCaptureAPIs api,
- const String& filename, int fourcc, double fps, const Size& frameSize, bool isColor)
- {
- #define CREATE_WRITER(backend_func) \
- { \
- try { \
- if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying ...\n", #backend_func)); \
- iwriter = backend_func; \
- if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): result=%p isOpened=%d...\n", #backend_func, iwriter.empty() ? NULL : iwriter.get(), iwriter.empty() ? iwriter->isOpened() : -1)); \
- } catch(const cv::Exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", #backend_func, e.what())); \
- } catch (const std::exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", #backend_func, e.what())); \
- } catch(...) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", #backend_func)); \
- } \
- break; \
- }
-
- #define CREATE_WRITER_LEGACY(backend_func) \
- { \
- try { \
- if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying ...\n", #backend_func)); \
- writer = backend_func; \
- if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
- CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): result=%p...\n", #backend_func, writer)); \
- } catch(const cv::Exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", #backend_func, e.what())); \
- } catch (const std::exception& e) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", #backend_func, e.what())); \
- } catch(...) { \
- CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", #backend_func)); \
- } \
- break; \
- }
-
- switch (api)
- return toIDs(VideoBackendRegistry::getInstance().getBackends(MODE_WRITER));
++ std::vector<VideoBackendInfo> backends = VideoBackendRegistry::getInstance().getEnabledBackends();
++ for (size_t i = 0; i < backends.size(); i++)
+ {
- default:
- CV_LOG_ERROR(NULL, "Unknown VideoWriter backend (check getBuildInformation()): " << (int)api);
- break;
- #ifdef HAVE_FFMPEG
- case CAP_FFMPEG:
- CREATE_WRITER(cvCreateVideoWriter_FFMPEG_proxy(filename, fourcc, fps, frameSize, isColor));
- break;
- #endif
- #ifdef HAVE_MSMF
- case CAP_MSMF:
- CREATE_WRITER(cvCreateVideoWriter_MSMF(filename, fourcc, fps, frameSize, isColor));
- break;
- #endif
- #ifdef HAVE_MFX
- case CAP_INTEL_MFX:
- CREATE_WRITER(VideoWriter_IntelMFX::create(filename, fourcc, fps, frameSize, isColor));
- break;
- #endif
- #ifdef HAVE_AVFOUNDATION
- case CAP_AVFOUNDATION:
- CREATE_WRITER_LEGACY(cvCreateVideoWriter_AVFoundation(filename.c_str(), fourcc, fps, cvSize(frameSize), isColor))
- break;
- #endif
- #ifdef HAVE_GSTREAMER
- case CAP_GSTREAMER:
- CREATE_WRITER_LEGACY(cvCreateVideoWriter_GStreamer (filename.c_str(), fourcc, fps, cvSize(frameSize), isColor))
- break;
- #endif
- case CAP_OPENCV_MJPEG:
- CREATE_WRITER(createMotionJpegWriter(filename, fourcc, fps, frameSize, isColor));
- break;
- case CAP_IMAGES:
- if(!fourcc || !fps)
++ const VideoBackendInfo& info = backends[i];
++ if (api == info.id)
+ {
- CREATE_WRITER_LEGACY(cvCreateVideoWriter_Images(filename.c_str()));
++ CV_Assert(!info.backendFactory.empty());
++ return !info.backendFactory->getBackend().empty();
+ }
- break;
- } // switch(api)
++ }
++ return false;
}
-}} // cv::videoio_registry::
++} // namespace registry
+
+} // namespace
#ifndef __OPENCV_VIDEOIO_VIDEOIO_REGISTRY_HPP__
#define __OPENCV_VIDEOIO_VIDEOIO_REGISTRY_HPP__
-#include "opencv2/videoio.hpp"
-#include "opencv2/videoio/registry.hpp"
+ #include "backend.hpp"
+
namespace cv
{
// 0 - disabled (OPENCV_VIDEOIO_PRIORITY_<name> = 0)
// >10000 - prioritized list (OPENCV_VIDEOIO_PRIORITY_LIST)
const char* name;
- Ptr<IBackend> backendFactory;
++ Ptr<IBackendFactory> backendFactory;
};
-/** @brief Manages list of enabled backends
- */
-class VideoBackendRegistry
-{
-public:
- typedef std::vector<VideoBackendInfo> BackendsVec;
-protected:
- BackendsVec enabledBackends;
- VideoBackendRegistry();
-public:
- std::string dumpBackends() const;
- Ptr<IBackend> getBackend(VideoCaptureAPIs api) const;
- BackendsVec getBackends(int capabilityMask, VideoCaptureAPIs filter = CAP_ANY) const;
- bool hasBackend(int mask, VideoCaptureAPIs api) const;
-
- static VideoBackendRegistry& getInstance();
-};
+namespace videoio_registry {
+
+std::vector<VideoBackendInfo> getAvailableBackends_CaptureByIndex();
+std::vector<VideoBackendInfo> getAvailableBackends_CaptureByFilename();
+std::vector<VideoBackendInfo> getAvailableBackends_Writer();
+
+} // namespace
- void VideoCapture_create(CvCapture*& capture, Ptr<IVideoCapture>& icap, VideoCaptureAPIs api, int index);
- void VideoCapture_create(CvCapture*& capture, Ptr<IVideoCapture>& icap, VideoCaptureAPIs api, const cv::String& filename);
- void VideoWriter_create(CvVideoWriter*& writer, Ptr<IVideoWriter>& iwriter, VideoCaptureAPIs api,
- const String& filename, int fourcc, double fps, const Size& frameSize, bool isColor);
-
} // namespace
#endif // __OPENCV_VIDEOIO_VIDEOIO_REGISTRY_HPP__
--- /dev/null
- const int fourcc = VideoWriter::fourcc('H', '2', '6', '4');
+ // This file is part of OpenCV project.
+ // It is subject to the license terms in the LICENSE file found in the top-level directory
+ // of this distribution and at http://opencv.org/license.html.
+
+ #include "test_precomp.hpp"
+
+ using namespace std;
+
+ namespace opencv_test { namespace {
+
+ const int FRAME_COUNT = 120;
+
+ inline void generateFrame(int i, Mat & frame)
+ {
+ ::generateFrame(i, FRAME_COUNT, frame);
+ }
+
+ TEST(videoio_dynamic, basic_write)
+ {
+ const Size FRAME_SIZE(640, 480);
+ const double FPS = 100;
+ const String filename = cv::tempfile(".avi");
++ const int fourcc = VideoWriter::fourcc('M', 'J', 'P', 'G');
+
+ bool fileExists = false;
+ {
+ vector<VideoCaptureAPIs> backends = videoio_registry::getWriterBackends();
+ for (VideoCaptureAPIs be : backends)
+ {
+ VideoWriter writer;
+ writer.open(filename, be, fourcc, FPS, FRAME_SIZE, true);
+ if (writer.isOpened())
+ {
+ Mat frame(FRAME_SIZE, CV_8UC3);
+ for (int j = 0; j < FRAME_COUNT; ++j)
+ {
+ generateFrame(j, frame);
+ writer << frame;
+ }
+ writer.release();
+ fileExists = true;
+ }
+ EXPECT_FALSE(writer.isOpened());
+ }
+ }
+ if (!fileExists)
+ {
+ cout << "None of backends has been able to write video file - SKIP reading part" << endl;
+ return;
+ }
+ {
+ vector<VideoCaptureAPIs> backends = videoio_registry::getStreamBackends();
+ for (VideoCaptureAPIs be : backends)
+ {
+ VideoCapture cap;
+ cap.open(filename, be);
+ if(cap.isOpened())
+ {
+ int count = 0;
+ while (true)
+ {
+ Mat frame;
+ if (cap.grab())
+ {
+ if (cap.retrieve(frame))
+ {
+ ++count;
+ continue;
+ }
+ }
+ break;
+ }
+ EXPECT_EQ(count, FRAME_COUNT);
+ cap.release();
+ }
+ EXPECT_FALSE(cap.isOpened());
+ }
+ }
+ remove(filename.c_str());
+ }
+
+
+ }} // opencv_test::<anonymous>::
public:
void doTest()
{
- if (!isBackendAvailable(apiPref, cv::videoio_registry::getStreamBackends()))
- if (!videoio_registry::hasBackend(apiPref, videoio_registry::Read))
++ if (!videoio_registry::hasBackend(apiPref))
throw SkipTestException(cv::String("Backend is not available/disabled: ") + cv::videoio_registry::getBackendName(apiPref));
+ writeVideo();
VideoCapture cap;
ASSERT_NO_THROW(cap.open(video_file, apiPref));
if (!cap.isOpened())
}
void doFrameCountTest()
{
- if (!isBackendAvailable(apiPref, cv::videoio_registry::getStreamBackends()))
- if (!videoio_registry::hasBackend(apiPref, videoio_registry::Read))
++ if (!videoio_registry::hasBackend(apiPref))
throw SkipTestException(cv::String("Backend is not available/disabled: ") + cv::videoio_registry::getBackendName(apiPref));
VideoCapture cap;
EXPECT_NO_THROW(cap.open(video_file, apiPref));