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

Merge pull request #16766 from VadimLevin:dev/vlevin/video_writer_params_constructor

* feature: Extend VideoWriter to accept vector of parameters

 - Add additional constructor and `open` method for `VideoWriter`
   those accept a vector of parameters
 - Move actual implementation of the `VideoWriter::open` to general method
   which accepts vector of parameters
 - Propagate parsed parameters map up to actual video backend construction

* fix: Change VideoWriter constructor description to suppress doc warning

* refactor: Rollback newlines changes

* feature: Changed VideoWriter parameters workflow

* feature: Log unused parameters in VideoWriter open

* doc: Fix VideoWriter `isColor` parameter description

* fix: int to bool VC++ conversion warning

* doc: Remove information about `isColor` flag usage.
This commit is contained in:
Vadim Levin
2020-04-28 11:38:39 +03:00
committed by GitHub
parent 152e6476d9
commit 7f90f04df2
14 changed files with 217 additions and 35 deletions
+4 -2
View File
@@ -18,7 +18,8 @@ public:
virtual ~IBackend() {}
virtual Ptr<IVideoCapture> createCapture(int camera) const = 0;
virtual Ptr<IVideoCapture> createCapture(const std::string &filename) const = 0;
virtual Ptr<IVideoWriter> createWriter(const std::string &filename, int fourcc, double fps, const cv::Size &sz, bool isColor) const = 0;
virtual Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps, const cv::Size& sz,
const VideoWriterParameters& params) const = 0;
};
class IBackendFactory
@@ -32,7 +33,8 @@ public:
typedef Ptr<IVideoCapture> (*FN_createCaptureFile)(const std::string & filename);
typedef Ptr<IVideoCapture> (*FN_createCaptureCamera)(int camera);
typedef Ptr<IVideoWriter> (*FN_createWriter)(const std::string& filename, int fourcc, double fps, const Size& sz, bool isColor);
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);
+8 -4
View File
@@ -243,7 +243,8 @@ public:
Ptr<IVideoCapture> createCapture(int camera) const CV_OVERRIDE;
Ptr<IVideoCapture> createCapture(const std::string &filename) const CV_OVERRIDE;
Ptr<IVideoWriter> createWriter(const std::string &filename, int fourcc, double fps, const cv::Size &sz, bool isColor) const CV_OVERRIDE;
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE;
};
class PluginBackendFactory : public IBackendFactory
@@ -502,7 +503,8 @@ class PluginWriter : public cv::IVideoWriter
public:
static
Ptr<PluginWriter> create(const OpenCV_VideoIO_Plugin_API_preview* plugin_api,
const std::string &filename, int fourcc, double fps, const cv::Size &sz, bool isColor)
const std::string& filename, int fourcc, double fps, const cv::Size& sz,
const VideoWriterParameters& params)
{
CV_Assert(plugin_api);
CvPluginWriter writer = NULL;
@@ -510,6 +512,7 @@ public:
{
CV_Assert(plugin_api->Writer_release);
CV_Assert(!filename.empty());
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
if (CV_ERROR_OK == plugin_api->Writer_open(filename.c_str(), fourcc, fps, sz.width, sz.height, isColor, &writer))
{
CV_Assert(writer);
@@ -597,12 +600,13 @@ Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) con
return Ptr<IVideoCapture>();
}
Ptr<IVideoWriter> PluginBackend::createWriter(const std::string &filename, int fourcc, double fps, const cv::Size &sz, bool isColor) const
Ptr<IVideoWriter> PluginBackend::createWriter(const std::string& filename, int fourcc, double fps,
const cv::Size& sz, const VideoWriterParameters& params) const
{
try
{
if (plugin_api_)
return PluginWriter::create(plugin_api_, filename, fourcc, fps, sz, isColor); //.staticCast<IVideoWriter>();
return PluginWriter::create(plugin_api_, filename, fourcc, fps, sz, params); //.staticCast<IVideoWriter>();
}
catch (...)
{
+3 -2
View File
@@ -34,10 +34,11 @@ public:
return fn_createCaptureFile_(filename);
return Ptr<IVideoCapture>();
}
Ptr<IVideoWriter> createWriter(const std::string &filename, int fourcc, double fps, const cv::Size &sz, bool isColor) const CV_OVERRIDE
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, isColor);
return fn_createWriter_(filename, fourcc, fps, sz, params);
return Ptr<IVideoWriter>();
}
}; // StaticBackend
+44 -8
View File
@@ -458,6 +458,18 @@ VideoWriter::VideoWriter(const String& filename, int apiPreference, int _fourcc,
open(filename, apiPreference, _fourcc, fps, frameSize, isColor);
}
VideoWriter::VideoWriter(const cv::String& filename, int fourcc, double fps,
const cv::Size& frameSize, const std::vector<int>& params)
{
open(filename, fourcc, fps, frameSize, params);
}
VideoWriter::VideoWriter(const cv::String& filename, int apiPreference, int fourcc, double fps,
const cv::Size& frameSize, const std::vector<int>& params)
{
open(filename, apiPreference, fourcc, fps, frameSize, params);
}
void VideoWriter::release()
{
iwriter.release();
@@ -471,11 +483,26 @@ VideoWriter::~VideoWriter()
bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize,
bool isColor)
{
return open(filename, CAP_ANY, _fourcc, fps, frameSize, isColor);
return open(filename, CAP_ANY, _fourcc, fps, frameSize,
std::vector<int> { VIDEOWRITER_PROP_IS_COLOR, static_cast<int>(isColor) });
}
bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, double fps,
Size frameSize, bool isColor)
{
return open(filename, apiPreference, _fourcc, fps, frameSize,
std::vector<int> { VIDEOWRITER_PROP_IS_COLOR, static_cast<int>(isColor) });
}
bool VideoWriter::open(const String& filename, int fourcc, double fps, const Size& frameSize,
const std::vector<int>& params)
{
return open(filename, CAP_ANY, fourcc, fps, frameSize, params);
}
bool VideoWriter::open(const String& filename, int apiPreference, int fourcc, double fps,
const Size& frameSize, const std::vector<int>& params)
{
CV_INSTRUMENT_REGION();
@@ -484,30 +511,39 @@ bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, d
release();
}
const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_Writer();
for (size_t i = 0; i < backends.size(); i++)
const VideoWriterParameters parameters(params);
for (const auto& info : videoio_registry::getAvailableBackends_Writer())
{
const VideoBackendInfo& info = backends[i];
if (apiPreference == CAP_ANY || apiPreference == info.id)
{
CV_WRITER_LOG_DEBUG(NULL,
cv::format("VIDEOIO(%s): trying writer with filename='%s' "
"fourcc=0x%08x fps=%g sz=%dx%d isColor=%d...",
info.name, filename.c_str(), (unsigned)_fourcc, fps,
frameSize.width, frameSize.height, (int)isColor));
info.name, filename.c_str(), (unsigned)fourcc, fps,
frameSize.width, frameSize.height,
parameters.get(VIDEOWRITER_PROP_IS_COLOR, true)));
CV_Assert(!info.backendFactory.empty());
const Ptr<IBackend> backend = info.backendFactory->getBackend();
if (!backend.empty())
{
try
{
iwriter = backend->createWriter(filename, _fourcc, fps, frameSize, isColor);
iwriter = backend->createWriter(filename, fourcc, fps, frameSize, parameters);
if (!iwriter.empty())
{
CV_WRITER_LOG_DEBUG(NULL,
cv::format("VIDEOIO(%s): created, isOpened=%d",
info.name, iwriter->isOpened()));
if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
{
for (int key: parameters.getUnused())
{
CV_LOG_WARNING(NULL,
cv::format("VIDEOIO(%s): parameter with key '%d' was unused",
info.name, key));
}
}
if (iwriter->isOpened())
{
return true;
@@ -529,7 +565,7 @@ bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, d
catch (const std::exception& e)
{
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n",
info.name, e.what()));
info.name, e.what()));
}
catch (...)
{
+4 -1
View File
@@ -221,9 +221,12 @@ cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
return 0;
}
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc, double fps, const cv::Size &frameSize, bool isColor)
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc,
double fps, const cv::Size &frameSize,
const cv::VideoWriterParameters& params)
{
CvSize sz = { frameSize.width, frameSize.height };
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
CvVideoWriter_AVFoundation* wrt = new CvVideoWriter_AVFoundation(filename.c_str(), fourcc, fps, sz, isColor);
return cv::makePtr<cv::LegacyWriter>(wrt);
}
+4 -1
View File
@@ -231,9 +231,12 @@ cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
return 0;
}
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc, double fps, const cv::Size &frameSize, bool isColor)
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc,
double fps, const cv::Size& frameSize,
const cv::VideoWriterParameters& params)
{
CvSize sz = { frameSize.width, frameSize.height };
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
CvVideoWriter_AVFoundation* wrt = new CvVideoWriter_AVFoundation(filename, fourcc, fps, sz, isColor);
if (wrt->isOpened())
{
+5 -2
View File
@@ -170,9 +170,12 @@ protected:
} // namespace
cv::Ptr<cv::IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc, double fps, const cv::Size &frameSize, bool isColor)
cv::Ptr<cv::IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc,
double fps, const cv::Size& frameSize,
const VideoWriterParameters& params)
{
cv::Ptr<CvVideoWriter_FFMPEG_proxy> writer = cv::makePtr<CvVideoWriter_FFMPEG_proxy>(filename, fourcc, fps, frameSize, isColor != 0);
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
cv::Ptr<CvVideoWriter_FFMPEG_proxy> writer = cv::makePtr<CvVideoWriter_FFMPEG_proxy>(filename, fourcc, fps, frameSize, isColor);
if (writer && writer->isOpened())
return writer;
return cv::Ptr<cv::IVideoWriter>();
+3 -1
View File
@@ -1673,9 +1673,11 @@ bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
return true;
}
Ptr<IVideoWriter> create_GStreamer_writer(const std::string &filename, int fourcc, double fps, const cv::Size &frameSize, bool isColor)
Ptr<IVideoWriter> create_GStreamer_writer(const std::string& filename, int fourcc, double fps,
const cv::Size& frameSize, const VideoWriterParameters& params)
{
CvVideoWriter_GStreamer* wrt = new CvVideoWriter_GStreamer;
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
try
{
if (wrt->open(filename, fourcc, fps, frameSize, isColor))
+2 -1
View File
@@ -429,7 +429,8 @@ bool CvVideoWriter_Images::setProperty( int id, double value )
return false; // not supported
}
Ptr<IVideoWriter> create_Images_writer(const std::string &filename, int, double, const Size &, bool)
Ptr<IVideoWriter> create_Images_writer(const std::string &filename, int, double, const Size &,
const cv::VideoWriterParameters&)
{
CvVideoWriter_Images *writer = new CvVideoWriter_Images;
+103 -7
View File
@@ -37,6 +37,88 @@ struct CvVideoWriter
namespace cv
{
namespace
{
template <class T>
inline T castParameterTo(int paramValue)
{
return static_cast<T>(paramValue);
}
template <>
inline bool castParameterTo(int paramValue)
{
return paramValue != 0;
}
}
class VideoWriterParameters
{
public:
struct VideoWriterParameter {
VideoWriterParameter() = default;
VideoWriterParameter(int key_, int value_) : key(key_), value(value_) {}
int key{-1};
int value{-1};
mutable bool isConsumed{false};
};
VideoWriterParameters() = default;
explicit VideoWriterParameters(const std::vector<int>& params)
{
const auto count = params.size();
if (count % 2 != 0)
{
CV_Error_(Error::StsVecLengthErr,
("Vector of VideoWriter parameters should have even length"));
}
params_.reserve(count / 2);
for (std::size_t i = 0; i < count; i += 2)
{
add(params[i], params[i + 1]);
}
}
void add(int key, int value)
{
params_.emplace_back(key, value);
}
template <class ValueType>
ValueType get(int key, ValueType defaultValue) const CV_NOEXCEPT
{
auto it = std::find_if(params_.begin(), params_.end(),
[key](const VideoWriterParameter &param) {
return param.key == key;
});
if (it != params_.end())
{
it->isConsumed = true;
return castParameterTo<ValueType>(it->value);
}
else
{
return defaultValue;
}
}
std::vector<int> getUnused() const CV_NOEXCEPT {
std::vector<int> unusedParams;
for (const auto &param : params_)
{
if (!param.isConsumed)
{
unusedParams.push_back(param.key);
}
}
return unusedParams;
}
private:
std::vector<VideoWriterParameter> params_;
};
class IVideoCapture
{
@@ -168,24 +250,34 @@ public:
//==================================================================================================
Ptr<IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const std::string &filename);
Ptr<IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc, double fps, const Size &frameSize, bool isColor);
Ptr<IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> createGStreamerCapture_file(const std::string& filename);
Ptr<IVideoCapture> createGStreamerCapture_cam(int index);
Ptr<IVideoWriter> create_GStreamer_writer(const std::string& filename, int fourcc, double fps, const Size &frameSize, bool isColor);
Ptr<IVideoWriter> create_GStreamer_writer(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> create_MFX_capture(const std::string &filename);
Ptr<IVideoWriter> create_MFX_writer(const std::string &filename, int _fourcc, double fps, const Size &frameSize, bool isColor);
Ptr<IVideoWriter> create_MFX_writer(const std::string& filename, int _fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> create_AVFoundation_capture_file(const std::string &filename);
Ptr<IVideoCapture> create_AVFoundation_capture_cam(int index);
Ptr<IVideoWriter> create_AVFoundation_writer(const std::string& filename, int fourcc, double fps, const Size &frameSize, bool isColor);
Ptr<IVideoWriter> create_AVFoundation_writer(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> create_WRT_capture(int device);
Ptr<IVideoCapture> cvCreateCapture_MSMF(int index);
Ptr<IVideoCapture> cvCreateCapture_MSMF(const std::string& filename);
Ptr<IVideoWriter> cvCreateVideoWriter_MSMF(const std::string& filename, int fourcc, double fps, const Size &frameSize, bool is_color);
Ptr<IVideoWriter> cvCreateVideoWriter_MSMF(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> create_DShow_capture(int index);
@@ -196,7 +288,9 @@ Ptr<IVideoCapture> create_OpenNI2_capture_cam( int index );
Ptr<IVideoCapture> create_OpenNI2_capture_file( const std::string &filename );
Ptr<IVideoCapture> create_Images_capture(const std::string &filename);
Ptr<IVideoWriter> create_Images_writer(const std::string &filename, int fourcc, double fps, const Size &frameSize, bool iscolor);
Ptr<IVideoWriter> create_Images_writer(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> create_DC1394_capture(int index);
@@ -210,7 +304,9 @@ Ptr<IVideoCapture> create_XIMEA_capture_file( const std::string &serialNumber );
Ptr<IVideoCapture> create_Aravis_capture( int index );
Ptr<IVideoCapture> createMotionJpegCapture(const std::string& filename);
Ptr<IVideoWriter> createMotionJpegWriter(const std::string &filename, int fourcc, double fps, const Size &frameSize, bool iscolor);
Ptr<IVideoWriter> createMotionJpegWriter(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params);
Ptr<IVideoCapture> createGPhoto2Capture(int index);
Ptr<IVideoCapture> createGPhoto2Capture(const std::string& deviceName);
+3 -1
View File
@@ -251,10 +251,12 @@ bool VideoWriter_IntelMFX::write_one(cv::InputArray bgr)
}
}
Ptr<IVideoWriter> cv::create_MFX_writer(const std::string &filename, int _fourcc, double fps, const Size &frameSize, bool isColor)
Ptr<IVideoWriter> cv::create_MFX_writer(const std::string& filename, int _fourcc, double fps,
const Size& frameSize, const VideoWriterParameters& params)
{
if (codecIdByFourCC(_fourcc) > 0)
{
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
Ptr<VideoWriter_IntelMFX> a = makePtr<VideoWriter_IntelMFX>(filename, _fourcc, fps, frameSize, isColor);
if (a->isOpened())
return a;
+5 -2
View File
@@ -1532,12 +1532,15 @@ void MotionJpegWriter::writeFrameData( const uchar* data, int step, int colorspa
}
Ptr<IVideoWriter> createMotionJpegWriter(const std::string &filename, int fourcc, double fps, const Size &frameSize, bool iscolor)
Ptr<IVideoWriter> createMotionJpegWriter(const std::string& filename, int fourcc,
double fps, const Size& frameSize,
const VideoWriterParameters& params)
{
if (fourcc != CV_FOURCC('M', 'J', 'P', 'G'))
return Ptr<IVideoWriter>();
Ptr<IVideoWriter> iwriter = makePtr<mjpeg::MotionJpegWriter>(filename, fps, frameSize, iscolor);
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
Ptr<IVideoWriter> iwriter = makePtr<mjpeg::MotionJpegWriter>(filename, fps, frameSize, isColor);
if( !iwriter->isOpened() )
iwriter.release();
return iwriter;
+3 -1
View File
@@ -1656,11 +1656,13 @@ void CvVideoWriter_MSMF::write(cv::InputArray img)
}
cv::Ptr<cv::IVideoWriter> cv::cvCreateVideoWriter_MSMF( const std::string& filename, int fourcc,
double fps, const cv::Size &frameSize, bool isColor )
double fps, const cv::Size& frameSize,
const VideoWriterParameters& params)
{
cv::Ptr<CvVideoWriter_MSMF> writer = cv::makePtr<CvVideoWriter_MSMF>();
if (writer)
{
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
writer->open(filename, fourcc, fps, frameSize, isColor);
if (writer->isOpened())
return writer;