From 1c88e1fd194e1607154a4ee6729b815e3b731daf Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 2 Mar 2021 23:41:05 +0300 Subject: [PATCH] Merge pull request #19661 from alalek:ffmpeg_fixes_3.4 * videoio(ffmpeg): eliminate MSVC build warnings * videoio(ffmpeg): update initialization code - repair FFmpeg logger settings on each .open() call --- modules/videoio/src/cap_ffmpeg_impl.hpp | 102 ++++++++++++++---------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index 3974f4af34..4164ab941c 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -61,6 +61,9 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif +#ifdef _MSC_VER +#pragma warning(disable: 4996) // was declared deprecated +#endif #ifndef CV_UNUSED // Required for standalone compilation mode (OpenCV defines this in base.hpp) #define CV_UNUSED(name) (void)name @@ -250,7 +253,7 @@ inline void get_monotonic_time(timespec *tv) t.QuadPart -= offset.QuadPart; microseconds = (double)t.QuadPart / frequencyToMicroseconds; - t.QuadPart = microseconds; + t.QuadPart = (LONGLONG)microseconds; tv->tv_sec = t.QuadPart / 1000000; tv->tv_nsec = (t.QuadPart % 1000000) * 1000; } @@ -722,16 +725,6 @@ struct ImplMutex::Impl int refcount; }; -#ifndef __GNUC__ -static int _interlockedExchangeAdd(int* addr, int delta) -{ -#if defined _MSC_VER && _MSC_VER >= 1500 - return (int)_InterlockedExchangeAdd((long volatile*)addr, delta); -#else - return (int)InterlockedExchangeAdd((long volatile*)addr, delta); -#endif -} -#endif // __GNUC__ #elif defined __APPLE__ @@ -859,51 +852,70 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *fmt, va_list v class InternalFFMpegRegister { -public: - InternalFFMpegRegister() + static void init_() { - AutoLock lock(_mutex); - if (!_initialized) + static InternalFFMpegRegister instance; + } + + static void initLogger_() + { + #ifndef NO_GETENV + char* debug_option = getenv("OPENCV_FFMPEG_DEBUG"); + if (debug_option != NULL) { - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) - avformat_network_init(); + av_log_set_level(AV_LOG_VERBOSE); + av_log_set_callback(ffmpeg_log_callback); + } + else #endif + { + av_log_set_level(AV_LOG_ERROR); + } + } - /* register all codecs, demux and protocols */ - av_register_all(); - - /* register a callback function for synchronization */ - av_lockmgr_register(&LockCallBack); - -#ifndef NO_GETENV - char* debug_option = getenv("OPENCV_FFMPEG_DEBUG"); - if (debug_option != NULL) +public: + static void init() + { + if (!_initialized) + { + AutoLock lock(_mutex); + if (!_initialized) { - av_log_set_level(AV_LOG_VERBOSE); - av_log_set_callback(ffmpeg_log_callback); + init_(); } - else + } + initLogger_(); // update logger setup unconditionally (GStreamer's libav plugin may override these settings) + } + + InternalFFMpegRegister() + { +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) + avformat_network_init(); #endif - { - av_log_set_level(AV_LOG_ERROR); - } - _initialized = true; - } + /* register all codecs, demux and protocols */ + av_register_all(); + + /* register a callback function for synchronization */ + av_lockmgr_register(&LockCallBack); + + _initialized = true; } ~InternalFFMpegRegister() { _initialized = false; av_lockmgr_register(NULL); + av_log_set_callback(NULL); } }; -static InternalFFMpegRegister _init; - bool CvCapture_FFMPEG::open( const char* _filename ) { + InternalFFMpegRegister::init(); + AutoLock lock(_mutex); + unsigned i; bool valid = false; @@ -1416,9 +1428,9 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const case CV_FFMPEG_CAP_PROP_FRAME_COUNT: return (double)get_total_frames(); case CV_FFMPEG_CAP_PROP_FRAME_WIDTH: - return (double)((rotation_auto && rotation_angle%180) ? frame.height : frame.width); + return (double)((rotation_auto && ((rotation_angle%180) != 0)) ? frame.height : frame.width); case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT: - return (double)((rotation_auto && rotation_angle%180) ? frame.width : frame.height); + return (double)((rotation_auto && ((rotation_angle%180) != 0)) ? frame.width : frame.height); case CV_FFMPEG_CAP_PROP_FPS: return get_fps(); case CV_FFMPEG_CAP_PROP_FOURCC: @@ -1658,10 +1670,10 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value ) case CV_FFMPEG_CAP_PROP_ORIENTATION_AUTO: #if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \ (LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100))) - rotation_auto = static_cast(value); + rotation_auto = value != 0 ? true : false; return true; #else - rotation_auto = 0; + rotation_auto = false; return false; #endif break; @@ -2096,7 +2108,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int // 2. (dataend - SIMD_SIZE) and (dataend + SIMD_SIZE) is from the same 4k page const int CV_STEP_ALIGNMENT = 32; const size_t CV_SIMD_SIZE = 32; - const size_t CV_PAGE_MASK = ~(4096 - 1); + const size_t CV_PAGE_MASK = ~(size_t)(4096 - 1); const unsigned char* dataend = data + ((size_t)height * step); if (step % CV_STEP_ALIGNMENT != 0 || (((size_t)dataend - CV_SIMD_SIZE) & CV_PAGE_MASK) != (((size_t)dataend + CV_SIMD_SIZE) & CV_PAGE_MASK)) @@ -2295,6 +2307,10 @@ static inline void cv_ff_codec_tag_dump(const AVCodecTag *const *tags) bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, double fps, int width, int height, bool is_color ) { + InternalFFMpegRegister::init(); + + AutoLock lock(_mutex); + CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_NONE); int err, codec_pix_fmt; double bitrate_scale = 1; @@ -2569,7 +2585,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, } int64_t lbit_rate = (int64_t)c->bit_rate; - lbit_rate += (bitrate / 2); + lbit_rate += (int64_t)(bitrate / 2); lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX); c->bit_rate_tolerance = (int)lbit_rate; c->bit_rate = (int)lbit_rate; @@ -2962,7 +2978,7 @@ bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, #endif c->codec_tag = MKTAG('H', '2', '6', '4'); - c->bit_rate_tolerance = c->bit_rate; + c->bit_rate_tolerance = (int)(c->bit_rate); // open the output file, if needed if (!(fmt_->flags & AVFMT_NOFILE))