Merge pull request #18146 from VadimLevin:dev/vlevin/ffmpeg-remove-obsolte-versions-support

Remove obsolete FFMPEG versions support

* refactor: removed obsolete FFMPEG version support

 - Oldest available version via official FFMPEG repository mirror has tag v.0.5
 LIBAVFORMAT version for this tag is 52.31.0

* refactor: prefer std::min function to MIN macro

* refactor: use appropriate macro instead of manual version calculation

* refactor: remove macros for versions prior 0.5.15 release

* refactor: remove libavcodec macros for versions < 54.35.1 (default to Ubuntu 14.04)

* refactor: remove libavformat macro for versions < 54.20.4 (default ubuntu 14.04)

* refactor: remove libavutil macro for versions < 52.3.0 (default ubuntu 14.04)

* refactor: remove missed macros for libavcodec and libavformat

* refactor: remove unused _opencv_ffmpeg_free function

* build: add FFMPEG libraries versions checks

 - Add verbose message about what FFMPEG libraries are missing.
 - Add minimal versions check set to libav 9.20 release (default ubuntu 14.04) and FFMPEG 1.1.16 release.
   If the check is failed CMake produces user-friendly message instead of build error.

* fix: libavcodec version guard for AVDISCARD_NONINTRA

* fix: libav check of libavcodec version guard for AVDISCARD_NONINTRA

* fix: version check for AV_CODEC_FLAG_GLOBAL_HEADER

* fix: missing FFMPEG libraries output
pull/18197/head
Vadim Levin 4 years ago committed by GitHub
parent e5e08ec523
commit 458bd1652d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      modules/videoio/cmake/detect_ffmpeg.cmake
  2. 311
      modules/videoio/src/cap_ffmpeg_impl.hpp

