123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- From a61b19b524cd2b66a7c43e67edd7cc780bf46cbb Mon Sep 17 00:00:00 2001
- From: Alexander Alekhin <alexander.alekhin@itseez.com>
- Date: Wed, 2 Mar 2016 17:54:17 +0300
- Subject: [PATCH] backport ffmpeg fixes
- Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
- Downloaded from upstream commit:
- https://github.com/Itseez/opencv/commit/a61b19b524cd2b66a7c43e67edd7cc780bf46cbb
- ---
- modules/highgui/src/cap_ffmpeg_impl.hpp | 364 +++++++++++++++++++++++++++-----
- 1 file changed, 314 insertions(+), 50 deletions(-)
- diff --git a/modules/highgui/src/cap_ffmpeg_impl.hpp b/modules/highgui/src/cap_ffmpeg_impl.hpp
- index 1b79870..6df542a 100644
- --- a/modules/highgui/src/cap_ffmpeg_impl.hpp
- +++ b/modules/highgui/src/cap_ffmpeg_impl.hpp
- @@ -118,11 +118,6 @@ extern "C" {
- #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
- #endif
-
- -/* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */
- -#ifndef PIX_FMT_RGBA32
- -#define PIX_FMT_RGBA32 PIX_FMT_RGB32
- -#endif
- -
- #define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c )
-
- #if defined WIN32 || defined _WIN32
- @@ -132,6 +127,11 @@ extern "C" {
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/sysctl.h>
- + #include <sys/time.h>
- +#if defined __APPLE__
- + #include <mach/clock.h>
- + #include <mach/mach.h>
- +#endif
- #endif
-
- #ifndef MIN
- @@ -156,6 +156,155 @@ extern "C" {
- # define CV_CODEC(name) name
- #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_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
- +
- +#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
- + ? CALC_FFMPEG_VERSION(52, 38, 100) : CALC_FFMPEG_VERSION(52, 13, 0))
- +#define USE_AV_FRAME_GET_BUFFER 1
- +#else
- +#define USE_AV_FRAME_GET_BUFFER 0
- +#ifndef AV_NUM_DATA_POINTERS // required for 0.7.x/0.8.x ffmpeg releases
- +#define AV_NUM_DATA_POINTERS 4
- +#endif
- +#endif
- +
- +
- +#ifndef USE_AV_INTERRUPT_CALLBACK
- +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 21, 0)
- +#define USE_AV_INTERRUPT_CALLBACK 1
- +#else
- +#define USE_AV_INTERRUPT_CALLBACK 0
- +#endif
- +#endif
- +
- +#if USE_AV_INTERRUPT_CALLBACK
- +#define LIBAVFORMAT_INTERRUPT_TIMEOUT_MS 30000
- +
- +#ifdef WIN32
- +// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
- +
- +static
- +inline LARGE_INTEGER get_filetime_offset()
- +{
- + SYSTEMTIME s;
- + FILETIME f;
- + LARGE_INTEGER t;
- +
- + s.wYear = 1970;
- + s.wMonth = 1;
- + s.wDay = 1;
- + s.wHour = 0;
- + s.wMinute = 0;
- + s.wSecond = 0;
- + s.wMilliseconds = 0;
- + SystemTimeToFileTime(&s, &f);
- + t.QuadPart = f.dwHighDateTime;
- + t.QuadPart <<= 32;
- + t.QuadPart |= f.dwLowDateTime;
- + return t;
- +}
- +
- +static
- +inline void get_monotonic_time(timespec *tv)
- +{
- + LARGE_INTEGER t;
- + FILETIME f;
- + double microseconds;
- + static LARGE_INTEGER offset;
- + static double frequencyToMicroseconds;
- + static int initialized = 0;
- + static BOOL usePerformanceCounter = 0;
- +
- + if (!initialized)
- + {
- + LARGE_INTEGER performanceFrequency;
- + initialized = 1;
- + usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
- + if (usePerformanceCounter)
- + {
- + QueryPerformanceCounter(&offset);
- + frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
- + }
- + else
- + {
- + offset = get_filetime_offset();
- + frequencyToMicroseconds = 10.;
- + }
- + }
- +
- + if (usePerformanceCounter)
- + {
- + QueryPerformanceCounter(&t);
- + } else {
- + GetSystemTimeAsFileTime(&f);
- + t.QuadPart = f.dwHighDateTime;
- + t.QuadPart <<= 32;
- + t.QuadPart |= f.dwLowDateTime;
- + }
- +
- + t.QuadPart -= offset.QuadPart;
- + microseconds = (double)t.QuadPart / frequencyToMicroseconds;
- + t.QuadPart = microseconds;
- + tv->tv_sec = t.QuadPart / 1000000;
- + tv->tv_nsec = (t.QuadPart % 1000000) * 1000;
- +}
- +#else
- +static
- +inline void get_monotonic_time(timespec *time)
- +{
- +#if defined(__APPLE__) && defined(__MACH__)
- + clock_serv_t cclock;
- + mach_timespec_t mts;
- + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
- + clock_get_time(cclock, &mts);
- + mach_port_deallocate(mach_task_self(), cclock);
- + time->tv_sec = mts.tv_sec;
- + time->tv_nsec = mts.tv_nsec;
- +#else
- + clock_gettime(CLOCK_MONOTONIC, time);
- +#endif
- +}
- +#endif
- +
- +static
- +inline timespec get_monotonic_time_diff(timespec start, timespec end)
- +{
- + timespec temp;
- + if (end.tv_nsec - start.tv_nsec < 0)
- + {
- + temp.tv_sec = end.tv_sec - start.tv_sec - 1;
- + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
- + }
- + else
- + {
- + temp.tv_sec = end.tv_sec - start.tv_sec;
- + temp.tv_nsec = end.tv_nsec - start.tv_nsec;
- + }
- + return temp;
- +}
- +
- +static
- +inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
- +{
- + timespec delta = get_monotonic_time_diff(time1, time2);
- + double milliseconds = delta.tv_sec * 1000 + (double)delta.tv_nsec / 1000000.0;
- +
- + return milliseconds;
- +}
- +#endif // USE_AV_INTERRUPT_CALLBACK
- +
- static int get_number_of_cpus(void)
- {
- #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0)
- @@ -205,12 +354,36 @@ struct Image_FFMPEG
- };
-
-
- +#if USE_AV_INTERRUPT_CALLBACK
- +struct AVInterruptCallbackMetadata
- +{
- + timespec value;
- + unsigned int timeout_after_ms;
- + int timeout;
- +};
- +
- +static
- inline void _opencv_ffmpeg_free(void** ptr)
- {
- if(*ptr) free(*ptr);
- *ptr = 0;
- }
-
- +static
- +inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
- +{
- + AVInterruptCallbackMetadata* metadata = (AVInterruptCallbackMetadata*)ptr;
- + assert(metadata);
- +
- + timespec now;
- + get_monotonic_time(&now);
- +
- + metadata->timeout = get_monotonic_time_diff_ms(metadata->value, now) > metadata->timeout_after_ms;
- +
- + return metadata->timeout ? -1 : 0;
- +}
- +#endif
- +
-
- struct CvCapture_FFMPEG
- {
- @@ -264,6 +437,10 @@ struct CvCapture_FFMPEG
- #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
- AVDictionary *dict;
- #endif
- +
- +#if USE_AV_INTERRUPT_CALLBACK
- + AVInterruptCallbackMetadata interrupt_metadata;
- +#endif
- };
-
- void CvCapture_FFMPEG::init()
- @@ -301,8 +478,10 @@ void CvCapture_FFMPEG::close()
-
- if( picture )
- {
- - // FFmpeg and Libav added avcodec_free_frame in different versions.
- #if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
- + ? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
- + av_frame_free(&picture);
- +#elif LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
- ? CALC_FFMPEG_VERSION(54, 59, 100) : CALC_FFMPEG_VERSION(54, 28, 0))
- avcodec_free_frame(&picture);
- #else
- @@ -333,11 +512,15 @@ void CvCapture_FFMPEG::close()
- ic = NULL;
- }
-
- +#if USE_AV_FRAME_GET_BUFFER
- + av_frame_unref(&rgb_picture);
- +#else
- if( rgb_picture.data[0] )
- {
- free( rgb_picture.data[0] );
- rgb_picture.data[0] = 0;
- }
- +#endif
-
- // free last packet if exist
- if (packet.data) {
- @@ -556,6 +739,16 @@ bool CvCapture_FFMPEG::open( const char* _filename )
-
- close();
-
- +#if USE_AV_INTERRUPT_CALLBACK
- + /* interrupt callback */
- + interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
- + get_monotonic_time(&interrupt_metadata.value);
- +
- + ic = avformat_alloc_context();
- + ic->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
- + ic->interrupt_callback.opaque = &interrupt_metadata;
- +#endif
- +
- #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
- av_dict_set(&dict, "rtsp_transport", "tcp", 0);
- int err = avformat_open_input(&ic, _filename, NULL, &dict);
- @@ -619,19 +812,18 @@ bool CvCapture_FFMPEG::open( const char* _filename )
-
- video_stream = i;
- video_st = ic->streams[i];
- +#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
- + ? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
- + picture = av_frame_alloc();
- +#else
- picture = avcodec_alloc_frame();
- -
- - rgb_picture.data[0] = (uint8_t*)malloc(
- - avpicture_get_size( PIX_FMT_BGR24,
- - enc->width, enc->height ));
- - avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
- - PIX_FMT_BGR24, enc->width, enc->height );
- +#endif
-
- frame.width = enc->width;
- frame.height = enc->height;
- frame.cn = 3;
- - frame.step = rgb_picture.linesize[0];
- - frame.data = rgb_picture.data[0];
- + frame.step = 0;
- + frame.data = NULL;
- break;
- }
- }
- @@ -668,6 +860,16 @@ bool CvCapture_FFMPEG::grabFrame()
- // get the next frame
- while (!valid)
- {
- + av_free_packet (&packet);
- +
- +#if USE_AV_INTERRUPT_CALLBACK
- + if (interrupt_metadata.timeout)
- + {
- + valid = false;
- + break;
- + }
- +#endif
- +
- int ret = av_read_frame(ic, &packet);
- if (ret == AVERROR(EAGAIN)) continue;
-
- @@ -703,6 +905,11 @@ bool CvCapture_FFMPEG::grabFrame()
- picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts;
- frame_number++;
- valid = true;
- +
- +#if USE_AV_INTERRUPT_CALLBACK
- + // update interrupt value
- + get_monotonic_time(&interrupt_metadata.value);
- +#endif
- }
- else
- {
- @@ -727,38 +934,59 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int*
- if( !video_st || !picture->data[0] )
- return false;
-
- - avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24,
- - video_st->codec->width, video_st->codec->height);
- -
- if( img_convert_ctx == NULL ||
- frame.width != video_st->codec->width ||
- - frame.height != video_st->codec->height )
- + frame.height != video_st->codec->height ||
- + frame.data == NULL )
- {
- - if( img_convert_ctx )
- - sws_freeContext(img_convert_ctx);
- -
- - frame.width = video_st->codec->width;
- - frame.height = video_st->codec->height;
- + // Some sws_scale optimizations have some assumptions about alignment of data/step/width/height
- + // Also we use coded_width/height to workaround problem with legacy ffmpeg versions (like n0.8)
- + int buffer_width = video_st->codec->coded_width, buffer_height = video_st->codec->coded_height;
-
- img_convert_ctx = sws_getCachedContext(
- - NULL,
- - video_st->codec->width, video_st->codec->height,
- + img_convert_ctx,
- + buffer_width, buffer_height,
- video_st->codec->pix_fmt,
- - video_st->codec->width, video_st->codec->height,
- - PIX_FMT_BGR24,
- + buffer_width, buffer_height,
- + AV_PIX_FMT_BGR24,
- SWS_BICUBIC,
- NULL, NULL, NULL
- );
-
- if (img_convert_ctx == NULL)
- return false;//CV_Error(0, "Cannot initialize the conversion context!");
- +
- +#if USE_AV_FRAME_GET_BUFFER
- + av_frame_unref(&rgb_picture);
- + rgb_picture.format = AV_PIX_FMT_BGR24;
- + rgb_picture.width = buffer_width;
- + rgb_picture.height = buffer_height;
- + if (0 != av_frame_get_buffer(&rgb_picture, 32))
- + {
- + CV_WARN("OutOfMemory");
- + return false;
- + }
- +#else
- + int aligns[AV_NUM_DATA_POINTERS];
- + avcodec_align_dimensions2(video_st->codec, &buffer_width, &buffer_height, aligns);
- + rgb_picture.data[0] = (uint8_t*)realloc(rgb_picture.data[0],
- + avpicture_get_size( AV_PIX_FMT_BGR24,
- + buffer_width, buffer_height ));
- + avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
- + AV_PIX_FMT_BGR24, buffer_width, buffer_height );
- +#endif
- + frame.width = video_st->codec->width;
- + frame.height = video_st->codec->height;
- + frame.cn = 3;
- + frame.data = rgb_picture.data[0];
- + frame.step = rgb_picture.linesize[0];
- }
-
- sws_scale(
- img_convert_ctx,
- picture->data,
- picture->linesize,
- - 0, video_st->codec->height,
- + 0, video_st->codec->coded_height,
- rgb_picture.data,
- rgb_picture.linesize
- );
- @@ -1099,10 +1327,20 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo
- uint8_t * picture_buf;
- int size;
-
- +#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
- + ? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
- + picture = av_frame_alloc();
- +#else
- picture = avcodec_alloc_frame();
- +#endif
- if (!picture)
- return NULL;
- - size = avpicture_get_size( (PixelFormat) pix_fmt, width, height);
- +
- + picture->format = pix_fmt;
- + picture->width = width;
- + picture->height = height;
- +
- + size = avpicture_get_size( (AVPixelFormat) pix_fmt, width, height);
- if(alloc){
- picture_buf = (uint8_t *) malloc(size);
- if (!picture_buf)
- @@ -1111,7 +1349,7 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo
- return NULL;
- }
- avpicture_fill((AVPicture *)picture, picture_buf,
- - (PixelFormat) pix_fmt, width, height);
- + (AVPixelFormat) pix_fmt, width, height);
- }
- else {
- }
- @@ -1211,7 +1449,7 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
- #endif
-
- c->gop_size = 12; /* emit one intra frame every twelve frames at most */
- - c->pix_fmt = (PixelFormat) pixel_format;
- + c->pix_fmt = (AVPixelFormat) pixel_format;
-
- if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO)) {
- c->max_b_frames = 2;
- @@ -1372,12 +1610,12 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
- #endif
-
- // check parameters
- - if (input_pix_fmt == PIX_FMT_BGR24) {
- + if (input_pix_fmt == AV_PIX_FMT_BGR24) {
- if (cn != 3) {
- return false;
- }
- }
- - else if (input_pix_fmt == PIX_FMT_GRAY8) {
- + else if (input_pix_fmt == AV_PIX_FMT_GRAY8) {
- if (cn != 1) {
- return false;
- }
- @@ -1390,13 +1628,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
- assert( input_picture );
- // let input_picture point to the raw data buffer of 'image'
- avpicture_fill((AVPicture *)input_picture, (uint8_t *) data,
- - (PixelFormat)input_pix_fmt, width, height);
- + (AVPixelFormat)input_pix_fmt, width, height);
-
- if( !img_convert_ctx )
- {
- img_convert_ctx = sws_getContext(width,
- height,
- - (PixelFormat)input_pix_fmt,
- + (AVPixelFormat)input_pix_fmt,
- c->width,
- c->height,
- c->pix_fmt,
- @@ -1414,7 +1652,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
- }
- else{
- avpicture_fill((AVPicture *)picture, (uint8_t *) data,
- - (PixelFormat)input_pix_fmt, width, height);
- + (AVPixelFormat)input_pix_fmt, width, height);
- }
-
- picture->pts = frame_idx;
- @@ -1547,10 +1785,10 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
-
- /* determine optimal pixel format */
- if (is_color) {
- - input_pix_fmt = PIX_FMT_BGR24;
- + input_pix_fmt = AV_PIX_FMT_BGR24;
- }
- else {
- - input_pix_fmt = PIX_FMT_GRAY8;
- + input_pix_fmt = AV_PIX_FMT_GRAY8;
- }
-
- /* Lookup codec_id for given fourcc */
- @@ -1587,21 +1825,21 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
- break;
- #endif
- case CV_CODEC(CODEC_ID_HUFFYUV):
- - codec_pix_fmt = PIX_FMT_YUV422P;
- + codec_pix_fmt = AV_PIX_FMT_YUV422P;
- break;
- case CV_CODEC(CODEC_ID_MJPEG):
- case CV_CODEC(CODEC_ID_LJPEG):
- - codec_pix_fmt = PIX_FMT_YUVJ420P;
- + codec_pix_fmt = AV_PIX_FMT_YUVJ420P;
- bitrate_scale = 3;
- break;
- case CV_CODEC(CODEC_ID_RAWVIDEO):
- - codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 ||
- - input_pix_fmt == PIX_FMT_GRAY16LE ||
- - input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P;
- + codec_pix_fmt = input_pix_fmt == AV_PIX_FMT_GRAY8 ||
- + input_pix_fmt == AV_PIX_FMT_GRAY16LE ||
- + input_pix_fmt == AV_PIX_FMT_GRAY16BE ? input_pix_fmt : AV_PIX_FMT_YUV420P;
- break;
- default:
- // good for lossy formats, MPEG, etc.
- - codec_pix_fmt = PIX_FMT_YUV420P;
- + codec_pix_fmt = AV_PIX_FMT_YUV420P;
- break;
- }
-
- @@ -1826,7 +2064,7 @@ struct OutputMediaStream_FFMPEG
- void write(unsigned char* data, int size, int keyFrame);
-
- // add a video output stream to the container
- - static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format);
- + static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, AVPixelFormat pixel_format);
-
- AVOutputFormat* fmt_;
- AVFormatContext* oc_;
- @@ -1873,7 +2111,7 @@ void OutputMediaStream_FFMPEG::close()
- }
- }
-
- -AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format)
- +AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, AVPixelFormat pixel_format)
- {
- #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
- AVStream* st = avformat_new_stream(oc, 0);
- @@ -2011,7 +2249,7 @@ bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height,
- oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG
-
- // set a few optimal pixel formats for lossless codecs of interest..
- - PixelFormat codec_pix_fmt = PIX_FMT_YUV420P;
- + AVPixelFormat codec_pix_fmt = AV_PIX_FMT_YUV420P;
- int bitrate_scale = 64;
-
- // TODO -- safe to ignore output audio stream?
- @@ -2150,6 +2388,10 @@ struct InputMediaStream_FFMPEG
- AVFormatContext* ctx_;
- int video_stream_id_;
- AVPacket pkt_;
- +
- +#if USE_AV_INTERRUPT_CALLBACK
- + AVInterruptCallbackMetadata interrupt_metadata;
- +#endif
- };
-
- bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
- @@ -2160,6 +2402,16 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
- video_stream_id_ = -1;
- memset(&pkt_, 0, sizeof(AVPacket));
-
- +#if USE_AV_INTERRUPT_CALLBACK
- + /* interrupt callback */
- + interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
- + get_monotonic_time(&interrupt_metadata.value);
- +
- + ctx_ = avformat_alloc_context();
- + ctx_->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
- + ctx_->interrupt_callback.opaque = &interrupt_metadata;
- +#endif
- +
- #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
- avformat_network_init();
- #endif
- @@ -2220,15 +2472,15 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
-
- switch (enc->pix_fmt)
- {
- - case PIX_FMT_YUV420P:
- + case AV_PIX_FMT_YUV420P:
- *chroma_format = ::VideoChromaFormat_YUV420;
- break;
-
- - case PIX_FMT_YUV422P:
- + case AV_PIX_FMT_YUV422P:
- *chroma_format = ::VideoChromaFormat_YUV422;
- break;
-
- - case PIX_FMT_YUV444P:
- + case AV_PIX_FMT_YUV444P:
- *chroma_format = ::VideoChromaFormat_YUV444;
- break;
-
- @@ -2276,11 +2528,23 @@ bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFi
- // get the next frame
- for (;;)
- {
- +#if USE_AV_INTERRUPT_CALLBACK
- + if(interrupt_metadata.timeout)
- + {
- + break;
- + }
- +#endif
- +
- int ret = av_read_frame(ctx_, &pkt_);
-
- if (ret == AVERROR(EAGAIN))
- continue;
-
- +#if USE_AV_INTERRUPT_CALLBACK
- + // update interrupt value
- + get_monotonic_time(&interrupt_metadata.value);
- +#endif
- +
- if (ret < 0)
- {
- if (ret == (int)AVERROR_EOF)
|