From 602d2c33c0098ce7553eb7b283d7cedb84425b1f Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 27 Mar 2015 15:15:59 +0300 Subject: [PATCH] added video writer quality, which user may change dynamically in the case of motion jpeg; enabled NEON intrinsics in the encoder --- modules/videoio/include/opencv2/videoio.hpp | 22 +++++++++++++ modules/videoio/src/cap.cpp | 15 +++++++++ modules/videoio/src/cap_mjpeg_encoder.cpp | 35 ++++++++++++++++----- modules/videoio/src/precomp.hpp | 4 +-- 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/modules/videoio/include/opencv2/videoio.hpp b/modules/videoio/include/opencv2/videoio.hpp index 85021163a3..ae958bcee8 100644 --- a/modules/videoio/include/opencv2/videoio.hpp +++ b/modules/videoio/include/opencv2/videoio.hpp @@ -376,6 +376,9 @@ enum { CAP_INTELPERC_DEPTH_MAP = 0, // Each pixel is a 16-bit integ CAP_INTELPERC_IMAGE = 3 }; +enum { VIDEOWRITER_PROP_QUALITY = 1, // Quality (0..100%) of the videostream encoded + VIDEOWRITER_PROP_FRAMEBYTES = 2, // (Read-only): Size of just encoded video frame + }; class IVideoCapture; @@ -642,6 +645,25 @@ public: */ CV_WRAP virtual void write(const Mat& image); + /** @brief Sets a property in the VideoWriter. + + @param propId Property identifier. It can be one of the following: + - **VIDEOWRITER_PROP_QUALITY** Quality (0..100%) of the videostream encoded. Can be adjusted dynamically in some codecs. + @param value Value of the property. + */ + CV_WRAP virtual bool set(int propId, double value); + + /** @brief Returns the specified VideoWriter property + + @param propId Property identifier. It can be one of the following: + - **VIDEOWRITER_PROP_QUALITY** Current quality of the encoded videostream. + - **VIDEOWRITER_PROP_FRAMEBYTES** (Read-only) Size of just encoded video frame; note that the encoding order may be different from representation order. + + **Note**: When querying a property that is not supported by the backend used by the VideoWriter + class, value 0 is returned. + */ + CV_WRAP virtual double get(int propId) const; + /** @brief Concatenates 4 chars to a fourcc code This static method constructs the fourcc code of the codec to be used in the constructor diff --git a/modules/videoio/src/cap.cpp b/modules/videoio/src/cap.cpp index 28470c6a56..b5a44da3f7 100644 --- a/modules/videoio/src/cap.cpp +++ b/modules/videoio/src/cap.cpp @@ -705,6 +705,21 @@ bool VideoWriter::isOpened() const return !iwriter.empty() || !writer.empty(); } + +bool VideoWriter::set(int propId, double value) +{ + if (!iwriter.empty()) + return iwriter->setProperty(propId, value); + return false; +} + +double VideoWriter::get(int propId) const +{ + if (!iwriter.empty()) + return iwriter->getProperty(propId); + return 0.; +} + void VideoWriter::write(const Mat& image) { if( iwriter ) diff --git a/modules/videoio/src/cap_mjpeg_encoder.cpp b/modules/videoio/src/cap_mjpeg_encoder.cpp index 601aeb6442..7856fd416f 100644 --- a/modules/videoio/src/cap_mjpeg_encoder.cpp +++ b/modules/videoio/src/cap_mjpeg_encoder.cpp @@ -42,9 +42,8 @@ #include "precomp.hpp" #include -//#define WITH_NEON -#ifdef WITH_NEON -#include "arm_neon.h" +#if CV_NEON +#define WITH_NEON #endif namespace cv @@ -381,7 +380,7 @@ public: outfps = cvRound(fps); width = size.width; height = size.height; - quality = 8; + quality = 75; rawstream = false; channels = iscolor ? 3 : 1; @@ -592,12 +591,31 @@ public: } } + double getProperty(int propId) const + { + if( propId == VIDEOWRITER_PROP_QUALITY ) + return quality; + if( propId == VIDEOWRITER_PROP_FRAMEBYTES ) + return frameSize.empty() ? 0. : (double)frameSize.back(); + return 0.; + } + + bool setProperty(int propId, double value) + { + if( propId == VIDEOWRITER_PROP_QUALITY ) + { + quality = value; + return true; + } + return false; + } + void writeFrameData( const uchar* data, int step, int colorspace, int input_channels ); protected: int outfps; int width, height, channels; - int quality; + double quality; size_t moviPointer; std::vector frameOffset, frameSize, AVIChunkSizeIndex, frameNumIndexes; bool rawstream; @@ -1116,11 +1134,12 @@ void MotionJpegWriter::writeFrameData( const uchar* data, int step, int colorspa const int UV_step = 16; int u_plane_ofs = step*height; int v_plane_ofs = u_plane_ofs + step*height; + double _quality = quality*0.01*max_quality; - if( quality < 1 ) quality = 1; - if( quality > max_quality ) quality = max_quality; + if( _quality < 1. ) _quality = 1.; + if( _quality > max_quality ) _quality = max_quality; - double inv_quality = 1./quality; + double inv_quality = 1./_quality; // Encode header strm.putBytes( (const uchar*)jpegHeader, sizeof(jpegHeader) - 1 ); diff --git a/modules/videoio/src/precomp.hpp b/modules/videoio/src/precomp.hpp index 38623c7cfa..c4662cccc5 100644 --- a/modules/videoio/src/precomp.hpp +++ b/modules/videoio/src/precomp.hpp @@ -166,7 +166,7 @@ namespace cv public: virtual ~IVideoCapture() {} virtual double getProperty(int) const { return 0; } - virtual bool setProperty(int, double) { return 0; } + virtual bool setProperty(int, double) { return false; } virtual bool grabFrame() = 0; virtual bool retrieveFrame(int, OutputArray) = 0; virtual bool isOpened() const = 0; @@ -178,7 +178,7 @@ namespace cv public: virtual ~IVideoWriter() {} virtual double getProperty(int) const { return 0; } - virtual bool setProperty(int, double) { return 0; } + virtual bool setProperty(int, double) { return false; } virtual bool isOpened() const = 0; virtual void write(InputArray) = 0;