@ -24,17 +24,56 @@ if(NOT HAVE_FFMPEG AND WIN32 AND NOT ARM AND NOT OPENCV_FFMPEG_SKIP_DOWNLOAD)
endif() endif()
endif() endif()
set(_required_ffmpeg_libraries libavcodec libavformat libavutil libswscale)
set(_used_ffmpeg_libraries ${_required_ffmpeg_libraries})
if(NOT HAVE_FFMPEG AND PKG_CONFIG_FOUND) if(NOT HAVE_FFMPEG AND PKG_CONFIG_FOUND)
ocv_check_modules(FFMPEG libavcodec libavformat libavutil libswscale) ocv_check_modules(FFMPEG libavcodec libavformat libavutil libswscale)
if(FFMPEG_FOUND) if(FFMPEG_FOUND)
ocv_check_modules(FFMPEG_libavresample libavresample) # optional ocv_check_modules(FFMPEG_libavresample libavresample) # optional
if(FFMPEG_libavresample_FOUND) if(FFMPEG_libavresample_FOUND)
list(APPEND FFMPEG_LIBRARIES ${FFMPEG_libavresample_LIBRARIES}) list(APPEND FFMPEG_LIBRARIES ${FFMPEG_libavresample_LIBRARIES})
list(APPEND _used_ffmpeg_libraries libavresample)
endif() endif()
set(HAVE_FFMPEG TRUE) set(HAVE_FFMPEG TRUE)
else()
set(_missing_ffmpeg_libraries "")
foreach (ffmpeg_lib ${_required_ffmpeg_libraries})
if (NOT FFMPEG_${ffmpeg_lib}_FOUND)
list(APPEND _missing_ffmpeg_libraries ${ffmpeg_lib})
endif()
endforeach ()
message(STATUS "FFMPEG is disabled. Required libraries: ${_required_ffmpeg_libraries}."
" Missing libraries: ${_missing_ffmpeg_libraries}")
unset(_missing_ffmpeg_libraries)
endif() endif()
endif() endif()
#=================================
# Versions check.
if(HAVE_FFMPEG AND NOT HAVE_FFMPEG_WRAPPER)
set(_min_libavcodec_version 54.35.1)
set(_min_libavformat_version 54.20.4)
set(_min_libavutil_version 52.3.0)
set(_min_libswscale_version 2.1.1)
set(_min_libavresample_version 1.0.1)
foreach(ffmpeg_lib ${_used_ffmpeg_libraries})
if(FFMPEG_${ffmpeg_lib}_VERSION VERSION_LESS _min_${ffmpeg_lib}_version)
message(STATUS "FFMPEG is disabled. Can't find suitable ${ffmpeg_lib} library"
" (minimal ${_min_${ffmpeg_lib}_version}, found ${FFMPEG_${ffmpeg_lib}_VERSION}).")
set(HAVE_FFMPEG FALSE)
endif()
endforeach()
if(NOT HAVE_FFMPEG)
message(STATUS "FFMPEG libraries version check failed "
"(minimal libav release 9.20, minimal FFMPEG release 1.1.16).")
endif()
unset(_min_libavcodec_version)
unset(_min_libavformat_version)
unset(_min_libavutil_version)
unset(_min_libswscale_version)
unset(_min_libavresample_version)
endif()
#================================== #==================================
if(HAVE_FFMPEG AND NOT HAVE_FFMPEG_WRAPPER AND NOT OPENCV_FFMPEG_SKIP_BUILD_CHECK) if(HAVE_FFMPEG AND NOT HAVE_FFMPEG_WRAPPER AND NOT OPENCV_FFMPEG_SKIP_BUILD_CHECK)
@ -53,6 +92,8 @@ if(HAVE_FFMPEG AND NOT HAVE_FFMPEG_WRAPPER AND NOT OPENCV_FFMPEG_SKIP_BUILD_CHEC
endif() endif()
#================================== #==================================
unset(_required_ffmpeg_libraries)
unset(_used_ffmpeg_libraries)
if(HAVE_FFMPEG_WRAPPER) if(HAVE_FFMPEG_WRAPPER)
ocv_add_external_target(ffmpeg "" "" "HAVE_FFMPEG_WRAPPER") ocv_add_external_target(ffmpeg "" "" "HAVE_FFMPEG_WRAPPER")

@ -76,10 +76,7 @@ extern "C" {
#include "ffmpeg_codecs.hpp" #include "ffmpeg_codecs.hpp"
#include <libavutil/mathematics.h> #include <libavutil/mathematics.h>
#include <libavutil/opt.h>
#if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0)
#include <libavutil/opt.h>
#endif
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \ #if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0)) ? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
@ -124,9 +121,6 @@ extern "C" {
#endif #endif
#endif #endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#if defined(__APPLE__) #if defined(__APPLE__)
#define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL) #define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
@ -146,22 +140,6 @@ extern "C" {
# define CV_CODEC(name) name # define CV_CODEC(name) name
#endif #endif
#if LIBAVUTIL_BUILD < (LIBAVUTIL_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(51, 74, 100) : CALC_FFMPEG_VERSION(51, 42, 0))
#define AVPixelFormat PixelFormat
#define AV_PIX_FMT_BGR24 PIX_FMT_BGR24
#define AV_PIX_FMT_RGB24 PIX_FMT_RGB24
#define AV_PIX_FMT_GRAY8 PIX_FMT_GRAY8
#define AV_PIX_FMT_BGRA PIX_FMT_BGRA
#define AV_PIX_FMT_RGBA PIX_FMT_RGBA
#define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
#define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
#define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
#define AV_PIX_FMT_GRAY16LE PIX_FMT_GRAY16LE
#define AV_PIX_FMT_GRAY16BE PIX_FMT_GRAY16BE
#endif
#ifndef PKT_FLAG_KEY #ifndef PKT_FLAG_KEY
#define PKT_FLAG_KEY AV_PKT_FLAG_KEY #define PKT_FLAG_KEY AV_PKT_FLAG_KEY
#endif #endif
@ -178,11 +156,7 @@ extern "C" {
#ifndef USE_AV_INTERRUPT_CALLBACK #ifndef USE_AV_INTERRUPT_CALLBACK
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 21, 0)
#define USE_AV_INTERRUPT_CALLBACK 1 #define USE_AV_INTERRUPT_CALLBACK 1
#else
#define USE_AV_INTERRUPT_CALLBACK 0
#endif
#endif #endif
#ifndef USE_AV_SEND_FRAME_API #ifndef USE_AV_SEND_FRAME_API
@ -314,9 +288,7 @@ inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
static int get_number_of_cpus(void) static int get_number_of_cpus(void)
{ {
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0) #if defined _WIN32
return 1;
#elif defined _WIN32
SYSTEM_INFO sysinfo; SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo ); GetSystemInfo( &sysinfo );
@ -404,12 +376,6 @@ inline const char* _opencv_avcodec_get_name(CV_CODEC_ID id)
#endif #endif
} }
static
inline void _opencv_ffmpeg_free(void** ptr)
{
if(*ptr) free(*ptr);
*ptr = 0;
}
static static
inline int _opencv_ffmpeg_interrupt_callback(void *ptr) inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
@ -541,9 +507,7 @@ struct CvCapture_FFMPEG
*/ */
char * filename; char * filename;
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
AVDictionary *dict; AVDictionary *dict;
#endif
#if USE_AV_INTERRUPT_CALLBACK #if USE_AV_INTERRUPT_CALLBACK
AVInterruptCallbackMetadata interrupt_metadata; AVInterruptCallbackMetadata interrupt_metadata;
#endif #endif
@ -581,16 +545,12 @@ void CvCapture_FFMPEG::init()
rotation_angle = 0; rotation_angle = 0;
#if (LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0))
#if (LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 92, 100)) #if (LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 92, 100))
rotation_auto = true; rotation_auto = true;
#else #else
rotation_auto = false; rotation_auto = false;
#endif #endif
dict = NULL; dict = NULL;
#else
rotation_auto = false;
#endif
rawMode = false; rawMode = false;
rawModeInitialized = false; rawModeInitialized = false;
@ -623,24 +583,13 @@ void CvCapture_FFMPEG::close()
if( video_st ) if( video_st )
{ {
#if LIBAVFORMAT_BUILD > 4628
avcodec_close( video_st->codec ); avcodec_close( video_st->codec );
#else
avcodec_close( &(video_st->codec) );
#endif
video_st = NULL; video_st = NULL;
} }
if( ic ) if( ic )
{ {
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
av_close_input_file(ic);
#else
avformat_close_input(&ic); avformat_close_input(&ic);
#endif
ic = NULL; ic = NULL;
} }
@ -660,10 +609,8 @@ void CvCapture_FFMPEG::close()
packet.data = NULL; packet.data = NULL;
} }
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
if (dict != NULL) if (dict != NULL)
av_dict_free(&dict); av_dict_free(&dict);
#endif
if (packet_filtered.data) if (packet_filtered.data)
{ {
@ -883,9 +830,7 @@ public:
} }
InternalFFMpegRegister() InternalFFMpegRegister()
{ {
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
avformat_network_init(); avformat_network_init();
#endif
/* register all codecs, demux and protocols */ /* register all codecs, demux and protocols */
av_register_all(); av_register_all();
@ -931,7 +876,6 @@ bool CvCapture_FFMPEG::open( const char* _filename )
ic->interrupt_callback.opaque = &interrupt_metadata; ic->interrupt_callback.opaque = &interrupt_metadata;
#endif #endif
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
#ifndef NO_GETENV #ifndef NO_GETENV
char* options = getenv("OPENCV_FFMPEG_CAPTURE_OPTIONS"); char* options = getenv("OPENCV_FFMPEG_CAPTURE_OPTIONS");
if(options == NULL) if(options == NULL)
@ -957,9 +901,6 @@ bool CvCapture_FFMPEG::open( const char* _filename )
} }
int err = avformat_open_input(&ic, _filename, input_format, &dict); int err = avformat_open_input(&ic, _filename, input_format, &dict);
#else
int err = av_open_input_file(&ic, _filename, NULL, 0, NULL);
#endif
if (err < 0) if (err < 0)
{ {
@ -967,12 +908,7 @@ bool CvCapture_FFMPEG::open( const char* _filename )
CV_WARN(_filename); CV_WARN(_filename);
goto exit_func; goto exit_func;
} }
err = err = avformat_find_stream_info(ic, NULL);
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
avformat_find_stream_info(ic, NULL);
#else
av_find_stream_info(ic);
#endif
if (err < 0) if (err < 0)
{ {
CV_WARN("Could not find codec parameters"); CV_WARN("Could not find codec parameters");
@ -980,11 +916,7 @@ bool CvCapture_FFMPEG::open( const char* _filename )
} }
for(i = 0; i < ic->nb_streams; i++) for(i = 0; i < ic->nb_streams; i++)
{ {
#if LIBAVFORMAT_BUILD > 4628 AVCodecContext* enc = ic->streams[i]->codec;
AVCodecContext *enc = ic->streams[i]->codec;
#else
AVCodecContext *enc = &ic->streams[i]->codec;
#endif
//#ifdef FF_API_THREAD_INIT //#ifdef FF_API_THREAD_INIT
// avcodec_thread_init(enc, get_number_of_cpus()); // avcodec_thread_init(enc, get_number_of_cpus());
@ -992,10 +924,9 @@ bool CvCapture_FFMPEG::open( const char* _filename )
enc->thread_count = get_number_of_cpus(); enc->thread_count = get_number_of_cpus();
//#endif //#endif
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(52, 123, 0)
AVDictionaryEntry* avdiscard_entry = av_dict_get(dict, "avdiscard", NULL, 0); AVDictionaryEntry* avdiscard_entry = av_dict_get(dict, "avdiscard", NULL, 0);
if (avdiscard_entry != 0) { if (avdiscard_entry) {
if(strcmp(avdiscard_entry->value, "all") == 0) if(strcmp(avdiscard_entry->value, "all") == 0)
enc->skip_frame = AVDISCARD_ALL; enc->skip_frame = AVDISCARD_ALL;
else if (strcmp(avdiscard_entry->value, "bidir") == 0) else if (strcmp(avdiscard_entry->value, "bidir") == 0)
@ -1004,7 +935,10 @@ bool CvCapture_FFMPEG::open( const char* _filename )
enc->skip_frame = AVDISCARD_DEFAULT; enc->skip_frame = AVDISCARD_DEFAULT;
else if (strcmp(avdiscard_entry->value, "none") == 0) else if (strcmp(avdiscard_entry->value, "none") == 0)
enc->skip_frame = AVDISCARD_NONE; enc->skip_frame = AVDISCARD_NONE;
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 59, 100) // NONINTRA flag was introduced with version bump at revision:
// https://github.com/FFmpeg/FFmpeg/commit/b152152df3b778d0a86dcda5d4f5d065b4175a7b
// This key is supported only for FFMPEG version
#if LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(55, 67, 100)
else if (strcmp(avdiscard_entry->value, "nonintra") == 0) else if (strcmp(avdiscard_entry->value, "nonintra") == 0)
enc->skip_frame = AVDISCARD_NONINTRA; enc->skip_frame = AVDISCARD_NONINTRA;
#endif #endif
@ -1013,11 +947,6 @@ bool CvCapture_FFMPEG::open( const char* _filename )
else if (strcmp(avdiscard_entry->value, "nonref") == 0) else if (strcmp(avdiscard_entry->value, "nonref") == 0)
enc->skip_frame = AVDISCARD_NONREF; enc->skip_frame = AVDISCARD_NONREF;
} }
#endif
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
#endif
if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0)
{ {
@ -1031,13 +960,7 @@ bool CvCapture_FFMPEG::open( const char* _filename )
} else { } else {
codec = avcodec_find_decoder_by_name(av_dict_get(dict, "video_codec", NULL, 0)->value); codec = avcodec_find_decoder_by_name(av_dict_get(dict, "video_codec", NULL, 0)->value);
} }
if (!codec || if (!codec || avcodec_open2(enc, codec, NULL) < 0)
#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
avcodec_open2(enc, codec, NULL)
#else
avcodec_open(enc, codec)
#endif
< 0)
goto exit_func; goto exit_func;
// checking width/height (since decoder can sometimes alter it, eg. vp6f) // checking width/height (since decoder can sometimes alter it, eg. vp6f)
@ -1101,10 +1024,8 @@ bool CvCapture_FFMPEG::processRawPacket()
rawModeInitialized = true; rawModeInitialized = true;
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(58, 20, 100) #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(58, 20, 100)
CV_CODEC_ID eVideoCodec = ic->streams[video_stream]->codecpar->codec_id; CV_CODEC_ID eVideoCodec = ic->streams[video_stream]->codecpar->codec_id;
#elif LIBAVFORMAT_BUILD > 4628
CV_CODEC_ID eVideoCodec = video_st->codec->codec_id;
#else #else
CV_CODEC_ID eVideoCodec = video_st->codec.codec_id; CV_CODEC_ID eVideoCodec = video_st->codec->codec_id;
#endif #endif
const char* filterName = NULL; const char* filterName = NULL;
if (eVideoCodec == CV_CODEC(CODEC_ID_H264) if (eVideoCodec == CV_CODEC(CODEC_ID_H264)
@ -1179,11 +1100,7 @@ bool CvCapture_FFMPEG::processRawPacket()
return false; return false;
} }
#else #else
#if LIBAVFORMAT_BUILD > 4628
AVCodecContext* ctx = ic->streams[video_stream]->codec; AVCodecContext* ctx = ic->streams[video_stream]->codec;
#else
AVCodecContext* ctx = &ic->streams[video_stream]->codec;
#endif
int err = av_bitstream_filter_filter(bsfc, ctx, NULL, &packet_filtered.data, int err = av_bitstream_filter_filter(bsfc, ctx, NULL, &packet_filtered.data,
&packet_filtered.size, packet.data, packet.size, packet_filtered.flags & AV_PKT_FLAG_KEY); &packet_filtered.size, packet.data, packet.size, packet_filtered.flags & AV_PKT_FLAG_KEY);
if (err < 0) if (err < 0)
@ -1265,17 +1182,7 @@ bool CvCapture_FFMPEG::grabFrame()
} }
// Decode video frame // Decode video frame
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
#elif LIBAVFORMAT_BUILD > 4628
avcodec_decode_video(video_st->codec,
picture, &got_picture,
packet.data, packet.size);
#else
avcodec_decode_video(&video_st->codec,
picture, &got_picture,
packet.data, packet.size);
#endif
// Did we get a video frame? // Did we get a video frame?
if(got_picture) if(got_picture)
@ -1423,13 +1330,8 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
case CAP_PROP_FPS: case CAP_PROP_FPS:
return get_fps(); return get_fps();
case CAP_PROP_FOURCC: case CAP_PROP_FOURCC:
#if LIBAVFORMAT_BUILD > 4628
codec_id = video_st->codec->codec_id; codec_id = video_st->codec->codec_id;
codec_tag = (double) video_st->codec->codec_tag; codec_tag = (double) video_st->codec->codec_tag;
#else
codec_id = video_st->codec.codec_id;
codec_tag = (double)video_st->codec.codec_tag;
#endif
if(codec_tag || codec_id == AV_CODEC_ID_NONE) if(codec_tag || codec_id == AV_CODEC_ID_NONE)
{ {
@ -1449,11 +1351,7 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).den; return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).den;
case CAP_PROP_CODEC_PIXEL_FORMAT: case CAP_PROP_CODEC_PIXEL_FORMAT:
{ {
#if LIBAVFORMAT_BUILD > 4628
AVPixelFormat pix_fmt = video_st->codec->pix_fmt; AVPixelFormat pix_fmt = video_st->codec->pix_fmt;
#else
AVPixelFormat pix_fmt = video_st->codec.pix_fmt;
#endif
unsigned int fourcc_tag = avcodec_pix_fmt_to_codec_tag(pix_fmt); unsigned int fourcc_tag = avcodec_pix_fmt_to_codec_tag(pix_fmt);
return (fourcc_tag == 0) ? (double)-1 : (double)fourcc_tag; return (fourcc_tag == 0) ? (double)-1 : (double)fourcc_tag;
} }
@ -1466,8 +1364,7 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
case CAP_PROP_ORIENTATION_META: case CAP_PROP_ORIENTATION_META:
return static_cast<double>(rotation_angle); return static_cast<double>(rotation_angle);
case CAP_PROP_ORIENTATION_AUTO: case CAP_PROP_ORIENTATION_AUTO:
#if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \ #if LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)
(LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)))
return static_cast<double>(rotation_auto); return static_cast<double>(rotation_auto);
#else #else
return 0; return 0;
@ -1506,11 +1403,7 @@ double CvCapture_FFMPEG::get_fps() const
#if 0 && LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 1, 100) && LIBAVFORMAT_VERSION_MICRO >= 100 #if 0 && LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 1, 100) && LIBAVFORMAT_VERSION_MICRO >= 100
double fps = r2d(av_guess_frame_rate(ic, ic->streams[video_stream], NULL)); double fps = r2d(av_guess_frame_rate(ic, ic->streams[video_stream], NULL));
#else #else
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
double fps = r2d(ic->streams[video_stream]->avg_frame_rate); double fps = r2d(ic->streams[video_stream]->avg_frame_rate);
#else
double fps = r2d(ic->streams[video_stream]->r_frame_rate);
#endif
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0) #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
if (fps < eps_zero) if (fps < eps_zero)
@ -1553,8 +1446,7 @@ double CvCapture_FFMPEG::dts_to_sec(int64_t dts) const
void CvCapture_FFMPEG::get_rotation_angle() void CvCapture_FFMPEG::get_rotation_angle()
{ {
rotation_angle = 0; rotation_angle = 0;
#if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \ #if LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)
(LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)))
AVDictionaryEntry *rotate_tag = av_dict_get(video_st->metadata, "rotate", NULL, 0); AVDictionaryEntry *rotate_tag = av_dict_get(video_st->metadata, "rotate", NULL, 0);
if (rotate_tag != NULL) if (rotate_tag != NULL)
rotation_angle = atoi(rotate_tag->value); rotation_angle = atoi(rotate_tag->value);
@ -1657,15 +1549,13 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value )
return setRaw(); return setRaw();
return false; return false;
case CAP_PROP_ORIENTATION_AUTO: case CAP_PROP_ORIENTATION_AUTO:
#if ((LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)) && \ #if LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)
(LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)))
rotation_auto = static_cast<bool>(value); rotation_auto = static_cast<bool>(value);
return true; return true;
#else #else
rotation_auto = 0; rotation_auto = 0;
return false; return false;
#endif #endif
break;
default: default:
return false; return false;
} }
@ -1704,7 +1594,6 @@ struct CvVideoWriter_FFMPEG
static const char * icvFFMPEGErrStr(int err) static const char * icvFFMPEGErrStr(int err)
{ {
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
switch(err) { switch(err) {
case AVERROR_BSF_NOT_FOUND: case AVERROR_BSF_NOT_FOUND:
return "Bitstream filter not found"; return "Bitstream filter not found";
@ -1735,22 +1624,6 @@ static const char * icvFFMPEGErrStr(int err)
default: default:
break; break;
} }
#else
switch(err) {
case AVERROR_NUMEXPECTED:
return "Incorrect filename syntax";
case AVERROR_INVALIDDATA:
return "Invalid data in header";
case AVERROR_NOFMT:
return "Unknown format";
case AVERROR_IO:
return "I/O error occurred";
case AVERROR_NOMEM:
return "Memory allocation error";
default:
break;
}
#endif
return "Unspecified error"; return "Unspecified error";
} }
@ -1829,28 +1702,16 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
int frame_rate, frame_rate_base; int frame_rate, frame_rate_base;
AVCodec *codec; AVCodec *codec;
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
st = avformat_new_stream(oc, 0); st = avformat_new_stream(oc, 0);
#else
st = av_new_stream(oc, 0);
#endif
if (!st) { if (!st) {
CV_WARN("Could not allocate stream"); CV_WARN("Could not allocate stream");
return NULL; return NULL;
} }
#if LIBAVFORMAT_BUILD > 4628
c = st->codec; c = st->codec;
#else
c = &(st->codec);
#endif
#if LIBAVFORMAT_BUILD > 4621
c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
#else
c->codec_id = oc->oformat->video_codec;
#endif
if(codec_id != CV_CODEC(CODEC_ID_NONE)){ if(codec_id != CV_CODEC(CODEC_ID_NONE)){
c->codec_id = codec_id; c->codec_id = codec_id;
@ -1861,13 +1722,11 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
c->codec_type = AVMEDIA_TYPE_VIDEO; c->codec_type = AVMEDIA_TYPE_VIDEO;
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0)
// Set per-codec defaults // Set per-codec defaults
CV_CODEC_ID c_id = c->codec_id; CV_CODEC_ID c_id = c->codec_id;
avcodec_get_context_defaults3(c, codec); avcodec_get_context_defaults3(c, codec);
// avcodec_get_context_defaults3 erases codec_id for some reason // avcodec_get_context_defaults3 erases codec_id for some reason
c->codec_id = c_id; c->codec_id = c_id;
#endif
/* put sample parameters */ /* put sample parameters */
int64_t lbit_rate = (int64_t)bitrate; int64_t lbit_rate = (int64_t)bitrate;
@ -1893,7 +1752,6 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
frame_rate_base*=10; frame_rate_base*=10;
frame_rate=(int)(fps*frame_rate_base + 0.5); frame_rate=(int)(fps*frame_rate_base + 0.5);
} }
#if LIBAVFORMAT_BUILD > 4752
c->time_base.den = frame_rate; c->time_base.den = frame_rate;
c->time_base.num = frame_rate_base; c->time_base.num = frame_rate_base;
/* adjust time base for supported framerates */ /* adjust time base for supported framerates */
@ -1915,10 +1773,6 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
c->time_base.den= best->num; c->time_base.den= best->num;
c->time_base.num= best->den; c->time_base.num= best->den;
} }
#else
c->frame_rate = frame_rate;
c->frame_rate_base = frame_rate_base;
#endif
c->gop_size = 12; /* emit one intra frame every twelve frames at most */ c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->pix_fmt = (AVPixelFormat) pixel_format; c->pix_fmt = (AVPixelFormat) pixel_format;
@ -1934,7 +1788,6 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
c->mb_decision=2; c->mb_decision=2;
} }
#if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0)
/* Some settings for libx264 encoding, restore dummy values for gop_size /* Some settings for libx264 encoding, restore dummy values for gop_size
and qmin since they will be set to reasonable defaults by the libx264 and qmin since they will be set to reasonable defaults by the libx264
preset system. Also, use a crf encode with the default quality rating, preset system. Also, use a crf encode with the default quality rating,
@ -1946,28 +1799,25 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
if (c->priv_data) if (c->priv_data)
av_opt_set(c->priv_data,"crf","23", 0); av_opt_set(c->priv_data,"crf","23", 0);
} }
#endif
#if LIBAVCODEC_VERSION_INT>0x000409
// some formats want stream headers to be separate // some formats want stream headers to be separate
if(oc->oformat->flags & AVFMT_GLOBALHEADER) if(oc->oformat->flags & AVFMT_GLOBALHEADER)
{ {
#if LIBAVCODEC_BUILD > CALC_FFMPEG_VERSION(56, 35, 0) // flags were renamed: https://github.com/libav/libav/commit/7c6eb0a1b7bf1aac7f033a7ec6d8cacc3b5c2615
#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(56, 60, 100) : CALC_FFMPEG_VERSION(56, 35, 0))
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
#else #else
c->flags |= CODEC_FLAG_GLOBAL_HEADER; c->flags |= CODEC_FLAG_GLOBAL_HEADER;
#endif #endif
} }
#endif
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(52, 42, 0)
#if defined(_MSC_VER) #if defined(_MSC_VER)
AVRational avg_frame_rate = {frame_rate, frame_rate_base}; AVRational avg_frame_rate = {frame_rate, frame_rate_base};
st->avg_frame_rate = avg_frame_rate; st->avg_frame_rate = avg_frame_rate;
#else #else
st->avg_frame_rate = (AVRational){frame_rate, frame_rate_base}; st->avg_frame_rate = (AVRational){frame_rate, frame_rate_base};
#endif #endif
#endif
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 20, 0) #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 20, 0)
st->time_base = c->time_base; st->time_base = c->time_base;
#endif #endif
@ -1978,18 +1828,10 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000; static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000;
static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st,
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
uint8_t *, uint32_t, uint8_t *, uint32_t,
#else
uint8_t * outbuf, uint32_t outbuf_size,
#endif
AVFrame * picture ) AVFrame * picture )
{ {
#if LIBAVFORMAT_BUILD > 4628 AVCodecContext* c = video_st->codec;
AVCodecContext * c = video_st->codec;
#else
AVCodecContext * c = &(video_st->codec);
#endif
int ret = OPENCV_NO_FRAMES_WRITTEN_CODE; int ret = OPENCV_NO_FRAMES_WRITTEN_CODE;
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(57, 0, 0) #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(57, 0, 0)
@ -2033,7 +1875,6 @@ static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st,
#else #else
AVPacket pkt; AVPacket pkt;
av_init_packet(&pkt); av_init_packet(&pkt);
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
int got_output = 0; int got_output = 0;
pkt.data = NULL; pkt.data = NULL;
pkt.size = 0; pkt.size = 0;
@ -2053,26 +1894,6 @@ static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st,
} }
else else
ret = OPENCV_NO_FRAMES_WRITTEN_CODE; ret = OPENCV_NO_FRAMES_WRITTEN_CODE;
#else
int out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
/* if zero size, it means the image was buffered */
if (out_size > 0) {
#if LIBAVFORMAT_BUILD > 4752
if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
#else
pkt.pts = c->coded_frame->pts;
#endif
if(c->coded_frame->key_frame)
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= video_st->index;
pkt.data= outbuf;
pkt.size= out_size;
/* write the compressed frame in the media file */
ret = av_write_frame(oc, &pkt);
}
#endif
#endif #endif
} }
return ret; return ret;
@ -2102,11 +1923,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
height = frame_height; height = frame_height;
// typecast from opaque data type to implemented struct // typecast from opaque data type to implemented struct
#if LIBAVFORMAT_BUILD > 4628 AVCodecContext* c = video_st->codec;
AVCodecContext *c = video_st->codec;
#else
AVCodecContext *c = &(video_st->codec);
#endif
// FFmpeg contains SIMD optimizations which can sometimes read data past // FFmpeg contains SIMD optimizations which can sometimes read data past
// the supplied input buffer. // the supplied input buffer.
@ -2220,11 +2037,7 @@ void CvVideoWriter_FFMPEG::close()
} }
// free pictures // free pictures
#if LIBAVFORMAT_BUILD > 4628
if( video_st->codec->pix_fmt != input_pix_fmt) if( video_st->codec->pix_fmt != input_pix_fmt)
#else
if( video_st->codec.pix_fmt != input_pix_fmt)
#endif
{ {
if(picture->data[0]) if(picture->data[0])
free(picture->data[0]); free(picture->data[0]);
@ -2236,11 +2049,7 @@ void CvVideoWriter_FFMPEG::close()
av_free(input_picture); av_free(input_picture);
/* close codec */ /* close codec */
#if LIBAVFORMAT_BUILD > 4628
avcodec_close(video_st->codec); avcodec_close(video_st->codec);
#else
avcodec_close(&(video_st->codec));
#endif
av_free(outbuf); av_free(outbuf);
@ -2249,17 +2058,7 @@ void CvVideoWriter_FFMPEG::close()
if (!(fmt->flags & AVFMT_NOFILE)) if (!(fmt->flags & AVFMT_NOFILE))
{ {
/* close the output file */ /* close the output file */
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
url_fclose(oc->pb);
#else
url_fclose(&oc->pb);
#endif
#else
avio_close(oc->pb); avio_close(oc->pb);
#endif
} }
/* free the stream */ /* free the stream */
@ -2338,11 +2137,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
/* auto detect the output format from the name and fourcc code. */ /* auto detect the output format from the name and fourcc code. */
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
fmt = av_guess_format(NULL, filename, NULL); fmt = av_guess_format(NULL, filename, NULL);
#else
fmt = guess_format(NULL, filename, NULL);
#endif
if (!fmt) if (!fmt)
return false; return false;
@ -2363,19 +2158,13 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
} }
/* Lookup codec_id for given fourcc */ /* Lookup codec_id for given fourcc */
#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
if( (codec_id = codec_get_bmp_id( fourcc )) == CV_CODEC(CODEC_ID_NONE) )
return false;
#else
if( (codec_id = av_codec_get_id(fmt->codec_tag, fourcc)) == CV_CODEC(CODEC_ID_NONE) ) if( (codec_id = av_codec_get_id(fmt->codec_tag, fourcc)) == CV_CODEC(CODEC_ID_NONE) )
{ {
const struct AVCodecTag * fallback_tags[] = { const struct AVCodecTag * fallback_tags[] = {
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
// APIchanges: // APIchanges:
// 2012-01-31 - dd6d3b0 - lavf 54.01.0 // 2012-01-31 - dd6d3b0 - lavf 54.01.0
// Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags(). // Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags().
avformat_get_riff_video_tags(), avformat_get_riff_video_tags(),
#endif
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 25, 100) && defined LIBAVFORMAT_VERSION_MICRO && LIBAVFORMAT_VERSION_MICRO >= 100 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 25, 100) && defined LIBAVFORMAT_VERSION_MICRO && LIBAVFORMAT_VERSION_MICRO >= 100
// APIchanges: ffmpeg only // APIchanges: ffmpeg only
// 2014-01-19 - 1a193c4 - lavf 55.25.100 - avformat.h // 2014-01-19 - 1a193c4 - lavf 55.25.100 - avformat.h
@ -2410,14 +2199,9 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
fourcc = supported_tag; fourcc = supported_tag;
} }
} }
#endif
// alloc memory for context // alloc memory for context
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
oc = avformat_alloc_context(); oc = avformat_alloc_context();
#else
oc = av_alloc_format_context();
#endif
assert (oc); assert (oc);
/* set file name */ /* set file name */
@ -2429,14 +2213,12 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
// set a few optimal pixel formats for lossless codecs of interest.. // set a few optimal pixel formats for lossless codecs of interest..
switch (codec_id) { switch (codec_id) {
#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
case CV_CODEC(CODEC_ID_JPEGLS): case CV_CODEC(CODEC_ID_JPEGLS):
// BGR24 or GRAY8 depending on is_color... // BGR24 or GRAY8 depending on is_color...
// supported: bgr24 rgb24 gray gray16le // supported: bgr24 rgb24 gray gray16le
// as of version 3.4.1 // as of version 3.4.1
codec_pix_fmt = input_pix_fmt; codec_pix_fmt = input_pix_fmt;
break; break;
#endif
case CV_CODEC(CODEC_ID_HUFFYUV): case CV_CODEC(CODEC_ID_HUFFYUV):
// supported: yuv422p rgb24 bgra // supported: yuv422p rgb24 bgra
// as of version 3.4.1 // as of version 3.4.1
@ -2537,21 +2319,13 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
break; break;
} }
double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2); double bitrate = std::min(bitrate_scale*fps*width*height, (double)INT_MAX/2);
// TODO -- safe to ignore output audio stream? // TODO -- safe to ignore output audio stream?
video_st = icv_add_video_stream_FFMPEG(oc, codec_id, video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
width, height, (int)(bitrate + 0.5), width, height, (int)(bitrate + 0.5),
fps, codec_pix_fmt); fps, codec_pix_fmt);
/* set the output parameters (must be done even if no
parameters). */
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
if (av_set_parameters(oc, NULL) < 0) {
return false;
}
#endif
#if 0 #if 0
#if FF_API_DUMP_FORMAT #if FF_API_DUMP_FORMAT
dump_format(oc, 0, filename, 1); dump_format(oc, 0, filename, 1);
@ -2566,26 +2340,14 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
return false; return false;
} }
AVCodec *codec; AVCodecContext* c = video_st->codec;
AVCodecContext *c;
#if LIBAVFORMAT_BUILD > 4628
c = (video_st->codec);
#else
c = &(video_st->codec);
#endif
c->codec_tag = fourcc; c->codec_tag = fourcc;
/* find the video encoder */ /* find the video encoder */
codec = avcodec_find_encoder(c->codec_id); AVCodec* codec = avcodec_find_encoder(c->codec_id);
if (!codec) { if (!codec) {
fprintf(stderr, "Could not find encoder for codec id %d: %s\n", c->codec_id, icvFFMPEGErrStr( fprintf(stderr, "Could not find encoder for codec id %d: %s\n", c->codec_id,
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) icvFFMPEGErrStr(AVERROR_ENCODER_NOT_FOUND));
AVERROR_ENCODER_NOT_FOUND
#else
-1
#endif
));
return false; return false;
} }
@ -2596,13 +2358,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
c->bit_rate = (int)lbit_rate; c->bit_rate = (int)lbit_rate;
/* open the codec */ /* open the codec */
if ((err= if ((err= avcodec_open2(c, codec, NULL)) < 0) {
#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
avcodec_open2(c, codec, NULL)
#else
avcodec_open(c, codec)
#endif
) < 0) {
fprintf(stderr, "Could not open codec '%s': %s\n", codec->name, icvFFMPEGErrStr(err)); fprintf(stderr, "Could not open codec '%s': %s\n", codec->name, icvFFMPEGErrStr(err));
return false; return false;
} }
@ -2641,23 +2397,16 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
} }
/* open the output file, if needed */ /* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) { if (!(fmt->flags & AVFMT_NOFILE))
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) {
if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0)
#else {
if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0)
#endif
{
return false; return false;
} }
} }
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
/* write the stream header, if any */ /* write the stream header, if any */
err=avformat_write_header(oc, NULL); err=avformat_write_header(oc, NULL);
#else
err=av_write_header( oc );
#endif
if(err < 0) if(err < 0)
{ {

Loading…
Cancel
Save