diff --git a/modules/videoio/src/backend_plugin.cpp b/modules/videoio/src/backend_plugin.cpp index a37cb872c1f512c34385d776f7b441fffe562367..1cdf4bd14944c639f645dc2e4814c1c2fceb2962 100644 --- a/modules/videoio/src/backend_plugin.cpp +++ b/modules/videoio/src/backend_plugin.cpp @@ -6,6 +6,8 @@ #include "backend.hpp" #include "plugin_api.hpp" +#include "plugin_capture_api.hpp" +#include "plugin_writer_api.hpp" #include "opencv2/core/utils/filesystem.hpp" #include "opencv2/core/utils/configuration.private.hpp" @@ -25,6 +27,8 @@ using namespace std; #include #endif +#include "backend_plugin_legacy.impl.hpp" + namespace cv { namespace impl { #if defined(_WIN32) @@ -164,7 +168,7 @@ public: } void * res = getSymbol_(handle, symbolName); if (!res) - CV_LOG_ERROR(NULL, "No symbol '" << symbolName << "' in " << toPrintablePath(fname)); + CV_LOG_DEBUG(NULL, "No symbol '" << symbolName << "' in " << toPrintablePath(fname)); return res; } const std::string getName() const { return toPrintablePath(fname); } @@ -194,76 +198,168 @@ private: class PluginBackend: public IBackend { -public: - Ptr lib_; - const OpenCV_VideoIO_Plugin_API_preview* plugin_api_; +protected: - PluginBackend(const Ptr& lib) : - lib_(lib), plugin_api_(NULL) + void initCaptureAPI() { - const char* init_name = "opencv_videoio_plugin_init_v0"; - FN_opencv_videoio_plugin_init_t fn_init = reinterpret_cast(lib_->getSymbol(init_name)); + const char* init_name = "opencv_videoio_capture_plugin_init_v1"; + FN_opencv_videoio_capture_plugin_init_t fn_init = reinterpret_cast(lib_->getSymbol(init_name)); if (fn_init) { - for (int supported_api_version = API_VERSION; supported_api_version >= 0; supported_api_version--) + CV_LOG_INFO(NULL, "Found entry: '" << init_name << "'"); + for (int supported_api_version = CAPTURE_API_VERSION; supported_api_version >= 0; supported_api_version--) { - plugin_api_ = fn_init(ABI_VERSION, supported_api_version, NULL); - if (plugin_api_) + capture_api_ = fn_init(CAPTURE_ABI_VERSION, supported_api_version, NULL); + if (capture_api_) break; } - if (!plugin_api_) + if (!capture_api_) { - CV_LOG_INFO(NULL, "Video I/O: plugin is incompatible (can't be initialized): " << lib->getName()); + CV_LOG_INFO(NULL, "Video I/O: plugin is incompatible (can't be initialized): " << lib_->getName()); return; } - if (plugin_api_->api_header.opencv_version_major != CV_VERSION_MAJOR) + if (!checkCompatibility( + capture_api_->api_header, CAPTURE_ABI_VERSION, CAPTURE_API_VERSION, + capture_api_->v0.id != CAP_FFMPEG)) { - CV_LOG_ERROR(NULL, "Video I/O: wrong OpenCV major version used by plugin '" << plugin_api_->api_header.api_description << "': " << - cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", plugin_api_->api_header.opencv_version_major, plugin_api_->api_header.opencv_version_minor)) - plugin_api_ = NULL; + capture_api_ = NULL; return; } -#ifdef HAVE_FFMPEG_WRAPPER - if (plugin_api_->v0.captureAPI == CAP_FFMPEG) + CV_LOG_INFO(NULL, "Video I/O: plugin is ready to use '" << capture_api_->api_header.api_description << "'"); + } + else + { + CV_LOG_INFO(NULL, "Video I/O: missing plugin init function: '" << init_name << "', file: " << lib_->getName()); + } + } + + + void initWriterAPI() + { + const char* init_name = "opencv_videoio_writer_plugin_init_v1"; + FN_opencv_videoio_writer_plugin_init_t fn_init = reinterpret_cast(lib_->getSymbol(init_name)); + if (fn_init) + { + CV_LOG_INFO(NULL, "Found entry: '" << init_name << "'"); + for (int supported_api_version = WRITER_API_VERSION; supported_api_version >= 0; supported_api_version--) { - // no checks for OpenCV minor version + writer_api_ = fn_init(WRITER_ABI_VERSION, supported_api_version, NULL); + if (writer_api_) + break; } - else -#endif - if (plugin_api_->api_header.opencv_version_minor != CV_VERSION_MINOR) + if (!writer_api_) { - CV_LOG_ERROR(NULL, "Video I/O: wrong OpenCV minor version used by plugin '" << plugin_api_->api_header.api_description << "': " << - cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", plugin_api_->api_header.opencv_version_major, plugin_api_->api_header.opencv_version_minor)) - plugin_api_ = NULL; + CV_LOG_INFO(NULL, "Video I/O: plugin is incompatible (can't be initialized): " << lib_->getName()); return; } - CV_LOG_INFO(NULL, "Video I/O: initialized '" << plugin_api_->api_header.api_description << "': built with " - << cv::format("OpenCV %d.%d (ABI/API = %d/%d)", - plugin_api_->api_header.opencv_version_major, plugin_api_->api_header.opencv_version_minor, - plugin_api_->api_header.min_api_version, plugin_api_->api_header.api_version) - << ", current OpenCV version is '" CV_VERSION "' (ABI/API = " << ABI_VERSION << "/" << API_VERSION << ")" - ); - if (plugin_api_->api_header.min_api_version != ABI_VERSION) // future: range can be here + if (!checkCompatibility( + writer_api_->api_header, WRITER_ABI_VERSION, WRITER_API_VERSION, + writer_api_->v0.id != CAP_FFMPEG)) { - // actually this should never happen due to checks in plugin's init() function - CV_LOG_ERROR(NULL, "Video I/O: plugin is not supported due to incompatible ABI = " << plugin_api_->api_header.min_api_version); - plugin_api_ = NULL; + writer_api_ = NULL; return; } - if (plugin_api_->api_header.api_version != API_VERSION) + CV_LOG_INFO(NULL, "Video I/O: plugin is ready to use '" << writer_api_->api_header.api_description << "'"); + } + else + { + CV_LOG_INFO(NULL, "Video I/O: missing plugin init function: '" << init_name << "', file: " << lib_->getName()); + } + } + + + void initPluginLegacyAPI() + { + const char* init_name = "opencv_videoio_plugin_init_v0"; + FN_opencv_videoio_plugin_init_t fn_init = reinterpret_cast(lib_->getSymbol(init_name)); + if (fn_init) + { + CV_LOG_INFO(NULL, "Found entry: '" << init_name << "'"); + for (int supported_api_version = API_VERSION; supported_api_version >= 0; supported_api_version--) { - CV_LOG_INFO(NULL, "Video I/O: NOTE: plugin is supported, but there is API version mismath: " - << cv::format("plugin API level (%d) != OpenCV API level (%d)", plugin_api_->api_header.api_version, API_VERSION)); - if (plugin_api_->api_header.api_version < API_VERSION) - { - CV_LOG_INFO(NULL, "Video I/O: NOTE: some functionality may be unavailable due to lack of support by plugin implementation"); - } + plugin_api_ = fn_init(ABI_VERSION, supported_api_version, NULL); + if (plugin_api_) + break; + } + if (!plugin_api_) + { + CV_LOG_INFO(NULL, "Video I/O: plugin is incompatible (can't be initialized): " << lib_->getName()); + return; + } + if (!checkCompatibility( + plugin_api_->api_header, ABI_VERSION, API_VERSION, + plugin_api_->v0.captureAPI != CAP_FFMPEG)) + { + plugin_api_ = NULL; + return; } CV_LOG_INFO(NULL, "Video I/O: plugin is ready to use '" << plugin_api_->api_header.api_description << "'"); } else { - CV_LOG_INFO(NULL, "Video I/O: plugin is incompatible, missing init function: '" << init_name << "', file: " << lib->getName()); + CV_LOG_INFO(NULL, "Video I/O: plugin is incompatible, missing init function: '" << init_name << "', file: " << lib_->getName()); + } + } + + + bool checkCompatibility(const OpenCV_API_Header& api_header, unsigned int abi_version, unsigned int api_version, bool checkMinorOpenCVVersion) + { + if (api_header.opencv_version_major != CV_VERSION_MAJOR) + { + CV_LOG_ERROR(NULL, "Video I/O: wrong OpenCV major version used by plugin '" << api_header.api_description << "': " << + cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", api_header.opencv_version_major, api_header.opencv_version_minor)) + return false; + } + if (!checkMinorOpenCVVersion) + { + // no checks for OpenCV minor version + } + else if (api_header.opencv_version_minor != CV_VERSION_MINOR) + { + CV_LOG_ERROR(NULL, "Video I/O: wrong OpenCV minor version used by plugin '" << api_header.api_description << "': " << + cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", api_header.opencv_version_major, api_header.opencv_version_minor)) + return false; + } + CV_LOG_INFO(NULL, "Video I/O: initialized '" << api_header.api_description << "': built with " + << cv::format("OpenCV %d.%d (ABI/API = %d/%d)", + api_header.opencv_version_major, api_header.opencv_version_minor, + api_header.min_api_version, api_header.api_version) + << ", current OpenCV version is '" CV_VERSION "' (ABI/API = " << abi_version << "/" << api_version << ")" + ); + if (api_header.min_api_version != abi_version) // future: range can be here + { + // actually this should never happen due to checks in plugin's init() function + CV_LOG_ERROR(NULL, "Video I/O: plugin is not supported due to incompatible ABI = " << api_header.min_api_version); + return false; + } + if (api_header.api_version != api_version) + { + CV_LOG_INFO(NULL, "Video I/O: NOTE: plugin is supported, but there is API version mismath: " + << cv::format("plugin API level (%d) != OpenCV API level (%d)", api_header.api_version, api_version)); + if (api_header.api_version < api_version) + { + CV_LOG_INFO(NULL, "Video I/O: NOTE: some functionality may be unavailable due to lack of support by plugin implementation"); + } + } + return true; + } + +public: + Ptr lib_; + const OpenCV_VideoIO_Capture_Plugin_API* capture_api_; + const OpenCV_VideoIO_Writer_Plugin_API* writer_api_; + const OpenCV_VideoIO_Plugin_API_preview* plugin_api_; //!< deprecated + + PluginBackend(const Ptr& lib) + : lib_(lib) + , capture_api_(NULL), writer_api_(NULL) + , plugin_api_(NULL) + { + initCaptureAPI(); + initWriterAPI(); + if (capture_api_ == NULL && writer_api_ == NULL) + { + initPluginLegacyAPI(); } } @@ -407,20 +503,46 @@ void PluginBackendFactory::loadPlugin() try { Ptr pluginBackend = makePtr(lib); - if (pluginBackend && pluginBackend->plugin_api_) + if (!pluginBackend) + return; + if (pluginBackend->capture_api_) + { + if (pluginBackend->capture_api_->v0.id != id_) + { + CV_LOG_ERROR(NULL, "Video I/O: plugin '" << pluginBackend->capture_api_->api_header.api_description << + "': unexpected backend ID: " << + pluginBackend->capture_api_->v0.id << " vs " << (int)id_ << " (expected)"); + return; + } + } + if (pluginBackend->writer_api_) + { + if (pluginBackend->writer_api_->v0.id != id_) + { + CV_LOG_ERROR(NULL, "Video I/O: plugin '" << pluginBackend->writer_api_->api_header.api_description << + "': unexpected backend ID: " << + pluginBackend->writer_api_->v0.id << " vs " << (int)id_ << " (expected)"); + return; + } + } + if (pluginBackend->plugin_api_) { if (pluginBackend->plugin_api_->v0.captureAPI != id_) { CV_LOG_ERROR(NULL, "Video I/O: plugin '" << pluginBackend->plugin_api_->api_header.api_description << "': unexpected backend ID: " << pluginBackend->plugin_api_->v0.captureAPI << " vs " << (int)id_ << " (expected)"); - } - else - { - backend = pluginBackend; return; } } + if (pluginBackend->capture_api_ == NULL && pluginBackend->writer_api_ == NULL + && pluginBackend->plugin_api_ == NULL) + { + CV_LOG_ERROR(NULL, "Video I/O: no compatible plugin API for backend ID: " << (int)id_); + return; + } + backend = pluginBackend; + return; } catch (...) { @@ -434,16 +556,17 @@ void PluginBackendFactory::loadPlugin() class PluginCapture : public cv::IVideoCapture { - const OpenCV_VideoIO_Plugin_API_preview* plugin_api_; + const OpenCV_VideoIO_Capture_Plugin_API* plugin_api_; CvPluginCapture capture_; public: static - Ptr create(const OpenCV_VideoIO_Plugin_API_preview* plugin_api, + Ptr create(const OpenCV_VideoIO_Capture_Plugin_API* plugin_api, const std::string &filename, int camera) { CV_Assert(plugin_api); CvPluginCapture capture = NULL; + if (plugin_api->v0.Capture_open) { CV_Assert(plugin_api->v0.Capture_release); @@ -456,7 +579,7 @@ public: return Ptr(); } - PluginCapture(const OpenCV_VideoIO_Plugin_API_preview* plugin_api, CvPluginCapture capture) + PluginCapture(const OpenCV_VideoIO_Capture_Plugin_API* plugin_api, CvPluginCapture capture) : plugin_api_(plugin_api), capture_(capture) { CV_Assert(plugin_api_); CV_Assert(capture_); @@ -491,13 +614,13 @@ public: return true; return false; } - static CvResult CV_API_CALL retrieve_callback(int stream_idx, const unsigned char* data, int step, int width, int height, int cn, void* userdata) + static CvResult CV_API_CALL retrieve_callback(int stream_idx, const unsigned char* data, int step, int width, int height, int type, void* userdata) { CV_UNUSED(stream_idx); cv::_OutputArray* dst = static_cast(userdata); if (!dst) return CV_ERROR_FAIL; - cv::Mat(cv::Size(width, height), CV_MAKETYPE(CV_8U, cn), (void*)data, step).copyTo(*dst); + cv::Mat(cv::Size(width, height), type, (void*)data, step).copyTo(*dst); return CV_ERROR_OK; } bool retrieveFrame(int idx, cv::OutputArray img) CV_OVERRIDE @@ -514,7 +637,7 @@ public: } int getCaptureDomain() CV_OVERRIDE { - return plugin_api_->v0.captureAPI; + return plugin_api_->v0.id; } }; @@ -523,12 +646,12 @@ public: class PluginWriter : public cv::IVideoWriter { - const OpenCV_VideoIO_Plugin_API_preview* plugin_api_; + const OpenCV_VideoIO_Writer_Plugin_API* plugin_api_; CvPluginWriter writer_; public: static - Ptr create(const OpenCV_VideoIO_Plugin_API_preview* plugin_api, + Ptr create(const OpenCV_VideoIO_Writer_Plugin_API* plugin_api, const std::string& filename, int fourcc, double fps, const cv::Size& sz, const VideoWriterParameters& params) { @@ -568,7 +691,7 @@ public: return Ptr(); } - PluginWriter(const OpenCV_VideoIO_Plugin_API_preview* plugin_api, CvPluginWriter writer) + PluginWriter(const OpenCV_VideoIO_Writer_Plugin_API* plugin_api, CvPluginWriter writer) : plugin_api_(plugin_api), writer_(writer) { CV_Assert(plugin_api_); CV_Assert(writer_); @@ -613,7 +736,7 @@ public: } int getCaptureDomain() const CV_OVERRIDE { - return plugin_api_->v0.captureAPI; + return plugin_api_->v0.id; } }; @@ -622,8 +745,10 @@ Ptr PluginBackend::createCapture(int camera) const { try { + if (capture_api_) + return PluginCapture::create(capture_api_, std::string(), camera); //.staticCast(); if (plugin_api_) - return PluginCapture::create(plugin_api_, std::string(), camera); //.staticCast(); + return legacy::PluginCapture::create(plugin_api_, std::string(), camera); //.staticCast(); } catch (...) { @@ -636,8 +761,10 @@ Ptr PluginBackend::createCapture(const std::string &filename) con { try { + if (capture_api_) + return PluginCapture::create(capture_api_, filename, 0); //.staticCast(); if (plugin_api_) - return PluginCapture::create(plugin_api_, filename, 0); //.staticCast(); + return legacy::PluginCapture::create(plugin_api_, filename, 0); //.staticCast(); } catch (...) { @@ -651,8 +778,10 @@ Ptr PluginBackend::createWriter(const std::string& filename, int f { try { + if (writer_api_) + return PluginWriter::create(writer_api_, filename, fourcc, fps, sz, params); //.staticCast(); if (plugin_api_) - return PluginWriter::create(plugin_api_, filename, fourcc, fps, sz, params); //.staticCast(); + return legacy::PluginWriter::create(plugin_api_, filename, fourcc, fps, sz, params); //.staticCast(); } catch (...) { diff --git a/modules/videoio/src/backend_plugin_legacy.impl.hpp b/modules/videoio/src/backend_plugin_legacy.impl.hpp index b75d8e0614411dda6cefa2e4afd3b69f81d28d06..fa9def4cc5fc8d115090e295494991dcffdf156c 100644 --- a/modules/videoio/src/backend_plugin_legacy.impl.hpp +++ b/modules/videoio/src/backend_plugin_legacy.impl.hpp @@ -2,7 +2,11 @@ // 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. -// NOT A STANDALONE HEADER +// +// Not a standalone header. +// + +namespace cv { namespace impl { namespace legacy { //================================================================================================== @@ -190,3 +194,6 @@ public: return plugin_api_->v0.captureAPI; } }; + + +}}} // namespace diff --git a/modules/videoio/src/cap_ffmpeg.cpp b/modules/videoio/src/cap_ffmpeg.cpp index 42124c527c97e8d9469e0c2a796decc1c74e1954..e80372106a3880db2bed97948da0439cf0e44676 100644 --- a/modules/videoio/src/cap_ffmpeg.cpp +++ b/modules/videoio/src/cap_ffmpeg.cpp @@ -217,9 +217,20 @@ cv::Ptr cvCreateVideoWriter_FFMPEG_proxy(const std::string& fi #if defined(BUILD_PLUGIN) +#define NEW_PLUGIN + +#ifndef NEW_PLUGIN #define ABI_VERSION 0 #define API_VERSION 0 #include "plugin_api.hpp" +#else +#define CAPTURE_ABI_VERSION 1 +#define CAPTURE_API_VERSION 0 +#include "plugin_capture_api.hpp" +#define WRITER_ABI_VERSION 1 +#define WRITER_API_VERSION 0 +#include "plugin_writer_api.hpp" +#endif namespace cv { @@ -312,6 +323,7 @@ CvResult CV_API_CALL cv_capture_grab(CvPluginCapture handle) } } +#ifndef NEW_PLUGIN static CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, cv_videoio_retrieve_cb_t callback, void* userdata) { @@ -331,6 +343,27 @@ CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, return CV_ERROR_FAIL; } } +#else +static +CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, cv_videoio_capture_retrieve_cb_t callback, void* userdata) +{ + if (!handle) + return CV_ERROR_FAIL; + try + { + CvCapture_FFMPEG_proxy* instance = (CvCapture_FFMPEG_proxy*)handle; + Mat img; + // TODO: avoid unnecessary copying + if (instance->retrieveFrame(stream_idx, img)) + return callback(stream_idx, img.data, img.step, img.cols, img.rows, img.type(), userdata); + return CV_ERROR_FAIL; + } + catch(...) + { + return CV_ERROR_FAIL; + } +} +#endif static CvResult CV_API_CALL cv_writer_open(const char* filename, int fourcc, double fps, int width, int height, int isColor, @@ -395,6 +428,10 @@ CvResult CV_API_CALL cv_writer_write(CvPluginWriter handle, const unsigned char } } +} // namespace + +#ifndef NEW_PLUGIN + static const OpenCV_VideoIO_Plugin_API_preview plugin_api = { { @@ -418,13 +455,64 @@ static const OpenCV_VideoIO_Plugin_API_preview plugin_api = } }; -} // 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 == ABI_VERSION && requested_api_version <= API_VERSION) - return &cv::plugin_api; + return &plugin_api; return NULL; } +#else // NEW_PLUGIN + +static const OpenCV_VideoIO_Capture_Plugin_API capture_plugin_api = +{ + { + sizeof(OpenCV_VideoIO_Capture_Plugin_API), CAPTURE_ABI_VERSION, CAPTURE_API_VERSION, + CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS, + "FFmpeg OpenCV Video I/O Capture plugin" + }, + { + /* 1*/CAP_FFMPEG, + /* 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, + } +}; + +const OpenCV_VideoIO_Capture_Plugin_API* opencv_videoio_capture_plugin_init_v1(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT +{ + if (requested_abi_version == CAPTURE_ABI_VERSION && requested_api_version <= CAPTURE_API_VERSION) + return &capture_plugin_api; + return NULL; +} + +static const OpenCV_VideoIO_Writer_Plugin_API writer_plugin_api = +{ + { + sizeof(OpenCV_VideoIO_Writer_Plugin_API), WRITER_ABI_VERSION, WRITER_API_VERSION, + CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS, + "FFmpeg OpenCV Video I/O Writer plugin" + }, + { + /* 1*/CAP_FFMPEG, + /* 2*/cv_writer_open, + /* 3*/cv_writer_release, + /* 4*/cv_writer_get_prop, + /* 5*/cv_writer_set_prop, + /* 6*/cv_writer_write + } +}; + +const OpenCV_VideoIO_Writer_Plugin_API* opencv_videoio_writer_plugin_init_v1(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT +{ + if (requested_abi_version == WRITER_ABI_VERSION && requested_api_version <= WRITER_API_VERSION) + return &writer_plugin_api; + return NULL; +} + +#endif // NEW_PLUGIN + #endif // BUILD_PLUGIN diff --git a/modules/videoio/src/cap_gstreamer.cpp b/modules/videoio/src/cap_gstreamer.cpp index 4fb4afc362239c0a3ddc0ea4bf063035c11077b8..0c2149f1c38061cade50c1dc3884bce9db5263ee 100644 --- a/modules/videoio/src/cap_gstreamer.cpp +++ b/modules/videoio/src/cap_gstreamer.cpp @@ -1846,9 +1846,12 @@ void handleMessage(GstElement * pipeline) #if defined(BUILD_PLUGIN) -#define ABI_VERSION 0 -#define API_VERSION 1 -#include "plugin_api.hpp" +#define CAPTURE_ABI_VERSION 1 +#define CAPTURE_API_VERSION 0 +#include "plugin_capture_api.hpp" +#define WRITER_ABI_VERSION 1 +#define WRITER_API_VERSION 1 +#include "plugin_writer_api.hpp" namespace cv { @@ -1946,7 +1949,7 @@ CvResult CV_API_CALL cv_capture_grab(CvPluginCapture handle) } static -CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, cv_videoio_retrieve_cb_t callback, void* userdata) +CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, cv_videoio_capture_retrieve_cb_t callback, void* userdata) { if (!handle) return CV_ERROR_FAIL; @@ -1956,7 +1959,7 @@ CvResult CV_API_CALL cv_capture_retrieve(CvPluginCapture handle, int stream_idx, Mat img; // TODO: avoid unnecessary copying - implement lower level GStreamerCapture::retrieve 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, img.step, img.cols, img.rows, img.type(), userdata); return CV_ERROR_FAIL; } catch(...) @@ -2063,12 +2066,12 @@ CvResult CV_API_CALL cv_writer_write(CvPluginWriter handle, const unsigned char } } -static const OpenCV_VideoIO_Plugin_API_preview plugin_api = +static const OpenCV_VideoIO_Capture_Plugin_API capture_api = { { - sizeof(OpenCV_VideoIO_Plugin_API_preview), ABI_VERSION, API_VERSION, + sizeof(OpenCV_VideoIO_Capture_Plugin_API), CAPTURE_ABI_VERSION, CAPTURE_API_VERSION, CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS, - "GStreamer OpenCV Video I/O plugin" + "GStreamer OpenCV Video I/O Capture plugin" }, { /* 1*/CAP_GSTREAMER, @@ -2078,23 +2081,42 @@ static const OpenCV_VideoIO_Plugin_API_preview plugin_api = /* 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 + } +}; + +static const OpenCV_VideoIO_Writer_Plugin_API writer_api = +{ + { + sizeof(OpenCV_VideoIO_Writer_Plugin_API), WRITER_ABI_VERSION, WRITER_API_VERSION, + CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS, + "GStreamer OpenCV Video I/O Writer plugin" }, { - /* 13*/cv_writer_open_with_params + /* 1*/CAP_GSTREAMER, + /* 2*/cv_writer_open, + /* 3*/cv_writer_release, + /* 4*/cv_writer_get_prop, + /* 5*/cv_writer_set_prop, + /* 6*/cv_writer_write + }, + { + /* 7*/cv_writer_open_with_params } }; } // 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 +const OpenCV_VideoIO_Capture_Plugin_API* opencv_videoio_capture_plugin_init_v1(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT +{ + if (requested_abi_version == CAPTURE_ABI_VERSION && requested_api_version <= CAPTURE_API_VERSION) + return &cv::capture_api; + return NULL; +} + +const OpenCV_VideoIO_Writer_Plugin_API* opencv_videoio_writer_plugin_init_v1(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT { - if (requested_abi_version == ABI_VERSION && requested_api_version <= API_VERSION) - return &cv::plugin_api; + if (requested_abi_version == WRITER_ABI_VERSION && requested_api_version <= WRITER_API_VERSION) + return &cv::writer_api; return NULL; } diff --git a/modules/videoio/src/plugin_api.hpp b/modules/videoio/src/plugin_api.hpp index 1281ab57ee2ab19025fbdfbec62191d4438b81a5..011dff5ff65802c944c03484c1a749a2eae56c3b 100644 --- a/modules/videoio/src/plugin_api.hpp +++ b/modules/videoio/src/plugin_api.hpp @@ -2,6 +2,10 @@ // 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. +// +// DEPRECATED. Do not use in new plugins +// + #ifndef PLUGIN_API_HPP #define PLUGIN_API_HPP @@ -129,7 +133,7 @@ struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries /** @brief Get property value - @param handle Capture handle + @param handle Writer handle @param prop Property index @param[out] val property value @@ -139,7 +143,7 @@ struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries /** @brief Set property value - @param handle Capture handle + @param handle Writer handle @param prop Property index @param val property value @@ -149,8 +153,8 @@ struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries /** @brief Write frame - @param handle Capture handle - @param data Capture handle + @param handle Writer handle + @param data frame data @param step step in bytes @param width frame width in pixels @param height frame height diff --git a/modules/videoio/src/plugin_capture_api.hpp b/modules/videoio/src/plugin_capture_api.hpp index 1281ab57ee2ab19025fbdfbec62191d4438b81a5..c18f77685ae4675b2b23e185557a27737ed7b4c1 100644 --- a/modules/videoio/src/plugin_capture_api.hpp +++ b/modules/videoio/src/plugin_capture_api.hpp @@ -2,8 +2,8 @@ // 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 PLUGIN_API_HPP -#define PLUGIN_API_HPP +#ifndef PLUGIN_CAPTURE_API_HPP +#define PLUGIN_CAPTURE_API_HPP #include #include @@ -13,18 +13,18 @@ /// increased for backward-compatible changes, e.g. add new function /// Caller API <= Plugin API -> plugin is fully compatible /// Caller API > Plugin API -> plugin is not fully compatible, caller should use extra checks to use plugins with older API -#define API_VERSION 1 // preview +#define CAPTURE_API_VERSION 0 /// increased for incompatible changes, e.g. remove function argument /// Caller ABI == Plugin ABI -> plugin is compatible /// Caller ABI > Plugin ABI -> plugin is not compatible, caller should use shim code to use old ABI plugins (caller may know how lower ABI works, so it is possible) /// Caller ABI < Plugin ABI -> plugin can't be used (plugin should provide interface with lower ABI to handle that) -#define ABI_VERSION 0 // preview +#define CAPTURE_ABI_VERSION 1 #else // !defined(BUILD_PLUGIN) -#if !defined(ABI_VERSION) || !defined(API_VERSION) -#error "Plugin must define ABI_VERSION and API_VERSION before including plugin_api.hpp" +#if !defined(CAPTURE_ABI_VERSION) || !defined(CAPTURE_API_VERSION) +#error "Plugin must define CAPTURE_ABI_VERSION and CAPTURE_API_VERSION before including plugin_capture_api.hpp" #endif #endif // !defined(BUILD_PLUGIN) @@ -34,17 +34,16 @@ extern "C" { #endif -typedef CvResult (CV_API_CALL *cv_videoio_retrieve_cb_t)(int stream_idx, unsigned const char* data, int step, int width, int height, int cn, void* userdata); +typedef CvResult (CV_API_CALL *cv_videoio_capture_retrieve_cb_t)(int stream_idx, unsigned const char* data, int step, int width, int height, int type, void* userdata); typedef struct CvPluginCapture_t* CvPluginCapture; -typedef struct CvPluginWriter_t* CvPluginWriter; -struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries +struct OpenCV_VideoIO_Capture_Plugin_API_v1_0_api_entries { /** OpenCV capture ID (VideoCaptureAPIs) @note API-ENTRY 1, API-Version == 0 */ - int captureAPI; + int id; /** @brief Open video capture @@ -101,108 +100,43 @@ struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries @note API-CALL 7, API-Version == 0 */ - CvResult (CV_API_CALL *Capture_retreive)(CvPluginCapture handle, int stream_idx, cv_videoio_retrieve_cb_t callback, void* userdata); + CvResult (CV_API_CALL *Capture_retreive)(CvPluginCapture handle, int stream_idx, cv_videoio_capture_retrieve_cb_t callback, void* userdata); +}; // OpenCV_VideoIO_Capture_Plugin_API_v1_0_api_entries - - /** @brief Try to open video writer - - @param filename Destination location - @param fourcc FOURCC code - @param fps FPS - @param width frame width - @param height frame height - @param isColor true if video stream should save color frames - @param[out] handle pointer on Writer handle - - @note API-CALL 8, API-Version == 0 - */ - CvResult (CV_API_CALL *Writer_open)(const char* filename, int fourcc, double fps, int width, int height, int isColor, - CV_OUT CvPluginWriter* handle); - - /** @brief Release Writer handle - - @param handle Writer handle - - @note API-CALL 9, API-Version == 0 - */ - CvResult (CV_API_CALL *Writer_release)(CvPluginWriter handle); - - /** @brief Get property value - - @param handle Capture handle - @param prop Property index - @param[out] val property value - - @note API-CALL 10, API-Version == 0 - */ - CvResult (CV_API_CALL *Writer_getProperty)(CvPluginWriter handle, int prop, CV_OUT double* val); - - /** @brief Set property value - - @param handle Capture handle - @param prop Property index - @param val property value - - @note API-CALL 11, API-Version == 0 - */ - CvResult (CV_API_CALL *Writer_setProperty)(CvPluginWriter handle, int prop, double val); - - /** @brief Write frame - - @param handle Capture handle - @param data Capture handle - @param step step in bytes - @param width frame width in pixels - @param height frame height - @param cn number of channels per pixel - - @note API-CALL 12, API-Version == 0 - */ - CvResult (CV_API_CALL *Writer_write)(CvPluginWriter handle, const unsigned char *data, int step, int width, int height, int cn); -}; // OpenCV_VideoIO_Plugin_API_v0_0_api_entries - -struct OpenCV_VideoIO_Plugin_API_v0_1_api_entries +#if 0 +struct OpenCV_VideoIO_Capture_Plugin_API_v1_1_api_entries { - /** @brief Try to open video writer - - @param filename Destination location - @param fourcc FOURCC code - @param fps FPS - @param width frame width - @param height frame height - @param params pointer on 2*n_params array of 'key,value' pairs - @param n_params number of passed parameters - @param[out] handle pointer on Writer handle - - @note API-CALL 13, API-Version == 1 + /** @brief TBD + + @note API-CALL XXX, API-Version == YYY */ - CvResult (CV_API_CALL* Writer_open_with_params)( - const char* filename, int fourcc, double fps, int width, int height, - int* params, unsigned n_params, - CV_OUT CvPluginWriter* handle + CvResult (CV_API_CALL* zzz)( + ... ); -}; // OpenCV_VideoIO_Plugin_API_v0_1_api_entries +}; // OpenCV_VideoIO_Capture_Plugin_API_v1_1_api_entries +#endif -typedef struct OpenCV_VideoIO_Plugin_API_preview_v0 +typedef struct OpenCV_VideoIO_Capture_Plugin_API_v1_0 { OpenCV_API_Header api_header; - struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries v0; -} OpenCV_VideoIO_Plugin_API_preview_v0; + struct OpenCV_VideoIO_Capture_Plugin_API_v1_0_api_entries v0; +} OpenCV_VideoIO_Capture_Plugin_API_v1_0; -typedef struct OpenCV_VideoIO_Plugin_API_preview_v1 +#if 0 +typedef struct OpenCV_VideoIO_Capture_Plugin_API_v1_1 { OpenCV_API_Header api_header; - struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries v0; - struct OpenCV_VideoIO_Plugin_API_v0_1_api_entries v1; -} OpenCV_VideoIO_Plugin_API_preview_v1; - + struct OpenCV_VideoIO_Capture_Plugin_API_v1_0_api_entries v0; + struct OpenCV_VideoIO_Capture_Plugin_API_v1_1_api_entries v1; +} OpenCV_VideoIO_Capture_Plugin_API_v1_1; +#endif -#if ABI_VERSION == 0 && API_VERSION == 1 -typedef struct OpenCV_VideoIO_Plugin_API_preview_v1 OpenCV_VideoIO_Plugin_API_preview; -#elif ABI_VERSION == 0 && API_VERSION == 0 -typedef struct OpenCV_VideoIO_Plugin_API_preview_v0 OpenCV_VideoIO_Plugin_API_preview; +#if 0 //CAPTURE_ABI_VERSION == 1 && CAPTURE_API_VERSION == 1 +typedef struct OpenCV_VideoIO_Capture_Plugin_API_v1_1 OpenCV_VideoIO_Capture_Plugin_API; +#elif CAPTURE_ABI_VERSION == 1 && CAPTURE_API_VERSION == 0 +typedef struct OpenCV_VideoIO_Capture_Plugin_API_v1_0 OpenCV_VideoIO_Capture_Plugin_API; #else -#error "Not supported configuration: check ABI_VERSION/API_VERSION" +#error "Not supported configuration: check CAPTURE_ABI_VERSION/CAPTURE_API_VERSION" #endif #ifdef BUILD_PLUGIN @@ -216,11 +150,11 @@ typedef struct OpenCV_VideoIO_Plugin_API_preview_v0 OpenCV_VideoIO_Plugin_API_pr #endif CV_PLUGIN_EXPORTS -const OpenCV_VideoIO_Plugin_API_preview* CV_API_CALL opencv_videoio_plugin_init_v0 +const OpenCV_VideoIO_Capture_Plugin_API* CV_API_CALL opencv_videoio_capture_plugin_init_v1 (int requested_abi_version, int requested_api_version, void* reserved /*NULL*/) CV_NOEXCEPT; #else // BUILD_PLUGIN -typedef const OpenCV_VideoIO_Plugin_API_preview* (CV_API_CALL *FN_opencv_videoio_plugin_init_t) +typedef const OpenCV_VideoIO_Capture_Plugin_API* (CV_API_CALL *FN_opencv_videoio_capture_plugin_init_t) (int requested_abi_version, int requested_api_version, void* reserved /*NULL*/); #endif // BUILD_PLUGIN @@ -229,4 +163,4 @@ typedef const OpenCV_VideoIO_Plugin_API_preview* (CV_API_CALL *FN_opencv_videoio } #endif -#endif // PLUGIN_API_HPP +#endif // PLUGIN_CAPTURE_API_HPP diff --git a/modules/videoio/src/plugin_writer_api.hpp b/modules/videoio/src/plugin_writer_api.hpp index 1281ab57ee2ab19025fbdfbec62191d4438b81a5..e1ce014e98347ce62b50acab6c9bc4744b39762f 100644 --- a/modules/videoio/src/plugin_writer_api.hpp +++ b/modules/videoio/src/plugin_writer_api.hpp @@ -2,8 +2,8 @@ // 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 PLUGIN_API_HPP -#define PLUGIN_API_HPP +#ifndef PLUGIN_WRITER_API_HPP +#define PLUGIN_WRITER_API_HPP #include #include @@ -13,18 +13,18 @@ /// increased for backward-compatible changes, e.g. add new function /// Caller API <= Plugin API -> plugin is fully compatible /// Caller API > Plugin API -> plugin is not fully compatible, caller should use extra checks to use plugins with older API -#define API_VERSION 1 // preview +#define WRITER_API_VERSION 1 /// increased for incompatible changes, e.g. remove function argument /// Caller ABI == Plugin ABI -> plugin is compatible /// Caller ABI > Plugin ABI -> plugin is not compatible, caller should use shim code to use old ABI plugins (caller may know how lower ABI works, so it is possible) /// Caller ABI < Plugin ABI -> plugin can't be used (plugin should provide interface with lower ABI to handle that) -#define ABI_VERSION 0 // preview +#define WRITER_ABI_VERSION 1 #else // !defined(BUILD_PLUGIN) -#if !defined(ABI_VERSION) || !defined(API_VERSION) -#error "Plugin must define ABI_VERSION and API_VERSION before including plugin_api.hpp" +#if !defined(WRITER_ABI_VERSION) || !defined(WRITER_API_VERSION) +#error "Plugin must define WRITER_ABI_VERSION and WRITER_API_VERSION before including plugin_writer_api.hpp" #endif #endif // !defined(BUILD_PLUGIN) @@ -34,75 +34,14 @@ extern "C" { #endif -typedef CvResult (CV_API_CALL *cv_videoio_retrieve_cb_t)(int stream_idx, unsigned const char* data, int step, int width, int height, int cn, void* userdata); - -typedef struct CvPluginCapture_t* CvPluginCapture; typedef struct CvPluginWriter_t* CvPluginWriter; -struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries +struct OpenCV_VideoIO_Writer_Plugin_API_v1_0_api_entries { /** OpenCV capture ID (VideoCaptureAPIs) @note API-ENTRY 1, API-Version == 0 */ - int captureAPI; - - /** @brief Open video capture - - @param filename File name or NULL to use camera_index instead - @param camera_index Camera index (used if filename == NULL) - @param[out] handle pointer on Capture handle - - @note API-CALL 2, API-Version == 0 - */ - CvResult (CV_API_CALL *Capture_open)(const char* filename, int camera_index, CV_OUT CvPluginCapture* handle); - - /** @brief Release Capture handle - - @param handle Capture handle - - @note API-CALL 3, API-Version == 0 - */ - CvResult (CV_API_CALL *Capture_release)(CvPluginCapture handle); - - /** @brief Get property value - - @param handle Capture handle - @param prop Property index - @param[out] val property value - - @note API-CALL 4, API-Version == 0 - */ - CvResult (CV_API_CALL *Capture_getProperty)(CvPluginCapture handle, int prop, CV_OUT double* val); - - /** @brief Set property value - - @param handle Capture handle - @param prop Property index - @param val property value - - @note API-CALL 5, API-Version == 0 - */ - CvResult (CV_API_CALL *Capture_setProperty)(CvPluginCapture handle, int prop, double val); - - /** @brief Grab frame - - @param handle Capture handle - - @note API-CALL 6, API-Version == 0 - */ - CvResult (CV_API_CALL *Capture_grab)(CvPluginCapture handle); - - /** @brief Retrieve frame - - @param handle Capture handle - @param stream_idx stream index to retrieve (BGR/IR/depth data) - @param callback retrieve callback (synchronous) - @param userdata callback context data - - @note API-CALL 7, API-Version == 0 - */ - CvResult (CV_API_CALL *Capture_retreive)(CvPluginCapture handle, int stream_idx, cv_videoio_retrieve_cb_t callback, void* userdata); - + int id; /** @brief Try to open video writer @@ -114,7 +53,7 @@ struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries @param isColor true if video stream should save color frames @param[out] handle pointer on Writer handle - @note API-CALL 8, API-Version == 0 + @note API-CALL 2, API-Version == 0 */ CvResult (CV_API_CALL *Writer_open)(const char* filename, int fourcc, double fps, int width, int height, int isColor, CV_OUT CvPluginWriter* handle); @@ -123,45 +62,45 @@ struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries @param handle Writer handle - @note API-CALL 9, API-Version == 0 + @note API-CALL 3, API-Version == 0 */ CvResult (CV_API_CALL *Writer_release)(CvPluginWriter handle); /** @brief Get property value - @param handle Capture handle + @param handle Writer handle @param prop Property index @param[out] val property value - @note API-CALL 10, API-Version == 0 + @note API-CALL 4, API-Version == 0 */ CvResult (CV_API_CALL *Writer_getProperty)(CvPluginWriter handle, int prop, CV_OUT double* val); /** @brief Set property value - @param handle Capture handle + @param handle Writer handle @param prop Property index @param val property value - @note API-CALL 11, API-Version == 0 + @note API-CALL 5, API-Version == 0 */ CvResult (CV_API_CALL *Writer_setProperty)(CvPluginWriter handle, int prop, double val); /** @brief Write frame - @param handle Capture handle - @param data Capture handle + @param handle Writer handle + @param data frame data @param step step in bytes @param width frame width in pixels @param height frame height @param cn number of channels per pixel - @note API-CALL 12, API-Version == 0 + @note API-CALL 6, API-Version == 0 */ CvResult (CV_API_CALL *Writer_write)(CvPluginWriter handle, const unsigned char *data, int step, int width, int height, int cn); -}; // OpenCV_VideoIO_Plugin_API_v0_0_api_entries +}; // OpenCV_VideoIO_Writer_Plugin_API_v1_0_api_entries -struct OpenCV_VideoIO_Plugin_API_v0_1_api_entries +struct OpenCV_VideoIO_Writer_Plugin_API_v1_1_api_entries { /** @brief Try to open video writer @@ -174,35 +113,35 @@ struct OpenCV_VideoIO_Plugin_API_v0_1_api_entries @param n_params number of passed parameters @param[out] handle pointer on Writer handle - @note API-CALL 13, API-Version == 1 + @note API-CALL 7, API-Version == 1 */ CvResult (CV_API_CALL* Writer_open_with_params)( const char* filename, int fourcc, double fps, int width, int height, int* params, unsigned n_params, CV_OUT CvPluginWriter* handle ); -}; // OpenCV_VideoIO_Plugin_API_v0_1_api_entries +}; // OpenCV_VideoIO_Writer_Plugin_API_v1_1_api_entries -typedef struct OpenCV_VideoIO_Plugin_API_preview_v0 +typedef struct OpenCV_VideoIO_Writer_Plugin_API_v1_0 { OpenCV_API_Header api_header; - struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries v0; -} OpenCV_VideoIO_Plugin_API_preview_v0; + struct OpenCV_VideoIO_Writer_Plugin_API_v1_0_api_entries v0; +} OpenCV_VideoIO_Writer_Plugin_API_v1_0; -typedef struct OpenCV_VideoIO_Plugin_API_preview_v1 +typedef struct OpenCV_VideoIO_Writer_Plugin_API_v1_1 { OpenCV_API_Header api_header; - struct OpenCV_VideoIO_Plugin_API_v0_0_api_entries v0; - struct OpenCV_VideoIO_Plugin_API_v0_1_api_entries v1; -} OpenCV_VideoIO_Plugin_API_preview_v1; + struct OpenCV_VideoIO_Writer_Plugin_API_v1_0_api_entries v0; + struct OpenCV_VideoIO_Writer_Plugin_API_v1_1_api_entries v1; +} OpenCV_VideoIO_Writer_Plugin_API_v1_1; -#if ABI_VERSION == 0 && API_VERSION == 1 -typedef struct OpenCV_VideoIO_Plugin_API_preview_v1 OpenCV_VideoIO_Plugin_API_preview; -#elif ABI_VERSION == 0 && API_VERSION == 0 -typedef struct OpenCV_VideoIO_Plugin_API_preview_v0 OpenCV_VideoIO_Plugin_API_preview; +#if WRITER_ABI_VERSION == 1 && WRITER_API_VERSION == 1 +typedef struct OpenCV_VideoIO_Writer_Plugin_API_v1_1 OpenCV_VideoIO_Writer_Plugin_API; +#elif WRITER_ABI_VERSION == 1 && WRITER_API_VERSION == 0 +typedef struct OpenCV_VideoIO_Writer_Plugin_API_v1_0 OpenCV_VideoIO_Writer_Plugin_API; #else -#error "Not supported configuration: check ABI_VERSION/API_VERSION" +#error "Not supported configuration: check WRITER_ABI_VERSION/WRITER_API_VERSION" #endif #ifdef BUILD_PLUGIN @@ -216,11 +155,11 @@ typedef struct OpenCV_VideoIO_Plugin_API_preview_v0 OpenCV_VideoIO_Plugin_API_pr #endif CV_PLUGIN_EXPORTS -const OpenCV_VideoIO_Plugin_API_preview* CV_API_CALL opencv_videoio_plugin_init_v0 +const OpenCV_VideoIO_Writer_Plugin_API* CV_API_CALL opencv_videoio_writer_plugin_init_v1 (int requested_abi_version, int requested_api_version, void* reserved /*NULL*/) CV_NOEXCEPT; #else // BUILD_PLUGIN -typedef const OpenCV_VideoIO_Plugin_API_preview* (CV_API_CALL *FN_opencv_videoio_plugin_init_t) +typedef const OpenCV_VideoIO_Writer_Plugin_API* (CV_API_CALL *FN_opencv_videoio_writer_plugin_init_t) (int requested_abi_version, int requested_api_version, void* reserved /*NULL*/); #endif // BUILD_PLUGIN @@ -229,4 +168,4 @@ typedef const OpenCV_VideoIO_Plugin_API_preview* (CV_API_CALL *FN_opencv_videoio } #endif -#endif // PLUGIN_API_HPP +#endif // PLUGIN_WRITER_API_HPP