videoio: add routines to query information about backends API

into cv::videoio_registry namespace
This commit is contained in:
Alexander Alekhin 2018-07-19 16:14:50 +03:00
parent 905da2994a
commit 270cc3bcbc
8 changed files with 213 additions and 57 deletions

View File

@ -1563,8 +1563,6 @@ PyObject* pyopencv_from(const Moments& m)
"nu30", m.nu30, "nu21", m.nu21, "nu12", m.nu12, "nu03", m.nu03);
}
#include "pyopencv_custom_headers.h"
static int OnError(int status, const char *func_name, const char *err_msg, const char *file_name, int line, void *userdata)
{
PyGILState_STATE gstate;
@ -1802,6 +1800,7 @@ static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name")
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
#include "pyopencv_custom_headers.h"
#include "pyopencv_generated_types.h"
#include "pyopencv_generated_funcs.h"

View File

@ -0,0 +1,25 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class Bindings(NewOpenCVTests):
def check_name(self, name):
#print(name)
self.assertFalse(name == None)
self.assertFalse(name == "")
def test_registry(self):
self.check_name(cv.videoio_registry.getBackendName(cv.CAP_ANY));
self.check_name(cv.videoio_registry.getBackendName(cv.CAP_FFMPEG))
self.check_name(cv.videoio_registry.getBackendName(cv.CAP_OPENCV_MJPEG))
backends = cv.videoio_registry.getBackends()
for backend in backends:
self.check_name(cv.videoio_registry.getBackendName(backend))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -59,6 +59,7 @@
@defgroup videoio_c C API for video I/O
@defgroup videoio_ios iOS glue for video I/O
@defgroup videoio_winrt WinRT glue for video I/O
@defgroup videoio_registry Query I/O API backends registry
@}
*/

View File

@ -0,0 +1,44 @@
// 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.
#ifndef OPENCV_VIDEOIO_REGISTRY_HPP
#define OPENCV_VIDEOIO_REGISTRY_HPP
#include <opencv2/videoio.hpp>
namespace cv { namespace videoio_registry {
/** @addtogroup videoio_registry
This section contains API description how to query/configure available Video I/O backends.
Runtime configuration options:
- enable debug mode: `OPENCV_VIDEOIO_DEBUG=1`
- change backend priority: `OPENCV_VIDEOIO_PRIORITY_<backend>=9999`
- disable backend: `OPENCV_VIDEOIO_PRIORITY_<backend>=0`
- specify list of backends with high priority (>100000): `OPENCV_VIDEOIO_PRIORITY_LIST=FFMPEG,GSTREAMER`
@{
*/
/** @brief Returns backend API name or "unknown"
@param api backend ID (#VideoCaptureAPIs)
*/
CV_EXPORTS_W cv::String getBackendName(VideoCaptureAPIs api);
/** @brief Returns list of all builtin backends */
CV_EXPORTS_W std::vector<VideoCaptureAPIs> getBackends();
/** @brief Returns list of available backends which works via `cv::VideoCapture(int index)` */
CV_EXPORTS_W std::vector<VideoCaptureAPIs> getCameraBackends();
/** @brief Returns list of available backends which works via `cv::VideoCapture(filename)` */
CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBackends();
/** @brief Returns list of available backends which works via `cv::VideoWriter()` */
CV_EXPORTS_W std::vector<VideoCaptureAPIs> getWriterBackends();
//! @}
}} // namespace
#endif // OPENCV_VIDEOIO_REGISTRY_HPP

View File

@ -0,0 +1,50 @@
#ifdef HAVE_OPENCV_VIDEOIO
typedef std::vector<VideoCaptureAPIs> vector_VideoCaptureAPIs;
template<>
bool pyopencv_to(PyObject *o, cv::VideoCaptureAPIs &v, const char *name)
{
(void)name;
v = CAP_ANY;
if (!o || o == Py_None)
return false;
else if (PyLong_Check(o))
{
v = VideoCaptureAPIs((int64)PyLong_AsLongLong(o));
return true;
}
else if (PyInt_Check(o))
{
v = VideoCaptureAPIs((int64)PyInt_AS_LONG(o));
return true;
}
else
return false;
}
template<>
PyObject* pyopencv_from(const cv::VideoCaptureAPIs &v)
{
return pyopencv_from((int)(v));
}
template<> struct pyopencvVecConverter<cv::VideoCaptureAPIs>
{
static bool to(PyObject* obj, std::vector<cv::VideoCaptureAPIs>& value, const ArgInfo info)
{
return pyopencv_to_generic_vec(obj, value, info);
}
static PyObject* from(const std::vector<cv::VideoCaptureAPIs>& value)
{
return pyopencv_from_generic_vec(value);
}
};
template<>
bool pyopencv_to(PyObject *o, std::vector<cv::VideoCaptureAPIs>& apis, const char *name)
{
return pyopencvVecConverter<cv::VideoCaptureAPIs>::to(o, apis, ArgInfo(name, false));
}
#endif // HAVE_OPENCV_VIDEOIO

View File

@ -6,6 +6,8 @@
#include "videoio_registry.hpp"
#include "opencv2/videoio/registry.hpp"
#include "cap_intelperc.hpp"
#include "cap_dshow.hpp"
@ -247,6 +249,8 @@ public:
return g_instance;
}
inline std::vector<VideoBackendInfo> getEnabledBackends() const { return enabledBackends; }
inline std::vector<VideoBackendInfo> getAvailableBackends_CaptureByIndex() const
{
std::vector<VideoBackendInfo> result;
@ -302,6 +306,58 @@ std::vector<VideoBackendInfo> 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) \

