From 467870415bbc9767c632e5c038efb1bd0755c813 Mon Sep 17 00:00:00 2001 From: MaximMilashchenko <67949029+MaximMilashchenko@users.noreply.github.com> Date: Thu, 28 Jan 2021 01:07:43 +0300 Subject: [PATCH] Merge pull request #19394 from MaximMilashchenko:params add video capture parameters * add parameters * videoio: revert unnecessary massive changes * videoio: support capture parameters in backends API - add tests - FFmpeg backend sample code - StaticBackend API is done - support through PluginBackend API will be added later Co-authored-by: Milashchenko Co-authored-by: Alexander Alekhin --- modules/videoio/include/opencv2/videoio.hpp | 42 +++++++++++ modules/videoio/misc/objc/gen_dict.json | 3 +- modules/videoio/src/backend.hpp | 11 ++- modules/videoio/src/backend_plugin.cpp | 30 +++++++- modules/videoio/src/backend_static.cpp | 113 +++++++++++++++++++++++++++- modules/videoio/src/cap.cpp | 32 +++++++- modules/videoio/src/cap_ffmpeg.cpp | 34 ++++++++- modules/videoio/src/cap_interface.hpp | 97 ++++++++++++++++++++---- modules/videoio/test/test_camera.cpp | 35 +++++++++ modules/videoio/test/test_ffmpeg.cpp | 59 +++++++++++++++ 10 files changed, 427 insertions(+), 29 deletions(-) diff --git a/modules/videoio/include/opencv2/videoio.hpp b/modules/videoio/include/opencv2/videoio.hpp index 7beb810..c8067e9 100644 --- a/modules/videoio/include/opencv2/videoio.hpp +++ b/modules/videoio/include/opencv2/videoio.hpp @@ -652,6 +652,14 @@ public: CV_WRAP explicit VideoCapture(const String& filename, int apiPreference = CAP_ANY); /** @overload + @brief Opens a video file or a capturing device or an IP video stream for video capturing with API Preference and parameters + + The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`. + See cv::VideoCaptureProperties + */ + CV_WRAP explicit VideoCapture(const String& filename, int apiPreference, const std::vector& params); + + /** @overload @brief Opens a camera for video capturing @param index id of the video capturing device to open. To open default camera using default backend just pass 0. @@ -663,6 +671,14 @@ public: */ CV_WRAP explicit VideoCapture(int index, int apiPreference = CAP_ANY); + /** @overload + @brief Opens a camera for video capturing with API Preference and parameters + + The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`. + See cv::VideoCaptureProperties + */ + CV_WRAP explicit VideoCapture(int index, int apiPreference, const std::vector& params); + /** @brief Default destructor The method first calls VideoCapture::release to close the already opened file or camera. @@ -684,6 +700,19 @@ public: @overload + The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`. + See cv::VideoCaptureProperties + + @return `true` if the file has been successfully opened + + The method first calls VideoCapture::release to close the already opened file or camera. + */ + CV_WRAP virtual bool open(const String& filename, int apiPreference, const std::vector& params); + + /** @brief Opens a camera for video capturing + + @overload + Parameters are same as the constructor VideoCapture(int index, int apiPreference = CAP_ANY) @return `true` if the camera has been successfully opened. @@ -693,6 +722,19 @@ public: /** @brief Returns true if video capturing has been initialized already. + @overload + + The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`. + See cv::VideoCaptureProperties + + @return `true` if the camera has been successfully opened. + + The method first calls VideoCapture::release to close the already opened file or camera. + */ + CV_WRAP virtual bool open(int index, int apiPreference, const std::vector& params); + + /** @brief Returns true if video capturing has been initialized already. + If the previous call to VideoCapture constructor or VideoCapture::open() succeeded, the method returns true. */ diff --git a/modules/videoio/misc/objc/gen_dict.json b/modules/videoio/misc/objc/gen_dict.json index e71c9ec..70dc844 100644 --- a/modules/videoio/misc/objc/gen_dict.json +++ b/modules/videoio/misc/objc/gen_dict.json @@ -13,7 +13,8 @@ }, "func_arg_fix" : { "VideoCapture" : { - "(BOOL)open:(int)index apiPreference:(int)apiPreference" : { "open" : {"name" : "openWithIndex"} } + "(BOOL)open:(int)index apiPreference:(int)apiPreference" : { "open" : {"name" : "openWithIndex"} }, + "(BOOL)open:(int)index apiPreference:(int)apiPreference params:(IntVector*)params" : { "open" : {"name" : "openWithIndexAndParameters"} } } } } diff --git a/modules/videoio/src/backend.hpp b/modules/videoio/src/backend.hpp index 1b2a1e6..ecf0e0d 100644 --- a/modules/videoio/src/backend.hpp +++ b/modules/videoio/src/backend.hpp @@ -16,8 +16,8 @@ class IBackend { public: virtual ~IBackend() {} - virtual Ptr createCapture(int camera) const = 0; - virtual Ptr createCapture(const std::string &filename) const = 0; + virtual Ptr createCapture(int camera, const VideoCaptureParameters& params) const = 0; + virtual Ptr createCapture(const std::string &filename, const VideoCaptureParameters& params) const = 0; virtual Ptr createWriter(const std::string& filename, int fourcc, double fps, const cv::Size& sz, const VideoWriterParameters& params) const = 0; }; @@ -33,14 +33,21 @@ public: typedef Ptr (*FN_createCaptureFile)(const std::string & filename); typedef Ptr (*FN_createCaptureCamera)(int camera); +typedef Ptr (*FN_createCaptureFileWithParams)(const std::string & filename, const VideoCaptureParameters& params); +typedef Ptr (*FN_createCaptureCameraWithParams)(int camera, const VideoCaptureParameters& params); typedef Ptr (*FN_createWriter)(const std::string& filename, int fourcc, double fps, const Size& sz, const VideoWriterParameters& params); Ptr createBackendFactory(FN_createCaptureFile createCaptureFile, FN_createCaptureCamera createCaptureCamera, FN_createWriter createWriter); +Ptr createBackendFactory(FN_createCaptureFileWithParams createCaptureFile, + FN_createCaptureCameraWithParams createCaptureCamera, + FN_createWriter createWriter); Ptr createPluginBackendFactory(VideoCaptureAPIs id, const char* baseName); +void applyParametersFallback(const Ptr& cap, const VideoCaptureParameters& params); + } // namespace cv:: #endif // BACKEND_HPP_DEFINED diff --git a/modules/videoio/src/backend_plugin.cpp b/modules/videoio/src/backend_plugin.cpp index 1cdf4bd..91270d9 100644 --- a/modules/videoio/src/backend_plugin.cpp +++ b/modules/videoio/src/backend_plugin.cpp @@ -363,8 +363,10 @@ public: } } - Ptr createCapture(int camera) const CV_OVERRIDE; - Ptr createCapture(const std::string &filename) const CV_OVERRIDE; + Ptr createCapture(int camera) const; + Ptr createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE; + Ptr createCapture(const std::string &filename) const; + Ptr createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE; Ptr createWriter(const std::string& filename, int fourcc, double fps, const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE; }; @@ -753,10 +755,22 @@ Ptr PluginBackend::createCapture(int camera) const catch (...) { CV_LOG_DEBUG(NULL, "Video I/O: can't create camera capture: " << camera); + throw; } return Ptr(); } +Ptr PluginBackend::createCapture(int camera, const VideoCaptureParameters& params) const +{ + // TODO Update plugins API to support parameters + Ptr cap = createCapture(camera); + if (cap && !params.empty()) + { + applyParametersFallback(cap, params); + } + return cap; +} + Ptr PluginBackend::createCapture(const std::string &filename) const { try @@ -769,10 +783,22 @@ Ptr PluginBackend::createCapture(const std::string &filename) con catch (...) { CV_LOG_DEBUG(NULL, "Video I/O: can't open file capture: " << filename); + throw; } return Ptr(); } +Ptr PluginBackend::createCapture(const std::string &filename, const VideoCaptureParameters& params) const +{ + // TODO Update plugins API to support parameters + Ptr cap = createCapture(filename); + if (cap && !params.empty()) + { + applyParametersFallback(cap, params); + } + return cap; +} + Ptr PluginBackend::createWriter(const std::string& filename, int fourcc, double fps, const cv::Size& sz, const VideoWriterParameters& params) const { diff --git a/modules/videoio/src/backend_static.cpp b/modules/videoio/src/backend_static.cpp index 5676286..1d23c28 100644 --- a/modules/videoio/src/backend_static.cpp +++ b/modules/videoio/src/backend_static.cpp @@ -8,6 +8,28 @@ namespace cv { + +void applyParametersFallback(const Ptr& cap, const VideoCaptureParameters& params) +{ + std::vector props = params.getUnused(); + CV_LOG_INFO(NULL, "VIDEOIO: Backend '" << videoio_registry::getBackendName((VideoCaptureAPIs)cap->getCaptureDomain()) << + "' implementation doesn't support parameters in .open(). Applying " << + props.size() << " properties through .setProperty()"); + for (int prop : props) + { + double value = params.get(prop, -1); + CV_LOG_INFO(NULL, "VIDEOIO: apply parameter: [" << prop << "]=" << + cv::format("%g / %lld / 0x%16llx", value, (long long)value, (long long)value)); + if (!cap->setProperty(prop, value)) + { + CV_Error_(cv::Error::StsNotImplemented, ("VIDEOIO: Failed to apply invalid or unsupported parameter: [%d]=%g / %lld / 0x%08llx", prop, value, (long long)value, (long long)value)); + } + } + // NB: there is no dedicated "commit" parameters event, implementations should commit after each property automatically +} + + +// Legacy API. Modern API with parameters is below class StaticBackend: public IBackend { public: @@ -20,18 +42,33 @@ public: { // nothing } + ~StaticBackend() CV_OVERRIDE {} - Ptr createCapture(int camera) const CV_OVERRIDE + Ptr createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE { if (fn_createCaptureCamera_) - return fn_createCaptureCamera_(camera); + { + Ptr cap = fn_createCaptureCamera_(camera); + if (cap && !params.empty()) + { + applyParametersFallback(cap, params); + } + return cap; + } return Ptr(); } - Ptr createCapture(const std::string &filename) const CV_OVERRIDE + Ptr createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE { if (fn_createCaptureFile_) - return fn_createCaptureFile_(filename); + { + Ptr cap = fn_createCaptureFile_(filename); + if (cap && !params.empty()) + { + applyParametersFallback(cap, params); + } + return cap; + } return Ptr(); } Ptr createWriter(const std::string& filename, int fourcc, double fps, @@ -63,6 +100,7 @@ public: } }; + Ptr createBackendFactory(FN_createCaptureFile createCaptureFile, FN_createCaptureCamera createCaptureCamera, FN_createWriter createWriter) @@ -70,4 +108,71 @@ Ptr createBackendFactory(FN_createCaptureFile createCaptureFile return makePtr(createCaptureFile, createCaptureCamera, createWriter).staticCast(); } + + +class StaticBackendWithParams: public IBackend +{ +public: + FN_createCaptureFileWithParams fn_createCaptureFile_; + FN_createCaptureCameraWithParams fn_createCaptureCamera_; + FN_createWriter fn_createWriter_; + + StaticBackendWithParams(FN_createCaptureFileWithParams fn_createCaptureFile, FN_createCaptureCameraWithParams fn_createCaptureCamera, FN_createWriter fn_createWriter) + : fn_createCaptureFile_(fn_createCaptureFile), fn_createCaptureCamera_(fn_createCaptureCamera), fn_createWriter_(fn_createWriter) + { + // nothing + } + + ~StaticBackendWithParams() CV_OVERRIDE {} + + Ptr createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE + { + if (fn_createCaptureCamera_) + return fn_createCaptureCamera_(camera, params); + return Ptr(); + } + Ptr createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE + { + if (fn_createCaptureFile_) + return fn_createCaptureFile_(filename, params); + return Ptr(); + } + Ptr createWriter(const std::string& filename, int fourcc, double fps, + const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE + { + if (fn_createWriter_) + return fn_createWriter_(filename, fourcc, fps, sz, params); + return Ptr(); + } +}; // StaticBackendWithParams + +class StaticBackendWithParamsFactory : public IBackendFactory +{ +protected: + Ptr backend; + +public: + StaticBackendWithParamsFactory(FN_createCaptureFileWithParams createCaptureFile, FN_createCaptureCameraWithParams createCaptureCamera, FN_createWriter createWriter) + : backend(makePtr(createCaptureFile, createCaptureCamera, createWriter)) + { + // nothing + } + + ~StaticBackendWithParamsFactory() CV_OVERRIDE {} + + Ptr getBackend() const CV_OVERRIDE + { + return backend.staticCast(); + } +}; + + +Ptr createBackendFactory(FN_createCaptureFileWithParams createCaptureFile, + FN_createCaptureCameraWithParams createCaptureCamera, + FN_createWriter createWriter) +{ + return makePtr(createCaptureFile, createCaptureCamera, createWriter).staticCast(); +} + + } // namespace diff --git a/modules/videoio/src/cap.cpp b/modules/videoio/src/cap.cpp index 77a2c36..f0afc1f 100644 --- a/modules/videoio/src/cap.cpp +++ b/modules/videoio/src/cap.cpp @@ -75,12 +75,26 @@ VideoCapture::VideoCapture(const String& filename, int apiPreference) : throwOnF open(filename, apiPreference); } +VideoCapture::VideoCapture(const String& filename, int apiPreference, const std::vector& params) + : throwOnFail(true) +{ + CV_TRACE_FUNCTION(); + open(filename, apiPreference, params); +} + VideoCapture::VideoCapture(int index, int apiPreference) : throwOnFail(false) { CV_TRACE_FUNCTION(); open(index, apiPreference); } +VideoCapture::VideoCapture(int index, int apiPreference, const std::vector& params) + : throwOnFail(true) +{ + CV_TRACE_FUNCTION(); + open(index, apiPreference, params); +} + VideoCapture::~VideoCapture() { CV_TRACE_FUNCTION(); @@ -89,13 +103,19 @@ VideoCapture::~VideoCapture() bool VideoCapture::open(const String& filename, int apiPreference) { - CV_TRACE_FUNCTION(); + return open(filename, apiPreference, std::vector()); +} + +bool VideoCapture::open(const String& filename, int apiPreference, const std::vector& params) +{ + CV_INSTRUMENT_REGION(); if (isOpened()) { release(); } + const VideoCaptureParameters parameters(params); const std::vector backends = cv::videoio_registry::getAvailableBackends_CaptureByFilename(); for (size_t i = 0; i < backends.size(); i++) { @@ -112,7 +132,7 @@ bool VideoCapture::open(const String& filename, int apiPreference) { try { - icap = backend->createCapture(filename); + icap = backend->createCapture(filename, parameters); if (!icap.empty()) { CV_CAPTURE_LOG_DEBUG(NULL, @@ -182,6 +202,11 @@ bool VideoCapture::open(const String& filename, int apiPreference) bool VideoCapture::open(int cameraNum, int apiPreference) { + return open(cameraNum, apiPreference, std::vector()); +} + +bool VideoCapture::open(int cameraNum, int apiPreference, const std::vector& params) +{ CV_TRACE_FUNCTION(); if (isOpened()) @@ -200,6 +225,7 @@ bool VideoCapture::open(int cameraNum, int apiPreference) } } + const VideoCaptureParameters parameters(params); const std::vector backends = cv::videoio_registry::getAvailableBackends_CaptureByIndex(); for (size_t i = 0; i < backends.size(); i++) { @@ -216,7 +242,7 @@ bool VideoCapture::open(int cameraNum, int apiPreference) { try { - icap = backend->createCapture(cameraNum); + icap = backend->createCapture(cameraNum, parameters); if (!icap.empty()) { CV_CAPTURE_LOG_DEBUG(NULL, diff --git a/modules/videoio/src/cap_ffmpeg.cpp b/modules/videoio/src/cap_ffmpeg.cpp index e803721..07f9998 100644 --- a/modules/videoio/src/cap_ffmpeg.cpp +++ b/modules/videoio/src/cap_ffmpeg.cpp @@ -67,7 +67,11 @@ class CvCapture_FFMPEG_proxy CV_FINAL : public cv::IVideoCapture { public: CvCapture_FFMPEG_proxy() { ffmpegCapture = 0; } - CvCapture_FFMPEG_proxy(const cv::String& filename) { ffmpegCapture = 0; open(filename); } + CvCapture_FFMPEG_proxy(const cv::String& filename, const cv::VideoCaptureParameters& params) + : ffmpegCapture(NULL) + { + open(filename, params); + } virtual ~CvCapture_FFMPEG_proxy() { close(); } virtual double getProperty(int propId) const CV_OVERRIDE @@ -104,6 +108,28 @@ public: ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename.c_str() ); return ffmpegCapture != 0; } + bool open(const cv::String& filename, const cv::VideoCaptureParameters& params) + { + close(); + + ffmpegCapture = icvCreateFileCapture_FFMPEG_p(filename.c_str()); + if (ffmpegCapture && !params.empty()) + { + if (params.has(CAP_PROP_FORMAT)) // just a sample code + { + int value = params.get(CAP_PROP_FORMAT); + if (!setProperty(CAP_PROP_FORMAT, value)) + { + CV_Error_(Error::StsBadArg, ("VIDEOIO/FFMPEG: CAP_PROP_FORMAT parameter value is invalid/unsupported: %d", value)); + } + } + if (params.warnUnusedParameters()) + { + CV_Error(Error::StsBadArg, "VIDEOIO/FFMPEG: unsupported parameters in .open(), see logger INFO channel for details"); + } + } + return ffmpegCapture != 0; + } virtual void close() { if (ffmpegCapture) @@ -145,9 +171,9 @@ protected: } // namespace -cv::Ptr cvCreateFileCapture_FFMPEG_proxy(const std::string &filename) +cv::Ptr cvCreateFileCapture_FFMPEG_proxy(const std::string &filename, const cv::VideoCaptureParameters& params) { - cv::Ptr capture = cv::makePtr(filename); + cv::Ptr capture = cv::makePtr(filename, params); if (capture && capture->isOpened()) return capture; return cv::Ptr(); @@ -246,7 +272,7 @@ CvResult CV_API_CALL cv_capture_open(const char* filename, int camera_index, CV_ CvCapture_FFMPEG_proxy *cap = 0; try { - cap = new CvCapture_FFMPEG_proxy(filename); + cap = new CvCapture_FFMPEG_proxy(filename, cv::VideoCaptureParameters()); if (cap->isOpened()) { *handle = (CvPluginCapture)cap; diff --git a/modules/videoio/src/cap_interface.hpp b/modules/videoio/src/cap_interface.hpp index 720fb0b..bc80300 100644 --- a/modules/videoio/src/cap_interface.hpp +++ b/modules/videoio/src/cap_interface.hpp @@ -52,22 +52,22 @@ inline bool castParameterTo(int paramValue) } } -class VideoWriterParameters +class VideoParameters { public: - struct VideoWriterParameter { - VideoWriterParameter() = default; + struct VideoParameter { + VideoParameter() = default; - VideoWriterParameter(int key_, int value_) : key(key_), value(value_) {} + VideoParameter(int key_, int value_) : key(key_), value(value_) {} int key{-1}; int value{-1}; mutable bool isConsumed{false}; }; - VideoWriterParameters() = default; + VideoParameters() = default; - explicit VideoWriterParameters(const std::vector& params) + explicit VideoParameters(const std::vector& params) { const auto count = params.size(); if (count % 2 != 0) @@ -87,13 +87,46 @@ public: params_.emplace_back(key, value); } + bool has(int key) const + { + auto it = std::find_if(params_.begin(), params_.end(), + [key](const VideoParameter ¶m) + { + return param.key == key; + } + ); + return it != params_.end(); + } + template - ValueType get(int key, ValueType defaultValue) const CV_NOEXCEPT + ValueType get(int key) const { auto it = std::find_if(params_.begin(), params_.end(), - [key](const VideoWriterParameter ¶m) { - return param.key == key; - }); + [key](const VideoParameter ¶m) + { + return param.key == key; + } + ); + if (it != params_.end()) + { + it->isConsumed = true; + return castParameterTo(it->value); + } + else + { + CV_Error_(Error::StsBadArg, ("Missing value for parameter: [%d]", key)); + } + } + + template + ValueType get(int key, ValueType defaultValue) const + { + auto it = std::find_if(params_.begin(), params_.end(), + [key](const VideoParameter ¶m) + { + return param.key == key; + } + ); if (it != params_.end()) { it->isConsumed = true; @@ -105,7 +138,8 @@ public: } } - std::vector getUnused() const CV_NOEXCEPT { + std::vector getUnused() const + { std::vector unusedParams; for (const auto ¶m : params_) { @@ -128,8 +162,45 @@ public: return vint_params; } + bool empty() const + { + return params_.empty(); + } + + bool warnUnusedParameters() const + { + bool found = false; + for (const auto ¶m : params_) + { + if (!param.isConsumed) + { + found = true; + CV_LOG_INFO(NULL, "VIDEOIO: unused parameter: [" << param.key << "]=" << + cv::format("%lld / 0x%16llx", (long long)param.value, (long long)param.value)); + } + } + return found; + } + + private: - std::vector params_; + std::vector params_; +}; + +class VideoWriterParameters : public VideoParameters +{ +public: + VideoWriterParameters() = default; + + explicit VideoWriterParameters(const std::vector& params) : VideoParameters(params) {}; +}; + +class VideoCaptureParameters : public VideoParameters +{ +public: + VideoCaptureParameters() = default; + + explicit VideoCaptureParameters(const std::vector& params) : VideoParameters(params) {}; }; class IVideoCapture @@ -261,7 +332,7 @@ public: //================================================================================================== -Ptr cvCreateFileCapture_FFMPEG_proxy(const std::string &filename); +Ptr cvCreateFileCapture_FFMPEG_proxy(const std::string &filename, const cv::VideoCaptureParameters& params); Ptr cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); diff --git a/modules/videoio/test/test_camera.cpp b/modules/videoio/test/test_camera.cpp index 884390e..274c822 100644 --- a/modules/videoio/test/test_camera.cpp +++ b/modules/videoio/test/test_camera.cpp @@ -87,6 +87,41 @@ TEST(DISABLED_videoio_camera, v4l_read_mjpg) capture.release(); } +TEST(DISABLED_videoio_camera, v4l_open_mjpg) +{ + VideoCapture capture; + capture.open(0, CAP_V4L2, { + CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G') + }); + ASSERT_TRUE(capture.isOpened()); + std::cout << "Camera 0 via " << capture.getBackendName() << " backend" << std::endl; + std::cout << "Frame width: " << capture.get(CAP_PROP_FRAME_WIDTH) << std::endl; + std::cout << " height: " << capture.get(CAP_PROP_FRAME_HEIGHT) << std::endl; + std::cout << "Capturing FPS: " << capture.get(CAP_PROP_FPS) << std::endl; + int fourcc = (int)capture.get(CAP_PROP_FOURCC); + std::cout << "FOURCC code: " << cv::format("0x%8x", fourcc) << std::endl; + test_readFrames(capture); + capture.release(); +} + +TEST(DISABLED_videoio_camera, v4l_open_mjpg_1280x720) +{ + VideoCapture capture(0, CAP_V4L2, { + CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'), + CAP_PROP_FRAME_WIDTH, 1280, + CAP_PROP_FRAME_HEIGHT, 720, + }); + ASSERT_TRUE(capture.isOpened()); + std::cout << "Camera 0 via " << capture.getBackendName() << " backend" << std::endl; + std::cout << "Frame width: " << capture.get(CAP_PROP_FRAME_WIDTH) << std::endl; + std::cout << " height: " << capture.get(CAP_PROP_FRAME_HEIGHT) << std::endl; + std::cout << "Capturing FPS: " << capture.get(CAP_PROP_FPS) << std::endl; + int fourcc = (int)capture.get(CAP_PROP_FOURCC); + std::cout << "FOURCC code: " << cv::format("0x%8x", fourcc) << std::endl; + test_readFrames(capture); + capture.release(); +} + //Following test if for capture device using PhysConn_Video_SerialDigital as crossbar input pin TEST(DISABLED_videoio_camera, channel6) { diff --git a/modules/videoio/test/test_ffmpeg.cpp b/modules/videoio/test/test_ffmpeg.cpp index 4bda7f3..84c34ec 100644 --- a/modules/videoio/test/test_ffmpeg.cpp +++ b/modules/videoio/test/test_ffmpeg.cpp @@ -459,4 +459,63 @@ TEST(videoio, mp4_orientation_no_rotation) ASSERT_EQ(384, frame.rows); } + +static void ffmpeg_check_read_raw(VideoCapture& cap) +{ + ASSERT_TRUE(cap.isOpened()) << "Can't open the video"; + + Mat data; + cap >> data; + EXPECT_EQ(CV_8UC1, data.type()) << "CV_8UC1 != " << typeToString(data.type()); + EXPECT_TRUE(data.rows == 1 || data.cols == 1) << data.size; + EXPECT_EQ((size_t)29729, data.total()); + + cap >> data; + EXPECT_EQ(CV_8UC1, data.type()) << "CV_8UC1 != " << typeToString(data.type()); + EXPECT_TRUE(data.rows == 1 || data.cols == 1) << data.size; + EXPECT_EQ((size_t)37118, data.total()); +} + +TEST(videoio_ffmpeg, open_with_property) +{ + if (!videoio_registry::hasBackend(CAP_FFMPEG)) + throw SkipTestException("FFmpeg backend was not found"); + + string video_file = findDataFile("video/big_buck_bunny.mp4"); + VideoCapture cap; + EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG, { + CAP_PROP_FORMAT, -1 // demux only + })); + + ffmpeg_check_read_raw(cap); +} + +TEST(videoio_ffmpeg, create_with_property) +{ + if (!videoio_registry::hasBackend(CAP_FFMPEG)) + throw SkipTestException("FFmpeg backend was not found"); + + string video_file = findDataFile("video/big_buck_bunny.mp4"); + VideoCapture cap(video_file, CAP_FFMPEG, { + CAP_PROP_FORMAT, -1 // demux only + }); + + ffmpeg_check_read_raw(cap); +} + +TEST(videoio_ffmpeg, create_with_property_badarg) +{ + if (!videoio_registry::hasBackend(CAP_FFMPEG)) + throw SkipTestException("FFmpeg backend was not found"); + + string video_file = findDataFile("video/big_buck_bunny.mp4"); + EXPECT_ANY_THROW( + { + VideoCapture cap(video_file, CAP_FFMPEG, { + CAP_PROP_FORMAT, -2 // invalid + }); + }); +} + + }} // namespace -- 2.7.4