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 <maksim.milashchenko@intel.com> Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
This commit is contained in:
parent
37c12db366
commit
467870415b
@ -651,6 +651,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<int>& params);
|
||||
|
||||
/** @overload
|
||||
@brief Opens a camera for video capturing
|
||||
|
||||
@ -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<int>& 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<int>& 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<int>& 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.
|
||||
*/
|
||||
|
||||
@ -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"} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ class IBackend
|
||||
{
|
||||
public:
|
||||
virtual ~IBackend() {}
|
||||
virtual Ptr<IVideoCapture> createCapture(int camera) const = 0;
|
||||
virtual Ptr<IVideoCapture> createCapture(const std::string &filename) const = 0;
|
||||
virtual Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const = 0;
|
||||
virtual Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const = 0;
|
||||
virtual Ptr<IVideoWriter> 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<IVideoCapture> (*FN_createCaptureFile)(const std::string & filename);
|
||||
typedef Ptr<IVideoCapture> (*FN_createCaptureCamera)(int camera);
|
||||
typedef Ptr<IVideoCapture> (*FN_createCaptureFileWithParams)(const std::string & filename, const VideoCaptureParameters& params);
|
||||
typedef Ptr<IVideoCapture> (*FN_createCaptureCameraWithParams)(int camera, const VideoCaptureParameters& params);
|
||||
typedef Ptr<IVideoWriter> (*FN_createWriter)(const std::string& filename, int fourcc, double fps, const Size& sz,
|
||||
const VideoWriterParameters& params);
|
||||
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFile createCaptureFile,
|
||||
FN_createCaptureCamera createCaptureCamera,
|
||||
FN_createWriter createWriter);
|
||||
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFileWithParams createCaptureFile,
|
||||
FN_createCaptureCameraWithParams createCaptureCamera,
|
||||
FN_createWriter createWriter);
|
||||
|
||||
Ptr<IBackendFactory> createPluginBackendFactory(VideoCaptureAPIs id, const char* baseName);
|
||||
|
||||
void applyParametersFallback(const Ptr<IVideoCapture>& cap, const VideoCaptureParameters& params);
|
||||
|
||||
} // namespace cv::
|
||||
|
||||
#endif // BACKEND_HPP_DEFINED
|
||||
|
||||
@ -363,8 +363,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<IVideoCapture> createCapture(int camera) const CV_OVERRIDE;
|
||||
Ptr<IVideoCapture> createCapture(const std::string &filename) const CV_OVERRIDE;
|
||||
Ptr<IVideoCapture> createCapture(int camera) const;
|
||||
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE;
|
||||
Ptr<IVideoCapture> createCapture(const std::string &filename) const;
|
||||
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE;
|
||||
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
|
||||
const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE;
|
||||
};
|
||||
@ -753,10 +755,22 @@ Ptr<IVideoCapture> PluginBackend::createCapture(int camera) const
|
||||
catch (...)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "Video I/O: can't create camera capture: " << camera);
|
||||
throw;
|
||||
}
|
||||
return Ptr<IVideoCapture>();
|
||||
}
|
||||
|
||||
Ptr<IVideoCapture> PluginBackend::createCapture(int camera, const VideoCaptureParameters& params) const
|
||||
{
|
||||
// TODO Update plugins API to support parameters
|
||||
Ptr<IVideoCapture> cap = createCapture(camera);
|
||||
if (cap && !params.empty())
|
||||
{
|
||||
applyParametersFallback(cap, params);
|
||||
}
|
||||
return cap;
|
||||
}
|
||||
|
||||
Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) const
|
||||
{
|
||||
try
|
||||
@ -769,10 +783,22 @@ Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) con
|
||||
catch (...)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "Video I/O: can't open file capture: " << filename);
|
||||
throw;
|
||||
}
|
||||
return Ptr<IVideoCapture>();
|
||||
}
|
||||
|
||||
Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename, const VideoCaptureParameters& params) const
|
||||
{
|
||||
// TODO Update plugins API to support parameters
|
||||
Ptr<IVideoCapture> cap = createCapture(filename);
|
||||
if (cap && !params.empty())
|
||||
{
|
||||
applyParametersFallback(cap, params);
|
||||
}
|
||||
return cap;
|
||||
}
|
||||
|
||||
Ptr<IVideoWriter> PluginBackend::createWriter(const std::string& filename, int fourcc, double fps,
|
||||
const cv::Size& sz, const VideoWriterParameters& params) const
|
||||
{
|
||||
|
||||
@ -8,6 +8,28 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
|
||||
void applyParametersFallback(const Ptr<IVideoCapture>& cap, const VideoCaptureParameters& params)
|
||||
{
|
||||
std::vector<int> 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<double>(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<IVideoCapture> createCapture(int camera) const CV_OVERRIDE
|
||||
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE
|
||||
{
|
||||
if (fn_createCaptureCamera_)
|
||||
return fn_createCaptureCamera_(camera);
|
||||
{
|
||||
Ptr<IVideoCapture> cap = fn_createCaptureCamera_(camera);
|
||||
if (cap && !params.empty())
|
||||
{
|
||||
applyParametersFallback(cap, params);
|
||||
}
|
||||
return cap;
|
||||
}
|
||||
return Ptr<IVideoCapture>();
|
||||
}
|
||||
Ptr<IVideoCapture> createCapture(const std::string &filename) const CV_OVERRIDE
|
||||
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE
|
||||
{
|
||||
if (fn_createCaptureFile_)
|
||||
return fn_createCaptureFile_(filename);
|
||||
{
|
||||
Ptr<IVideoCapture> cap = fn_createCaptureFile_(filename);
|
||||
if (cap && !params.empty())
|
||||
{
|
||||
applyParametersFallback(cap, params);
|
||||
}
|
||||
return cap;
|
||||
}
|
||||
return Ptr<IVideoCapture>();
|
||||
}
|
||||
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
|
||||
@ -63,6 +100,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFile createCaptureFile,
|
||||
FN_createCaptureCamera createCaptureCamera,
|
||||
FN_createWriter createWriter)
|
||||
@ -70,4 +108,71 @@ Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFile createCaptureFile
|
||||
return makePtr<StaticBackendFactory>(createCaptureFile, createCaptureCamera, createWriter).staticCast<IBackendFactory>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
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<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE
|
||||
{
|
||||
if (fn_createCaptureCamera_)
|
||||
return fn_createCaptureCamera_(camera, params);
|
||||
return Ptr<IVideoCapture>();
|
||||
}
|
||||
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE
|
||||
{
|
||||
if (fn_createCaptureFile_)
|
||||
return fn_createCaptureFile_(filename, params);
|
||||
return Ptr<IVideoCapture>();
|
||||
}
|
||||
Ptr<IVideoWriter> 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<IVideoWriter>();
|
||||
}
|
||||
}; // StaticBackendWithParams
|
||||
|
||||
class StaticBackendWithParamsFactory : public IBackendFactory
|
||||
{
|
||||
protected:
|
||||
Ptr<StaticBackendWithParams> backend;
|
||||
|
||||
public:
|
||||
StaticBackendWithParamsFactory(FN_createCaptureFileWithParams createCaptureFile, FN_createCaptureCameraWithParams createCaptureCamera, FN_createWriter createWriter)
|
||||
: backend(makePtr<StaticBackendWithParams>(createCaptureFile, createCaptureCamera, createWriter))
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
~StaticBackendWithParamsFactory() CV_OVERRIDE {}
|
||||
|
||||
Ptr<IBackend> getBackend() const CV_OVERRIDE
|
||||
{
|
||||
return backend.staticCast<IBackend>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFileWithParams createCaptureFile,
|
||||
FN_createCaptureCameraWithParams createCaptureCamera,
|
||||
FN_createWriter createWriter)
|
||||
{
|
||||
return makePtr<StaticBackendWithParamsFactory>(createCaptureFile, createCaptureCamera, createWriter).staticCast<IBackendFactory>();
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -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<int>& 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<int>& 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<int>());
|
||||
}
|
||||
|
||||
bool VideoCapture::open(const String& filename, int apiPreference, const std::vector<int>& params)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
if (isOpened())
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
const VideoCaptureParameters parameters(params);
|
||||
const std::vector<VideoBackendInfo> 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,
|
||||
@ -181,6 +201,11 @@ bool VideoCapture::open(const String& filename, int apiPreference)
|
||||
}
|
||||
|
||||
bool VideoCapture::open(int cameraNum, int apiPreference)
|
||||
{
|
||||
return open(cameraNum, apiPreference, std::vector<int>());
|
||||
}
|
||||
|
||||
bool VideoCapture::open(int cameraNum, int apiPreference, const std::vector<int>& params)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
@ -200,6 +225,7 @@ bool VideoCapture::open(int cameraNum, int apiPreference)
|
||||
}
|
||||
}
|
||||
|
||||
const VideoCaptureParameters parameters(params);
|
||||
const std::vector<VideoBackendInfo> 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,
|
||||
|
||||
@ -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<int>(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<cv::IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const std::string &filename)
|
||||
cv::Ptr<cv::IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const std::string &filename, const cv::VideoCaptureParameters& params)
|
||||
{
|
||||
cv::Ptr<CvCapture_FFMPEG_proxy> capture = cv::makePtr<CvCapture_FFMPEG_proxy>(filename);
|
||||
cv::Ptr<CvCapture_FFMPEG_proxy> capture = cv::makePtr<CvCapture_FFMPEG_proxy>(filename, params);
|
||||
if (capture && capture->isOpened())
|
||||
return capture;
|
||||
return cv::Ptr<cv::IVideoCapture>();
|
||||
@ -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;
|
||||
|
||||
@ -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<int>& params)
|
||||
explicit VideoParameters(const std::vector<int>& params)
|
||||
{
|
||||
const auto count = params.size();
|
||||
if (count % 2 != 0)
|
||||
@ -87,13 +87,46 @@ public:
|
||||
params_.emplace_back(key, value);
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
ValueType get(int key, ValueType defaultValue) const CV_NOEXCEPT
|
||||
bool has(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;
|
||||
}
|
||||
);
|
||||
return it != params_.end();
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
ValueType get(int key) 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;
|
||||
return castParameterTo<ValueType>(it->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error_(Error::StsBadArg, ("Missing value for parameter: [%d]", key));
|
||||
}
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
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<int> getUnused() const CV_NOEXCEPT {
|
||||
std::vector<int> getUnused() const
|
||||
{
|
||||
std::vector<int> 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<VideoWriterParameter> params_;
|
||||
std::vector<VideoParameter> params_;
|
||||
};
|
||||
|
||||
class VideoWriterParameters : public VideoParameters
|
||||
{
|
||||
public:
|
||||
VideoWriterParameters() = default;
|
||||
|
||||
explicit VideoWriterParameters(const std::vector<int>& params) : VideoParameters(params) {};
|
||||
};
|
||||
|
||||
class VideoCaptureParameters : public VideoParameters
|
||||
{
|
||||
public:
|
||||
VideoCaptureParameters() = default;
|
||||
|
||||
explicit VideoCaptureParameters(const std::vector<int>& params) : VideoParameters(params) {};
|
||||
};
|
||||
|
||||
class IVideoCapture
|
||||
@ -261,7 +332,7 @@ public:
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
Ptr<IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const std::string &filename);
|
||||
Ptr<IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const std::string &filename, const cv::VideoCaptureParameters& params);
|
||||
Ptr<IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc,
|
||||
double fps, const Size& frameSize,
|
||||
const VideoWriterParameters& params);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user