1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Alexander Alekhin 9a54a3273d dnn(protobuf): backport AllowUnknownField(), SetRecursionLimit()
- limit recursion in SkipField*() calls

original commit 288fa70ed9
2020-04-27 12:25:47 +00:00
Alexander Alekhin 9c1e2a6906 dnn(ie): avoid conversion to legacy CNNNetworkImpl
original commit: f756923271
2020-04-23 22:42:12 +00:00
Maksim Shabunin 626db27735 videoio: load debug versions of plug-ins in debug builds
original commit: 9415560250
2020-04-22 13:04:33 +00:00
Maksim Shabunin 4366ec4dcc videoio: set plugin output dir on windows to bin
original commit: 90e7c29c46
2020-04-22 13:04:33 +00:00
Maksim Shabunin f773729449 videoio: added plug-in support to MSMF backend
original commit: ca6a11e4d2
2020-04-22 13:04:33 +00:00
Alexander Alekhin 841860f580 OpenCV version '-openvino-2020.3.0' 2020-04-22 13:04:33 +00:00
Alexander Alekhin ac4aed62c8 dnn: use OpenVINO 2020.3 defines 2020-04-22 13:04:33 +00:00
Liubov Batanina 776586fb08 Fix ENet test with OpenVINO 2020.2
original commit: a448d3a6aa
2020-04-22 13:04:33 +00:00
Alexander Alekhin 4d34934d25 gapi(simd): initialize accumulator values
original commit: 99502e99cc
2020-03-30 19:36:30 +03:00
Alexander Alekhin 1b5c2bb363 OpenCV version '-openvino' 2020-03-24 16:17:01 +03:00
Alexander Alekhin 45263d7642 dnn: use OpenVINO 2020.2 defines 2020-03-24 16:17:01 +03:00
16 changed files with 408 additions and 49 deletions
+54 -18
View File
@@ -225,7 +225,9 @@ class TextFormat::Parser::ParserImpl {
bool allow_unknown_enum,
bool allow_field_number,
bool allow_relaxed_whitespace,
bool allow_partial)
bool allow_partial,
int recursion_limit // backported from 3.8.0
)
: error_collector_(error_collector),
finder_(finder),
parse_info_tree_(parse_info_tree),
@@ -238,7 +240,9 @@ class TextFormat::Parser::ParserImpl {
allow_unknown_enum_(allow_unknown_enum),
allow_field_number_(allow_field_number),
allow_partial_(allow_partial),
had_errors_(false) {
had_errors_(false),
recursion_limit_(recursion_limit) // backported from 3.8.0
{
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
// for floats.
tokenizer_.set_allow_f_after_float(true);
@@ -490,9 +494,9 @@ class TextFormat::Parser::ParserImpl {
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
return SkipFieldValue(unknown_field);
return SkipFieldValue(unknown_field, recursion_limit_);
} else {
return SkipFieldMessage(unknown_fields);
return SkipFieldMessage(unknown_fields, recursion_limit_);
}
}
@@ -575,7 +579,14 @@ label_skip_parsing:
}
// Skips the next field including the field's name and value.
bool SkipField(UnknownFieldSet* unknown_fields) {
bool SkipField(UnknownFieldSet* unknown_fields, int recursion_limit) {
// OpenCV specific
if (--recursion_limit < 0) {
ReportError("Message is too deep (SkipField)");
return false;
}
string field_name;
if (TryConsume("[")) {
// Extension name.
@@ -594,9 +605,9 @@ label_skip_parsing:
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
DO(SkipFieldValue(unknown_field));
DO(SkipFieldValue(unknown_field, recursion_limit));
} else {
DO(SkipFieldMessage(unknown_fields));
DO(SkipFieldMessage(unknown_fields, recursion_limit));
}
// For historical reasons, fields may optionally be separated by commas or
// semicolons.
@@ -608,6 +619,12 @@ label_skip_parsing:
const Reflection* reflection,
const FieldDescriptor* field) {
// backported from 3.8.0
if (--recursion_limit_ < 0) {
ReportError("Message is too deep");
return false;
}
// If the parse information tree is not NULL, create a nested one
// for the nested message.
ParseInfoTree* parent = parse_info_tree_;
@@ -624,6 +641,9 @@ label_skip_parsing:
delimiter));
}
// backported from 3.8.0
++recursion_limit_;
// Reset the parse information tree.
parse_info_tree_ = parent;
return true;
@@ -631,11 +651,17 @@ label_skip_parsing:
// Skips the whole body of a message including the beginning delimiter and
// the ending delimiter.
bool SkipFieldMessage(UnknownFieldSet* unknown_fields) {
bool SkipFieldMessage(UnknownFieldSet* unknown_fields, int recursion_limit) {
// OpenCV specific
if (--recursion_limit < 0) {
ReportError("Message is too deep (SkipFieldMessage)");
return false;
}
string delimiter;
DO(ConsumeMessageDelimiter(&delimiter));
while (!LookingAt(">") && !LookingAt("}")) {
DO(SkipField(unknown_fields));
DO(SkipField(unknown_fields, recursion_limit));
}
DO(Consume(delimiter));
return true;
@@ -775,7 +801,14 @@ label_skip_parsing:
return true;
}
bool SkipFieldValue(UnknownFieldSet* unknown_field) {
bool SkipFieldValue(UnknownFieldSet* unknown_field, int recursion_limit) {
// OpenCV specific
if (--recursion_limit < 0) {
ReportError("Message is too deep (SkipFieldValue)");
return false;
}
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
tokenizer_.Next();
@@ -785,9 +818,9 @@ label_skip_parsing:
if (TryConsume("[")) {
while (true) {
if (!LookingAt("{") && !LookingAt("<")) {
DO(SkipFieldValue(unknown_field));
DO(SkipFieldValue(unknown_field, recursion_limit));
} else {
DO(SkipFieldMessage(unknown_field));
DO(SkipFieldMessage(unknown_field, recursion_limit));
}
if (TryConsume("]")) {
break;
@@ -1156,6 +1189,7 @@ label_skip_parsing:
const bool allow_field_number_;
const bool allow_partial_;
bool had_errors_;
int recursion_limit_; // backported from 3.8.0
};
#undef DO
@@ -1306,17 +1340,19 @@ class TextFormat::Printer::TextGenerator
TextFormat::Finder::~Finder() {
}
TextFormat::Parser::Parser(bool allow_unknown_field)
TextFormat::Parser::Parser()
: error_collector_(NULL),
finder_(NULL),
parse_info_tree_(NULL),
allow_partial_(false),
allow_case_insensitive_field_(false),
allow_unknown_field_(allow_unknown_field),
allow_unknown_field_(false),
allow_unknown_enum_(false),
allow_field_number_(false),
allow_relaxed_whitespace_(false),
allow_singular_overwrites_(false) {
allow_singular_overwrites_(false),
recursion_limit_(std::numeric_limits<int>::max())
{
}
TextFormat::Parser::~Parser() {}
@@ -1335,7 +1371,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
overwrites_policy,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
allow_relaxed_whitespace_, allow_partial_);
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
return MergeUsingImpl(input, output, &parser);
}
@@ -1353,7 +1389,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
allow_relaxed_whitespace_, allow_partial_);
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
return MergeUsingImpl(input, output, &parser);
}
@@ -1388,7 +1424,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
allow_relaxed_whitespace_, allow_partial_);
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
return parser.ParseField(field, output);
}
+16 -1
View File
@@ -457,7 +457,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
// For more control over parsing, use this class.
class LIBPROTOBUF_EXPORT Parser {
public:
Parser(bool allow_unknown_field = false);
Parser();
~Parser();
// Like TextFormat::Parse().
@@ -508,10 +508,24 @@ class LIBPROTOBUF_EXPORT TextFormat {
Message* output);
// backported from 3.8.0
// When an unknown field is met, parsing will fail if this option is set
// to false(the default). If true, unknown fields will be ignored and
// a warning message will be generated.
// Please aware that set this option true may hide some errors (e.g.
// spelling error on field name). Avoid to use this option if possible.
void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; }
void AllowFieldNumber(bool allow) {
allow_field_number_ = allow;
}
// backported from 3.8.0
// Sets maximum recursion depth which parser can use. This is effectively
// the maximum allowed nesting of proto messages.
void SetRecursionLimit(int limit) { recursion_limit_ = limit; }
private:
// Forward declaration of an internal class used to parse text
// representations (see text_format.cc for implementation).
@@ -533,6 +547,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
bool allow_field_number_;
bool allow_relaxed_whitespace_;
bool allow_singular_overwrites_;
int recursion_limit_; // backported from 3.8.0
};
+2 -2
View File
@@ -92,9 +92,9 @@ endif()
if(INF_ENGINE_TARGET)
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version has not been set, 2020.1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
message(WARNING "InferenceEngine version has not been set, 2020.3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
endif()
set(INF_ENGINE_RELEASE "2020010000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set(INF_ENGINE_RELEASE "2020030000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
)
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 4
#define CV_VERSION_MINOR 3
#define CV_VERSION_REVISION 0
#define CV_VERSION_STATUS "-pre"
#define CV_VERSION_STATUS "-openvino-2020.3.0"
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+8 -7
View File
@@ -1120,11 +1120,12 @@ bool ReadProtoFromTextFile(const char* filename, Message* proto) {
std::ifstream fs(filename, std::ifstream::in);
CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";
IstreamInputStream input(&fs);
google::protobuf::TextFormat::Parser parser;
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
return google::protobuf::TextFormat::Parser(true).Parse(&input, proto);
#else
return google::protobuf::TextFormat::Parser().Parse(&input, proto);
parser.AllowUnknownField(true);
parser.SetRecursionLimit(1000);
#endif
return parser.Parse(&input, proto);
}
bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
@@ -1137,12 +1138,12 @@ bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
bool ReadProtoFromTextBuffer(const char* data, size_t len, Message* proto) {
ArrayInputStream input(data, len);
google::protobuf::TextFormat::Parser parser;
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
return google::protobuf::TextFormat::Parser(true).Parse(&input, proto);
#else
return google::protobuf::TextFormat::Parser().Parse(&input, proto);
parser.AllowUnknownField(true);
parser.SetRecursionLimit(1000);
#endif
return parser.Parse(&input, proto);
}
+56 -5
View File
@@ -2228,7 +2228,11 @@ struct Net::Impl
auto ieInpNode = inputNodes[i].dynamicCast<InfEngineNgraphNode>();
CV_Assert(oid < ieInpNode->node->get_output_size());
#if INF_ENGINE_VER_MAJOR_GT(2020030000)
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid)));
#else
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid, false)));
#endif
}
if (layer->supportBackend(preferableBackend))
@@ -3444,6 +3448,8 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
{
CV_TRACE_FUNCTION();
CV_TRACE_REGION("register_inputs");
std::vector<String> inputsNames;
std::vector<MatShape> inp_shapes;
for (auto& it : ieNet.getInputsInfo())
@@ -3462,6 +3468,8 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
cvNet.setInputShape(inputsNames[inp_id], inp_shapes[inp_id]);
}
CV_TRACE_REGION_NEXT("backendNode");
Ptr<BackendNode> backendNode;
#ifdef HAVE_DNN_NGRAPH
if (DNN_BACKEND_INFERENCE_ENGINE_NGRAPH == getInferenceEngineBackendTypeParam())
@@ -3483,8 +3491,25 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
#endif
}
CV_TRACE_REGION_NEXT("register_outputs");
#ifdef HAVE_DNN_NGRAPH
auto ngraphFunction = ieNet.getFunction();
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2)
std::list< std::shared_ptr<ngraph::Node> > ngraphOperations;
#else
std::vector< std::shared_ptr<ngraph::Node> > ngraphOperations;
#endif
if (ngraphFunction)
{
ngraphOperations = ngraphFunction->get_ops();
}
#endif
for (auto& it : ieNet.getOutputsInfo())
{
CV_TRACE_REGION("output");
LayerParams lp;
int lid = cvNet.addLayer(it.first, "", lp);
@@ -3493,15 +3518,38 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
#ifdef HAVE_DNN_NGRAPH
if (DNN_BACKEND_INFERENCE_ENGINE_NGRAPH == getInferenceEngineBackendTypeParam())
{
const auto& outputName = it.first;
Ptr<Layer> cvLayer(new NgraphBackendLayer(ieNet));
cvLayer->name = outputName;
cvLayer->type = "_unknown_";
InferenceEngine::CNNLayerPtr ieLayer = ieNet.getLayerByName(it.first.c_str());
CV_Assert(ieLayer);
if (ngraphFunction)
{
CV_TRACE_REGION("ngraph_function");
bool found = false;
for (const auto& op : ngraphOperations)
{
CV_Assert(op);
if (op->get_friendly_name() == outputName)
{
const std::string typeName = op->get_type_info().name;
cvLayer->type = typeName;
found = true;
break;
}
}
if (!found)
CV_LOG_WARNING(NULL, "DNN/IE: Can't determine output layer type: '" << outputName << "'");
}
else
{
CV_TRACE_REGION("legacy_cnn_layer");
InferenceEngine::CNNLayerPtr ieLayer = ieNet.getLayerByName(it.first.c_str());
CV_Assert(ieLayer);
cvLayer->name = it.first;
cvLayer->type = ieLayer->type;
cvLayer->type = ieLayer->type;
}
ld.layerInstance = cvLayer;
ld.backendNodes[DNN_BACKEND_INFERENCE_ENGINE_NGRAPH] = backendNode;
}
else
@@ -3526,6 +3574,9 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
for (int i = 0; i < inputsNames.size(); ++i)
cvNet.connect(0, i, lid, i);
}
CV_TRACE_REGION_NEXT("finalize");
cvNet.setPreferableBackend(getInferenceEngineBackendTypeParam());
cvNet.impl->skipInfEngineInit = true;
+4 -2
View File
@@ -24,10 +24,12 @@
#define INF_ENGINE_RELEASE_2019R2 2019020000
#define INF_ENGINE_RELEASE_2019R3 2019030000
#define INF_ENGINE_RELEASE_2020_1 2020010000
#define INF_ENGINE_RELEASE_2020_2 2020020000
#define INF_ENGINE_RELEASE_2020_3 2020030000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2019.1 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2020_1
#warning("IE version have not been provided via command-line. Using 2020.3 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2020_3
#endif
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
+11 -3
View File
@@ -273,9 +273,18 @@ TEST_P(DNNTestOpenVINO, models)
const Backend backendId = get<0>(get<0>(GetParam()));
const Target targetId = get<1>(get<0>(GetParam()));
std::string modelName = get<1>(GetParam());
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
throw SkipTestException("No support for async forward");
ASSERT_FALSE(backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) <<
"Inference Engine backend is required";
#if INF_ENGINE_VER_MAJOR_GE(2020020000)
if (targetId == DNN_TARGET_MYRIAD && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
{
if (modelName == "person-detection-retail-0013") // IRv10
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
}
#endif
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
@@ -284,7 +293,6 @@ TEST_P(DNNTestOpenVINO, models)
else
FAIL() << "Unknown backendId";
std::string modelName = get<1>(GetParam());
bool isFP16 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD);
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
@@ -1831,7 +1831,7 @@ static void run_sepfilter5x5_char2short(short out[], const uchar *in[], int widt
for (; l <= length - nlanes; l += nlanes)
{
v_uint16 t[kxLen];
v_int16 sum;
v_int16 sum = vx_setzero_s16();
for (int i = 0; i < kxLen; ++i)
{
@@ -1862,7 +1862,7 @@ static void run_sepfilter5x5_char2short(short out[], const uchar *in[], int widt
for (; l <= length - nlanes; l += nlanes)
{
v_int16 s[buffSize];
v_int16 sum;
v_int16 sum = vx_setzero_s16();
for (int i = 0; i < kyLen; ++i)
{
+11 -3
View File
@@ -31,6 +31,10 @@ file(GLOB videoio_ext_hdrs
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h"
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/legacy/*.h")
if(OPENCV_DEBUG_POSTFIX)
ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/backend_plugin.cpp" "DEBUG_POSTFIX=${OPENCV_DEBUG_POSTFIX}")
endif()
# Removing WinRT API headers by default
list(REMOVE_ITEM videoio_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/cap_winrt.hpp")
@@ -91,9 +95,13 @@ if(TARGET ocv.3rdparty.dshow)
endif()
if(TARGET ocv.3rdparty.msmf)
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_msmf.hpp)
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_msmf.cpp)
list(APPEND tgts ocv.3rdparty.msmf)
if("msmf" IN_LIST VIDEOIO_PLUGIN_LIST)
ocv_create_builtin_videoio_plugin("opencv_videoio_msmf" ocv.3rdparty.msmf "cap_msmf.cpp")
else()
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_msmf.hpp)
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_msmf.cpp)
list(APPEND tgts ocv.3rdparty.msmf)
endif()
endif()
if(TARGET ocv.3rdparty.xine)
+2
View File
@@ -40,10 +40,12 @@ function(ocv_create_builtin_videoio_plugin name target)
set_target_properties(${name} PROPERTIES
CXX_STANDARD 11
CXX_VISIBILITY_PRESET hidden
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
OUTPUT_NAME "${name}${OPENCV_PLUGIN_VERSION}${OPENCV_PLUGIN_ARCH}"
)
if(WIN32)
set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
install(TARGETS ${name} OPTIONAL LIBRARY DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT plugins)
else()
install(TARGETS ${name} OPTIONAL LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT plugins)
+16
View File
@@ -123,6 +123,9 @@ std::string librarySuffix()
CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__)
"_64"
#endif
#if defined(_DEBUG) && defined(DEBUG_POSTFIX)
CVAUX_STR(DEBUG_POSTFIX)
#endif
".dll";
return suffix;
@@ -338,6 +341,19 @@ std::vector<FileSystemPath_t> getPluginCandidates(const std::string& baseName)
results.push_back(path + L"\\" + moduleName);
}
results.push_back(moduleName);
#if defined(_DEBUG) && defined(DEBUG_POSTFIX)
if (baseName_u == "FFMPEG") // backward compatibility
{
const FileSystemPath_t templ = toFileSystemPath(CVAUX_STR(DEBUG_POSTFIX) ".dll");
FileSystemPath_t nonDebugName(moduleName);
size_t suf = nonDebugName.rfind(templ);
if (suf != FileSystemPath_t::npos)
{
nonDebugName.replace(suf, suf + templ.size(), L".dll");
results.push_back(nonDebugName);
}
}
#endif // _DEBUG && DEBUG_POSTFIX
#else
CV_LOG_INFO(NULL, "VideoIO pluigin (" << baseName << "): glob is '" << plugin_expr << "', " << paths.size() << " location(s)");
for (const string & path : paths)
+1 -1
View File
@@ -114,7 +114,7 @@ CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx,
VideoCapture_IntelMFX* instance = (VideoCapture_IntelMFX*)handle;
Mat img;
if (instance->retrieveFrame(stream_idx, img))
return callback(stream_idx, img.data, img.step, img.cols, img.rows, img.channels(), userdata);
return callback(stream_idx, img.data, (int)img.step, img.cols, img.rows, img.channels(), userdata);
return CV_ERROR_FAIL;
}
catch(...)
+218 -2
View File
@@ -3,7 +3,6 @@
// of this distribution and at http://opencv.org/license.html
#include "precomp.hpp"
#if defined _WIN32 && defined HAVE_MSMF
/*
Media Foundation-based Video Capturing module is based on
videoInput library by Evgeny Pereguda:
@@ -1668,4 +1667,221 @@ cv::Ptr<cv::IVideoWriter> cv::cvCreateVideoWriter_MSMF( const std::string& filen
return cv::Ptr<cv::IVideoWriter>();
}
#endif
#if defined(BUILD_PLUGIN)
#include "plugin_api.hpp"
namespace cv {
typedef CvCapture_MSMF CaptureT;
typedef CvVideoWriter_MSMF WriterT;
static
CvResult CV_API_CALL cv_capture_open(const char* filename, int camera_index, CV_OUT CvPluginCapture* handle)
{
if (!handle)
return CV_ERROR_FAIL;
*handle = NULL;
if (!filename)
return CV_ERROR_FAIL;
CaptureT* cap = 0;
try
{
cap = new CaptureT();
bool res;
if (filename)
res = cap->open(std::string(filename));
else
res = cap->open(camera_index);
if (res)
{
*handle = (CvPluginCapture)cap;
return CV_ERROR_OK;
}
}
catch (...)
{
}
if (cap)
delete cap;
return CV_ERROR_FAIL;
}
static
CvResult CV_API_CALL cv_capture_release(CvPluginCapture handle)
{
if (!handle)
return CV_ERROR_FAIL;
CaptureT* instance = (CaptureT*)handle;
delete instance;
return CV_ERROR_OK;
}
static
CvResult CV_API_CALL cv_capture_get_prop(CvPluginCapture handle, int prop, CV_OUT double* val)
{
if (!handle)
return CV_ERROR_FAIL;
if (!val)
return CV_ERROR_FAIL;
try
{
CaptureT* instance = (CaptureT*)handle;
*val = instance->getProperty(prop);
return CV_ERROR_OK;
}
catch (...)
{
return CV_ERROR_FAIL;
}
}
static
CvResult CV_API_CALL cv_capture_set_prop(CvPluginCapture handle, int prop, double val)
{
if (!handle)
return CV_ERROR_FAIL;
try
{
CaptureT* instance = (CaptureT*)handle;
return instance->setProperty(prop, val) ? CV_ERROR_OK : CV_ERROR_FAIL;
}
catch (...)
{
return CV_ERROR_FAIL;
}
}
static
CvResult CV_API_CALL cv_capture_grab(CvPluginCapture handle)
{
if (!handle)
return CV_ERROR_FAIL;
try
{
CaptureT* instance = (CaptureT*)handle;
return instance->grabFrame() ? CV_ERROR_OK : CV_ERROR_FAIL;
}
catch (...)
{
return CV_ERROR_FAIL;
}
}
static
CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, cv_videoio_retrieve_cb_t callback, void* userdata)
{
if (!handle)
return CV_ERROR_FAIL;
try
{
CaptureT* instance = (CaptureT*)handle;
Mat img;
if (instance->retrieveFrame(stream_idx, img))
return callback(stream_idx, img.data, (int)img.step, img.cols, img.rows, img.channels(), userdata);
return CV_ERROR_FAIL;
}
catch (...)
{
return CV_ERROR_FAIL;
}
}
static
CvResult CV_API_CALL cv_writer_open(const char* filename, int fourcc, double fps, int width, int height, int isColor, CV_OUT CvPluginWriter* handle)
{
WriterT* wrt = 0;
try
{
wrt = new WriterT();
Size sz(width, height);
if (wrt && wrt->open(filename, fourcc, fps, sz, isColor))
{
*handle = (CvPluginWriter)wrt;
return CV_ERROR_OK;
}
}
catch (...)
{
}
if (wrt)
delete wrt;
return CV_ERROR_FAIL;
}
static
CvResult CV_API_CALL cv_writer_release(CvPluginWriter handle)
{
if (!handle)
return CV_ERROR_FAIL;
WriterT* instance = (WriterT*)handle;
delete instance;
return CV_ERROR_OK;
}
static
CvResult CV_API_CALL cv_writer_get_prop(CvPluginWriter /*handle*/, int /*prop*/, CV_OUT double* /*val*/)
{
return CV_ERROR_FAIL;
}
static
CvResult CV_API_CALL cv_writer_set_prop(CvPluginWriter /*handle*/, int /*prop*/, double /*val*/)
{
return CV_ERROR_FAIL;
}
static
CvResult CV_API_CALL cv_writer_write(CvPluginWriter handle, const unsigned char* data, int step, int width, int height, int cn)
{
if (!handle)
return CV_ERROR_FAIL;
try
{
CV_Assert(step >= 0);
WriterT* instance = (WriterT*)handle;
Size sz(width, height);
Mat img(sz, CV_MAKETYPE(CV_8U, cn), (void*)data, (size_t)step);
instance->write(img);
return CV_ERROR_OK;
}
catch (...)
{
return CV_ERROR_FAIL;
}
}
static const OpenCV_VideoIO_Plugin_API_preview plugin_api_v0 =
{
{
sizeof(OpenCV_VideoIO_Plugin_API_preview), ABI_VERSION, API_VERSION,
CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS,
"Microsoft Media Foundation OpenCV Video I/O plugin"
},
/* 1*/CAP_MSMF,
/* 2*/cv_capture_open,
/* 3*/cv_capture_release,
/* 4*/cv_capture_get_prop,
/* 5*/cv_capture_set_prop,
/* 6*/cv_capture_grab,
/* 7*/cv_capture_retrieve,
/* 8*/cv_writer_open,
/* 9*/cv_writer_release,
/* 10*/cv_writer_get_prop,
/* 11*/cv_writer_set_prop,
/* 12*/cv_writer_write
};
} // namespace
const OpenCV_VideoIO_Plugin_API_preview* opencv_videoio_plugin_init_v0(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT
{
if (requested_abi_version != 0)
return NULL;
if (requested_api_version != 0)
return NULL;
return &cv::plugin_api_v0;
}
#endif // BUILD_PLUGIN
+4
View File
@@ -83,9 +83,13 @@ static const struct VideoBackendInfo builtin_backends[] =
#ifdef WINRT_VIDEO
DECLARE_STATIC_BACKEND(CAP_WINRT, "WINRT", MODE_CAPTURE_BY_INDEX, 0, create_WRT_capture, 0),
#endif
#ifdef HAVE_MSMF
DECLARE_STATIC_BACKEND(CAP_MSMF, "MSMF", MODE_CAPTURE_ALL | MODE_WRITER, cvCreateCapture_MSMF, cvCreateCapture_MSMF, cvCreateVideoWriter_MSMF),
#elif defined(ENABLE_PLUGINS)
DECLARE_DYNAMIC_BACKEND(CAP_MSMF, "MSMF", MODE_CAPTURE_ALL | MODE_WRITER),
#endif
#ifdef HAVE_DSHOW
DECLARE_STATIC_BACKEND(CAP_DSHOW, "DSHOW", MODE_CAPTURE_BY_INDEX, 0, create_DShow_capture, 0),
#endif
+2 -2
View File
@@ -323,7 +323,7 @@ static const VideoCaptureAPIs backend_params[] = {
CAP_AVFOUNDATION,
#endif
#ifdef HAVE_MSMF
#ifdef _WIN32
CAP_MSMF,
#endif
@@ -366,7 +366,7 @@ inline static std::ostream &operator<<(std::ostream &out, const Ext_Fourcc_PSNR
static Ext_Fourcc_PSNR synthetic_params[] = {
#ifdef HAVE_MSMF
#ifdef _WIN32
#if !defined(_M_ARM)
{"wmv", "WMV1", 30.f, CAP_MSMF},
{"wmv", "WMV2", 30.f, CAP_MSMF},