opencv/modules/videoio/src/videoio_registry.cpp
Pavel Rojtberg 0d65397ae7 videoio: remove cap_libv4l in favour of cap_v4l
cap_libv4l depends on an external library (libv4l) yet is still larger
(1966 loc vs 1822 loc).
It was initially introduced copy pasting cap_v4l in order to offload
various color conversions to libv4l.
However nowadays we handle most of the needed color conversions inside
OpenCV. Our own implementation is better tested and (probably) also
better performing. (as it can optionally leverage IPP/ OpenCL)

Currently cap_v4l is better maintained and generally the code is in
better shape. There is however an API
difference in getting unconverted frames:
* on cap_libv4l one need to set `CV_CAP_MODE_GRAY=1` or
`CV_CAP_MODE_YUYV=1`
* on cap_v4l one needs to set `CV_CAP_PROP_CONVERT_RGB=0`

the latter is more flexible though as it also allows accessing undecoded
JPEG images.

fixes #4563
2018-11-12 13:38:59 +03:00

647 lines
21 KiB
C++

// 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 "precomp.hpp"
#include "videoio_registry.hpp"
#include "opencv2/videoio/registry.hpp"
#include "cap_intelperc.hpp"
#include "cap_librealsense.hpp"
#include "cap_dshow.hpp"
#ifdef HAVE_MFX
#include "cap_mfx_reader.hpp"
#include "cap_mfx_writer.hpp"
#endif
// All WinRT versions older than 8.0 should provide classes used for video support
#if defined(WINRT) && !defined(WINRT_8_0) && defined(__cplusplus_winrt)
# include "cap_winrt_capture.hpp"
# include "cap_winrt_bridge.hpp"
# define WINRT_VIDEO
#endif
#if defined _M_X64 && defined _MSC_VER && !defined CV_ICC
#pragma optimize("",off)
#pragma warning(disable: 4748)
#endif
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 {
#define DECLARE_BACKEND(cap, name, mode) { cap, (BackendMode)(mode), 1000, name }
/** Ordering guidelines:
- modern optimized, multi-platform libraries: ffmpeg, gstreamer, Media SDK
- platform specific universal SDK: WINRT, AVFOUNDATION, MSMF/DSHOW, V4L/V4L2
- RGB-D: OpenNI/OpenNI2, INTELPERC/REALSENSE
- special OpenCV (file-based): "images", "mjpeg"
- special camera SDKs, including stereo: other special SDKs: FIREWIRE/1394, XIMEA/ARAVIS/GIGANETIX/PVAPI(GigE)
- other: XINE, gphoto2, etc
*/
static const struct VideoBackendInfo builtin_backends[] =
{
#ifdef HAVE_FFMPEG
DECLARE_BACKEND(CAP_FFMPEG, "FFMPEG", MODE_CAPTURE_BY_FILENAME | MODE_WRITER),
#endif
#ifdef HAVE_GSTREAMER
DECLARE_BACKEND(CAP_GSTREAMER, "GSTREAMER", MODE_CAPTURE_ALL | MODE_WRITER),
#endif
#ifdef HAVE_MFX // Media SDK
DECLARE_BACKEND(CAP_INTEL_MFX, "INTEL_MFX", MODE_CAPTURE_BY_FILENAME | MODE_WRITER),
#endif
// Apple platform
#ifdef HAVE_AVFOUNDATION
DECLARE_BACKEND(CAP_AVFOUNDATION, "AVFOUNDATION", MODE_CAPTURE_ALL | MODE_WRITER),
#endif
// Windows
#ifdef WINRT_VIDEO
DECLARE_BACKEND(CAP_WINRT, "WINRT", MODE_CAPTURE_BY_INDEX),
#endif
#ifdef HAVE_MSMF
DECLARE_BACKEND(CAP_MSMF, "MSMF", MODE_CAPTURE_ALL | MODE_WRITER),
#endif
#ifdef HAVE_DSHOW
DECLARE_BACKEND(CAP_DSHOW, "DSHOW", MODE_CAPTURE_BY_INDEX),
#endif
// Linux, some Unix
#if defined HAVE_CAMV4L2
DECLARE_BACKEND(CAP_V4L2, "V4L2", MODE_CAPTURE_ALL),
#elif defined HAVE_CAMV4L
DECLARE_BACKEND(CAP_V4L, "V4L", MODE_CAPTURE_ALL),
#endif
// RGB-D universal
#ifdef HAVE_OPENNI
DECLARE_BACKEND(CAP_OPENNI, "OPENNI", MODE_CAPTURE_ALL),
#endif
#ifdef HAVE_OPENNI2
DECLARE_BACKEND(CAP_OPENNI2, "OPENNI2", MODE_CAPTURE_ALL),
#endif
#ifdef HAVE_INTELPERC
DECLARE_BACKEND(CAP_INTELPERC, "INTEL_PERC", MODE_CAPTURE_BY_INDEX),
#elif defined(HAVE_LIBREALSENSE)
DECLARE_BACKEND(CAP_INTELPERC, "INTEL_REALSENSE", MODE_CAPTURE_BY_INDEX),
#endif
// OpenCV file-based only
DECLARE_BACKEND(CAP_IMAGES, "CV_IMAGES", MODE_CAPTURE_BY_FILENAME | MODE_WRITER),
DECLARE_BACKEND(CAP_OPENCV_MJPEG, "CV_MJPEG", MODE_CAPTURE_BY_FILENAME | MODE_WRITER),
// special interfaces / stereo cameras / other SDKs
#if defined(HAVE_DC1394_2)
DECLARE_BACKEND(CAP_FIREWIRE, "FIREWIRE", MODE_CAPTURE_BY_INDEX),
#endif
// GigE
#ifdef HAVE_PVAPI
DECLARE_BACKEND(CAP_PVAPI, "PVAPI", MODE_CAPTURE_BY_INDEX),
#endif
#ifdef HAVE_XIMEA
DECLARE_BACKEND(CAP_XIAPI, "XIMEA", MODE_CAPTURE_ALL),
#endif
#ifdef HAVE_GIGE_API
DECLARE_BACKEND(CAP_GIGANETIX, "GIGANETIX", MODE_CAPTURE_BY_INDEX),
#endif
#ifdef HAVE_ARAVIS_API
DECLARE_BACKEND(CAP_ARAVIS, "ARAVIS", MODE_CAPTURE_BY_INDEX),
#endif
#ifdef HAVE_GPHOTO2
DECLARE_BACKEND(CAP_GPHOTO2, "GPHOTO2", MODE_CAPTURE_ALL),
#endif
#ifdef HAVE_XINE
DECLARE_BACKEND(CAP_XINE, "XINE", MODE_CAPTURE_BY_FILENAME),
#endif
// dropped backends: MIL, TYZX, Android
};
bool sortByPriority(const VideoBackendInfo &lhs, const VideoBackendInfo &rhs)
{
return lhs.priority > rhs.priority;
}
/** @brief Manages list of enabled backends
*/
class VideoBackendRegistry
{
protected:
std::vector<VideoBackendInfo> enabledBackends;
VideoBackendRegistry()
{
const int N = sizeof(builtin_backends)/sizeof(builtin_backends[0]);
enabledBackends.assign(builtin_backends, builtin_backends + N);
for (int i = 0; i < N; i++)
{
VideoBackendInfo& info = enabledBackends[i];
info.priority = 1000 - i * 10;
}
CV_LOG_DEBUG(NULL, "VIDEOIO: Builtin backends(" << N << "): " << dumpBackends());
if (readPrioritySettings())
{
CV_LOG_INFO(NULL, "VIDEOIO: Updated backends priorities: " << dumpBackends());
}
int enabled = 0;
for (int i = 0; i < N; i++)
{
VideoBackendInfo& info = enabledBackends[enabled];
if (enabled != i)
info = enabledBackends[i];
size_t param_priority = utils::getConfigurationParameterSizeT(cv::format("OPENCV_VIDEOIO_PRIORITY_%s", info.name).c_str(), (size_t)info.priority);
CV_Assert(param_priority == (size_t)(int)param_priority); // overflow check
if (param_priority > 0)
{
info.priority = (int)param_priority;
enabled++;
}
else
{
CV_LOG_INFO(NULL, "VIDEOIO: Disable backend: " << info.name);
}
}
enabledBackends.resize(enabled);
CV_LOG_DEBUG(NULL, "VIDEOIO: Available backends(" << enabled << "): " << dumpBackends());
std::sort(enabledBackends.begin(), enabledBackends.end(), sortByPriority);
CV_LOG_INFO(NULL, "VIDEOIO: Enabled backends(" << enabled << ", sorted by priority): " << dumpBackends());
}
static std::vector<std::string> tokenize_string(const std::string& input, char token)
{
std::vector<std::string> result;
std::string::size_type prev_pos = 0, pos = 0;
while((pos = input.find(token, pos)) != std::string::npos)
{
result.push_back(input.substr(prev_pos, pos-prev_pos));
prev_pos = ++pos;
}
result.push_back(input.substr(prev_pos));
return result;
}
bool readPrioritySettings()
{
bool hasChanges = false;
cv::String prioritized_backends = utils::getConfigurationParameterString("OPENCV_VIDEOIO_PRIORITY_LIST", NULL);
if (prioritized_backends.empty())
return hasChanges;
CV_LOG_INFO(NULL, "VIDEOIO: Configured priority list (OPENCV_VIDEOIO_PRIORITY_LIST): " << prioritized_backends);
const std::vector<std::string> names = tokenize_string(prioritized_backends, ',');
for (size_t i = 0; i < names.size(); i++)
{
const std::string& name = names[i];
bool found = false;
for (size_t k = 0; k < enabledBackends.size(); k++)
{
VideoBackendInfo& info = enabledBackends[k];
if (name == info.name)
{
info.priority = (int)(100000 + (names.size() - i) * 1000);
CV_LOG_DEBUG(NULL, "VIDEOIO: New backend priority: '" << name << "' => " << info.priority);
found = true;
hasChanges = true;
break;
}
}
if (!found)
{
CV_LOG_WARNING(NULL, "VIDEOIO: Can't prioritize unknown/unavailable backend: '" << name << "'");
}
}
return hasChanges;
}
public:
std::string dumpBackends() const
{
std::ostringstream os;
for (size_t i = 0; i < enabledBackends.size(); i++)
{
if (i > 0) os << "; ";
const VideoBackendInfo& info = enabledBackends[i];
os << info.name << '(' << info.priority << ')';
}
return os.str();
}
static VideoBackendRegistry& getInstance()
{
static VideoBackendRegistry g_instance;
return g_instance;
}
inline std::vector<VideoBackendInfo> getEnabledBackends() const { return enabledBackends; }
inline std::vector<VideoBackendInfo> getAvailableBackends_CaptureByIndex() const
{
std::vector<VideoBackendInfo> result;
for (size_t i = 0; i < enabledBackends.size(); i++)
{
const VideoBackendInfo& info = enabledBackends[i];
if (info.mode & MODE_CAPTURE_BY_INDEX)
result.push_back(info);
}
return result;
}
inline std::vector<VideoBackendInfo> getAvailableBackends_CaptureByFilename() const
{
std::vector<VideoBackendInfo> result;
for (size_t i = 0; i < enabledBackends.size(); i++)
{
const VideoBackendInfo& info = enabledBackends[i];
if (info.mode & MODE_CAPTURE_BY_FILENAME)
result.push_back(info);
}
return result;
}
inline std::vector<VideoBackendInfo> getAvailableBackends_Writer() const
{
std::vector<VideoBackendInfo> result;
for (size_t i = 0; i < enabledBackends.size(); i++)
{
const VideoBackendInfo& info = enabledBackends[i];
if (info.mode & MODE_WRITER)
result.push_back(info);
}
return result;
}
};
} // namespace
namespace videoio_registry {
std::vector<VideoBackendInfo> getAvailableBackends_CaptureByIndex()
{
const std::vector<VideoBackendInfo> result = VideoBackendRegistry::getInstance().getAvailableBackends_CaptureByIndex();
return result;
}
std::vector<VideoBackendInfo> getAvailableBackends_CaptureByFilename()
{
const std::vector<VideoBackendInfo> result = VideoBackendRegistry::getInstance().getAvailableBackends_CaptureByFilename();
return result;
}
std::vector<VideoBackendInfo> getAvailableBackends_Writer()
{
const std::vector<VideoBackendInfo> result = VideoBackendRegistry::getInstance().getAvailableBackends_Writer();
return result;
}
cv::String getBackendName(VideoCaptureAPIs api)
{
if (api == CAP_ANY)
return "CAP_ANY"; // special case, not a part of backends list
const int N = sizeof(builtin_backends)/sizeof(builtin_backends[0]);
for (size_t i = 0; i < N; i++)
{
const VideoBackendInfo& backend = builtin_backends[i];
if (backend.id == api)
return backend.name;
}
return cv::format("UnknownVideoAPI(%d)", (int)api);
}
std::vector<VideoCaptureAPIs> getBackends()
{
std::vector<VideoBackendInfo> backends = VideoBackendRegistry::getInstance().getEnabledBackends();
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> getCameraBackends()
{
const std::vector<VideoBackendInfo> backends = VideoBackendRegistry::getInstance().getAvailableBackends_CaptureByIndex();
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()
{
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> getWriterBackends()
{
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)
{
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_INTELPERC
case CAP_INTELPERC:
TRY_OPEN(makePtr<VideoCapture_IntelPerC>());
break;
#elif defined(HAVE_LIBREALSENSE)
case CAP_INTELPERC:
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
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_OPENNI
case CAP_OPENNI:
TRY_OPEN_LEGACY(cvCreateCameraCapture_OpenNI(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_GIGE_API
case CAP_GIGANETIX:
TRY_OPEN_LEGACY(cvCreateCameraCapture_Giganetix(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_CAMV4L || 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_OPENNI
case CAP_OPENNI:
TRY_OPEN_LEGACY(cvCreateFileCapture_OpenNI(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)
{
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)
{
CREATE_WRITER_LEGACY(cvCreateVideoWriter_Images(filename.c_str()));
}
break;
} // switch(api)
}
} // namespace