Skip to content

Commit

Permalink
Merge pull request opencv#16766 from VadimLevin:dev/vlevin/video_writ…
Browse files Browse the repository at this point in the history
…er_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.
  • Loading branch information
VadimLevin authored Apr 28, 2020
1 parent 152e647 commit 7f90f04
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 35 deletions.
28 changes: 26 additions & 2 deletions modules/videoio/include/opencv2/videoio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ enum VideoCaptureProperties {
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
Expand Down Expand Up @@ -876,7 +878,7 @@ class CV_EXPORTS_W VideoWriter
@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.
Expand All @@ -896,6 +898,18 @@ class CV_EXPORTS_W VideoWriter
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.
Expand All @@ -918,6 +932,16 @@ class CV_EXPORTS_W VideoWriter
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;
Expand Down
6 changes: 4 additions & 2 deletions modules/videoio/src/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class IBackend
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
Expand All @@ -32,7 +33,8 @@ 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);
Expand Down
12 changes: 8 additions & 4 deletions modules/videoio/src/backend_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ class PluginBackend: public IBackend

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
Expand Down Expand Up @@ -502,14 +503,16 @@ 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;
if (plugin_api->Writer_open)
{
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);
Expand Down Expand Up @@ -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 (...)
{
Expand Down
5 changes: 3 additions & 2 deletions modules/videoio/src/backend_static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ class StaticBackend: public IBackend
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
Expand Down
52 changes: 44 additions & 8 deletions modules/videoio/src/cap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();

Expand All @@ -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;
Expand All @@ -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 (...)
{
Expand Down
5 changes: 4 additions & 1 deletion modules/videoio/src/cap_avfoundation.mm
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,12 @@ - (IplImage*)getOutput;
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);
}
Expand Down
5 changes: 4 additions & 1 deletion modules/videoio/src/cap_avfoundation_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,12 @@ bool isOpened() const
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())
{
Expand Down
7 changes: 5 additions & 2 deletions modules/videoio/src/cap_ffmpeg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,12 @@ class CvVideoWriter_FFMPEG_proxy CV_FINAL :

} // 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>();
Expand Down
4 changes: 3 additions & 1 deletion modules/videoio/src/cap_gstreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 2 additions & 1 deletion modules/videoio/src/cap_images.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading

0 comments on commit 7f90f04

Please sign in to comment.