View File

@ -6,10 +6,26 @@
#include "opencv2/ts.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/videoio/registry.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/private.hpp"
namespace cv {
inline std::ostream &operator<<(std::ostream &out, const VideoCaptureAPIs& api)
{
out << cv::videoio_registry::getBackendName(api); return out;
}
static inline void PrintTo(const cv::VideoCaptureAPIs& api, std::ostream* os)
{
*os << cv::videoio_registry::getBackendName(api);
}
} // namespace
inline std::string fourccToString(int fourcc)
{
return cv::format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
@ -55,4 +71,15 @@ public:
}
};
static inline bool isBackendAvailable(cv::VideoCaptureAPIs api, const std::vector<cv::VideoCaptureAPIs>& api_list)
{
for (size_t i = 0; i < api_list.size(); i++)
{
if (api_list[i] == api)
return true;
}
return false;
}
#endif

View File

@ -46,62 +46,12 @@
namespace opencv_test
{
struct VideoCaptureAPI
{
VideoCaptureAPIs api;
inline const char * toString() const
{
switch (api)
{
case CAP_ANY: return "CAP_ANY";
#ifdef __linux__
case CAP_V4L2: return "CAP_V4L/CAP_V4L2";
#else
case CAP_VFW: return "CAP_VFW";
#endif
case CAP_FIREWIRE: return "CAP_FIREWIRE";
case CAP_QT: return "CAP_QT";
case CAP_UNICAP: return "CAP_UNICAP";
case CAP_DSHOW: return "CAP_DSHOW";
case CAP_PVAPI: return "CAP_PVAPI";
case CAP_OPENNI: return "CAP_OPENNI";
case CAP_OPENNI_ASUS: return "CAP_OPENNI_ASUS";
case CAP_ANDROID: return "CAP_ANDROID";
case CAP_XIAPI: return "CAP_XIAPI";
case CAP_AVFOUNDATION: return "CAP_AVFOUNDATION";
case CAP_GIGANETIX: return "CAP_GIGANETIX";
case CAP_MSMF: return "CAP_MSMF";
case CAP_WINRT: return "CAP_WINRT";
case CAP_INTELPERC: return "CAP_INTELPERC";
case CAP_OPENNI2: return "CAP_OPENNI2";
case CAP_OPENNI2_ASUS: return "CAP_OPENNI2_ASUS";
case CAP_GPHOTO2: return "CAP_GPHOTO2";
case CAP_GSTREAMER: return "CAP_GSTREAMER";
case CAP_FFMPEG: return "CAP_FFMPEG";
case CAP_IMAGES: return "CAP_IMAGES";
case CAP_ARAVIS: return "CAP_ARAVIS";
case CAP_OPENCV_MJPEG: return "CAP_OPENCV_MJPEG";
case CAP_INTEL_MFX: return "CAP_INTEL_MFX";
case CAP_XINE: return "CAP_XINE";
}
return "unknown";
}
VideoCaptureAPI(int api_ = CAP_ANY) : api((VideoCaptureAPIs)api_) {}
operator int() { return api; }
};
inline std::ostream &operator<<(std::ostream &out, const VideoCaptureAPI & api)
{
out << api.toString(); return out;
}
class Videoio_Test_Base
{
protected:
string ext;
string video_file;
VideoCaptureAPI apiPref;
VideoCaptureAPIs apiPref;
protected:
Videoio_Test_Base() {}
virtual ~Videoio_Test_Base() {}
@ -131,6 +81,8 @@ protected:
public:
void doTest()
{
if (!isBackendAvailable(apiPref, cv::videoio_registry::getStreamBackends()))
throw SkipTestException(cv::String("Backend is not available/disabled: ") + cv::videoio_registry::getBackendName(apiPref));
VideoCapture cap;
ASSERT_NO_THROW(cap.open(video_file, apiPref));
if (!cap.isOpened())
@ -200,7 +152,7 @@ public:
};
//==================================================================================================
typedef tuple<string, VideoCaptureAPI> Backend_Type_Params;
typedef tuple<string, VideoCaptureAPIs> Backend_Type_Params;
class Videoio_Bunny : public Videoio_Test_Base, public testing::TestWithParam<Backend_Type_Params>
{
@ -214,6 +166,8 @@ public:
}
void doFrameCountTest()
{
if (!isBackendAvailable(apiPref, cv::videoio_registry::getStreamBackends()))
throw SkipTestException(cv::String("Backend is not available/disabled: ") + cv::videoio_registry::getBackendName(apiPref));
VideoCapture cap;
EXPECT_NO_THROW(cap.open(video_file, apiPref));
if (!cap.isOpened())
@ -274,7 +228,7 @@ struct Ext_Fourcc_PSNR
string ext;
string fourcc;
float PSNR;
VideoCaptureAPI api;
VideoCaptureAPIs api;
};
typedef tuple<Size, Ext_Fourcc_PSNR> Size_Ext_Fourcc_PSNR;
@ -348,7 +302,7 @@ public:
//==================================================================================================
static VideoCaptureAPI backend_params[] = {
static const VideoCaptureAPIs backend_params[] = {
#ifdef HAVE_QUICKTIME
CAP_QT,
#endif
@ -383,7 +337,7 @@ static VideoCaptureAPI backend_params[] = {
// CAP_INTEL_MFX
};
static string bunny_params[] = {
static const string bunny_params[] = {
#ifdef HAVE_VIDEO_INPUT
string("wmv"),
string("mov"),