enum VideoWriterProperties {
VIDEOWRITER_PROP_QUALITY = 1, //!< Current quality (0..100%) of the encoded videostream. Can be adjusted dynamically in some codecs.
VIDEOWRITER_PROP_FRAMEBYTES = 2, //!< (Read-only): Size of just encoded video frame. Note that the encoding order may be different from representation order.
- VIDEOWRITER_PROP_NSTRIPES = 3 //!< Number of stripes for parallel encoding. -1 for auto detection.
+ VIDEOWRITER_PROP_NSTRIPES = 3, //!< Number of stripes for parallel encoding. -1 for auto detection.
+ VIDEOWRITER_PROP_IS_COLOR = 4 //!< If it is not zero, the encoder will expect and encode color frames, otherwise it
+ //!< will work with grayscale frames.
};
//! @} videoio_flags_base
@param fps Framerate of the created video stream.
@param frameSize Size of the video frames.
@param isColor If it is not zero, the encoder will expect and encode color frames, otherwise it
- will work with grayscale frames (the flag is currently supported on Windows only).
+ will work with grayscale frames.
@b Tips:
- With some backends `fourcc=-1` pops up the codec selection dialog from the system.
CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
Size frameSize, bool isColor = true);
+ /** @overload
+ * The `params` parameter allows to specify extra encoder parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ... .)
+ * see cv::VideoWriterProperties
+ */
+ CV_WRAP VideoWriter(const String& filename, int fourcc, double fps, const Size& frameSize,
+ const std::vector<int>& params);
+
+ /** @overload
+ */
+ CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
+ const Size& frameSize, const std::vector<int>& params);
+
/** @brief Default destructor
The method first calls VideoWriter::release to close the already opened file.
CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,
Size frameSize, bool isColor = true);
+ /** @overload
+ */
+ CV_WRAP bool open(const String& filename, int fourcc, double fps, const Size& frameSize,
+ const std::vector<int>& params);
+
+ /** @overload
+ */
+ CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,
+ const Size& frameSize, const std::vector<int>& params);
+
/** @brief Returns true if video writer has been successfully initialized.
*/
CV_WRAP virtual bool isOpened() const;
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
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);
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
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;
{
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);
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 (...)
{
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
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();
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();
if (isOpened())
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;
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 (...)
{
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);
}
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())
{
} // 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>();
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))
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;
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 ¶m) {
+ 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 ¶m : params_)
+ {
+ if (!param.isConsumed)
+ {
+ unusedParams.push_back(param.key);
+ }
+ }
+ return unusedParams;
+ }
+private:
+ std::vector<VideoWriterParameter> params_;
+};
class IVideoCapture
{
//==================================================================================================
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);
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);
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);
}
}
-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;
}
-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;
}
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;