cannelloni: needs dynamic library
[buildroot-gz.git] / package / opencv / 0001-ffmpeg30.patch
blob70b6510b15b4fd0ca9cd4873d1fbb9bd50d6ae94
1 From a61b19b524cd2b66a7c43e67edd7cc780bf46cbb Mon Sep 17 00:00:00 2001
2 From: Alexander Alekhin <alexander.alekhin@itseez.com>
3 Date: Wed, 2 Mar 2016 17:54:17 +0300
4 Subject: [PATCH] backport ffmpeg fixes
6 Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
7 Downloaded from upstream commit:
8 https://github.com/Itseez/opencv/commit/a61b19b524cd2b66a7c43e67edd7cc780bf46cbb
9 ---
10 modules/highgui/src/cap_ffmpeg_impl.hpp | 364 +++++++++++++++++++++++++++-----
11 1 file changed, 314 insertions(+), 50 deletions(-)
13 diff --git a/modules/highgui/src/cap_ffmpeg_impl.hpp b/modules/highgui/src/cap_ffmpeg_impl.hpp
14 index 1b79870..6df542a 100644
15 --- a/modules/highgui/src/cap_ffmpeg_impl.hpp
16 +++ b/modules/highgui/src/cap_ffmpeg_impl.hpp
17 @@ -118,11 +118,6 @@ extern "C" {
18 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
19 #endif
21 -/* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */
22 -#ifndef PIX_FMT_RGBA32
23 -#define PIX_FMT_RGBA32 PIX_FMT_RGB32
24 -#endif
26 #define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c )
28 #if defined WIN32 || defined _WIN32
29 @@ -132,6 +127,11 @@ extern "C" {
30 #include <stdio.h>
31 #include <sys/types.h>
32 #include <sys/sysctl.h>
33 + #include <sys/time.h>
34 +#if defined __APPLE__
35 + #include <mach/clock.h>
36 + #include <mach/mach.h>
37 +#endif
38 #endif
40 #ifndef MIN
41 @@ -156,6 +156,155 @@ extern "C" {
42 # define CV_CODEC(name) name
43 #endif
45 +#if LIBAVUTIL_BUILD < (LIBAVUTIL_VERSION_MICRO >= 100 \
46 + ? CALC_FFMPEG_VERSION(51, 74, 100) : CALC_FFMPEG_VERSION(51, 42, 0))
47 +#define AVPixelFormat PixelFormat
48 +#define AV_PIX_FMT_BGR24 PIX_FMT_BGR24
49 +#define AV_PIX_FMT_RGB24 PIX_FMT_RGB24
50 +#define AV_PIX_FMT_GRAY8 PIX_FMT_GRAY8
51 +#define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
52 +#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
53 +#define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
54 +#define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
55 +#define AV_PIX_FMT_GRAY16LE PIX_FMT_GRAY16LE
56 +#define AV_PIX_FMT_GRAY16BE PIX_FMT_GRAY16BE
57 +#endif
59 +#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
60 + ? CALC_FFMPEG_VERSION(52, 38, 100) : CALC_FFMPEG_VERSION(52, 13, 0))
61 +#define USE_AV_FRAME_GET_BUFFER 1
62 +#else
63 +#define USE_AV_FRAME_GET_BUFFER 0
64 +#ifndef AV_NUM_DATA_POINTERS // required for 0.7.x/0.8.x ffmpeg releases
65 +#define AV_NUM_DATA_POINTERS 4
66 +#endif
67 +#endif
70 +#ifndef USE_AV_INTERRUPT_CALLBACK
71 +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 21, 0)
72 +#define USE_AV_INTERRUPT_CALLBACK 1
73 +#else
74 +#define USE_AV_INTERRUPT_CALLBACK 0
75 +#endif
76 +#endif
78 +#if USE_AV_INTERRUPT_CALLBACK
79 +#define LIBAVFORMAT_INTERRUPT_TIMEOUT_MS 30000
81 +#ifdef WIN32
82 +// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
84 +static
85 +inline LARGE_INTEGER get_filetime_offset()
87 + SYSTEMTIME s;
88 + FILETIME f;
89 + LARGE_INTEGER t;
91 + s.wYear = 1970;
92 + s.wMonth = 1;
93 + s.wDay = 1;
94 + s.wHour = 0;
95 + s.wMinute = 0;
96 + s.wSecond = 0;
97 + s.wMilliseconds = 0;
98 + SystemTimeToFileTime(&s, &f);
99 + t.QuadPart = f.dwHighDateTime;
100 + t.QuadPart <<= 32;
101 + t.QuadPart |= f.dwLowDateTime;
102 + return t;
105 +static
106 +inline void get_monotonic_time(timespec *tv)
108 + LARGE_INTEGER t;
109 + FILETIME f;
110 + double microseconds;
111 + static LARGE_INTEGER offset;
112 + static double frequencyToMicroseconds;
113 + static int initialized = 0;
114 + static BOOL usePerformanceCounter = 0;
116 + if (!initialized)
118 + LARGE_INTEGER performanceFrequency;
119 + initialized = 1;
120 + usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
121 + if (usePerformanceCounter)
123 + QueryPerformanceCounter(&offset);
124 + frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
126 + else
128 + offset = get_filetime_offset();
129 + frequencyToMicroseconds = 10.;
133 + if (usePerformanceCounter)
135 + QueryPerformanceCounter(&t);
136 + } else {
137 + GetSystemTimeAsFileTime(&f);
138 + t.QuadPart = f.dwHighDateTime;
139 + t.QuadPart <<= 32;
140 + t.QuadPart |= f.dwLowDateTime;
143 + t.QuadPart -= offset.QuadPart;
144 + microseconds = (double)t.QuadPart / frequencyToMicroseconds;
145 + t.QuadPart = microseconds;
146 + tv->tv_sec = t.QuadPart / 1000000;
147 + tv->tv_nsec = (t.QuadPart % 1000000) * 1000;
149 +#else
150 +static
151 +inline void get_monotonic_time(timespec *time)
153 +#if defined(__APPLE__) && defined(__MACH__)
154 + clock_serv_t cclock;
155 + mach_timespec_t mts;
156 + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
157 + clock_get_time(cclock, &mts);
158 + mach_port_deallocate(mach_task_self(), cclock);
159 + time->tv_sec = mts.tv_sec;
160 + time->tv_nsec = mts.tv_nsec;
161 +#else
162 + clock_gettime(CLOCK_MONOTONIC, time);
163 +#endif
165 +#endif
167 +static
168 +inline timespec get_monotonic_time_diff(timespec start, timespec end)
170 + timespec temp;
171 + if (end.tv_nsec - start.tv_nsec < 0)
173 + temp.tv_sec = end.tv_sec - start.tv_sec - 1;
174 + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
176 + else
178 + temp.tv_sec = end.tv_sec - start.tv_sec;
179 + temp.tv_nsec = end.tv_nsec - start.tv_nsec;
181 + return temp;
184 +static
185 +inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
187 + timespec delta = get_monotonic_time_diff(time1, time2);
188 + double milliseconds = delta.tv_sec * 1000 + (double)delta.tv_nsec / 1000000.0;
190 + return milliseconds;
192 +#endif // USE_AV_INTERRUPT_CALLBACK
194 static int get_number_of_cpus(void)
196 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0)
197 @@ -205,12 +354,36 @@ struct Image_FFMPEG
201 +#if USE_AV_INTERRUPT_CALLBACK
202 +struct AVInterruptCallbackMetadata
204 + timespec value;
205 + unsigned int timeout_after_ms;
206 + int timeout;
209 +static
210 inline void _opencv_ffmpeg_free(void** ptr)
212 if(*ptr) free(*ptr);
213 *ptr = 0;
216 +static
217 +inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
219 + AVInterruptCallbackMetadata* metadata = (AVInterruptCallbackMetadata*)ptr;
220 + assert(metadata);
222 + timespec now;
223 + get_monotonic_time(&now);
225 + metadata->timeout = get_monotonic_time_diff_ms(metadata->value, now) > metadata->timeout_after_ms;
227 + return metadata->timeout ? -1 : 0;
229 +#endif
232 struct CvCapture_FFMPEG
234 @@ -264,6 +437,10 @@ struct CvCapture_FFMPEG
235 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
236 AVDictionary *dict;
237 #endif
239 +#if USE_AV_INTERRUPT_CALLBACK
240 + AVInterruptCallbackMetadata interrupt_metadata;
241 +#endif
244 void CvCapture_FFMPEG::init()
245 @@ -301,8 +478,10 @@ void CvCapture_FFMPEG::close()
247 if( picture )
249 - // FFmpeg and Libav added avcodec_free_frame in different versions.
250 #if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
251 + ? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
252 + av_frame_free(&picture);
253 +#elif LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
254 ? CALC_FFMPEG_VERSION(54, 59, 100) : CALC_FFMPEG_VERSION(54, 28, 0))
255 avcodec_free_frame(&picture);
256 #else
257 @@ -333,11 +512,15 @@ void CvCapture_FFMPEG::close()
258 ic = NULL;
261 +#if USE_AV_FRAME_GET_BUFFER
262 + av_frame_unref(&rgb_picture);
263 +#else
264 if( rgb_picture.data[0] )
266 free( rgb_picture.data[0] );
267 rgb_picture.data[0] = 0;
269 +#endif
271 // free last packet if exist
272 if (packet.data) {
273 @@ -556,6 +739,16 @@ bool CvCapture_FFMPEG::open( const char* _filename )
275 close();
277 +#if USE_AV_INTERRUPT_CALLBACK
278 + /* interrupt callback */
279 + interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
280 + get_monotonic_time(&interrupt_metadata.value);
282 + ic = avformat_alloc_context();
283 + ic->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
284 + ic->interrupt_callback.opaque = &interrupt_metadata;
285 +#endif
287 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
288 av_dict_set(&dict, "rtsp_transport", "tcp", 0);
289 int err = avformat_open_input(&ic, _filename, NULL, &dict);
290 @@ -619,19 +812,18 @@ bool CvCapture_FFMPEG::open( const char* _filename )
292 video_stream = i;
293 video_st = ic->streams[i];
294 +#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
295 + ? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
296 + picture = av_frame_alloc();
297 +#else
298 picture = avcodec_alloc_frame();
300 - rgb_picture.data[0] = (uint8_t*)malloc(
301 - avpicture_get_size( PIX_FMT_BGR24,
302 - enc->width, enc->height ));
303 - avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
304 - PIX_FMT_BGR24, enc->width, enc->height );
305 +#endif
307 frame.width = enc->width;
308 frame.height = enc->height;
309 frame.cn = 3;
310 - frame.step = rgb_picture.linesize[0];
311 - frame.data = rgb_picture.data[0];
312 + frame.step = 0;
313 + frame.data = NULL;
314 break;
317 @@ -668,6 +860,16 @@ bool CvCapture_FFMPEG::grabFrame()
318 // get the next frame
319 while (!valid)
321 + av_free_packet (&packet);
323 +#if USE_AV_INTERRUPT_CALLBACK
324 + if (interrupt_metadata.timeout)
326 + valid = false;
327 + break;
329 +#endif
331 int ret = av_read_frame(ic, &packet);
332 if (ret == AVERROR(EAGAIN)) continue;
334 @@ -703,6 +905,11 @@ bool CvCapture_FFMPEG::grabFrame()
335 picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts;
336 frame_number++;
337 valid = true;
339 +#if USE_AV_INTERRUPT_CALLBACK
340 + // update interrupt value
341 + get_monotonic_time(&interrupt_metadata.value);
342 +#endif
344 else
346 @@ -727,38 +934,59 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int*
347 if( !video_st || !picture->data[0] )
348 return false;
350 - avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24,
351 - video_st->codec->width, video_st->codec->height);
353 if( img_convert_ctx == NULL ||
354 frame.width != video_st->codec->width ||
355 - frame.height != video_st->codec->height )
356 + frame.height != video_st->codec->height ||
357 + frame.data == NULL )
359 - if( img_convert_ctx )
360 - sws_freeContext(img_convert_ctx);
362 - frame.width = video_st->codec->width;
363 - frame.height = video_st->codec->height;
364 + // Some sws_scale optimizations have some assumptions about alignment of data/step/width/height
365 + // Also we use coded_width/height to workaround problem with legacy ffmpeg versions (like n0.8)
366 + int buffer_width = video_st->codec->coded_width, buffer_height = video_st->codec->coded_height;
368 img_convert_ctx = sws_getCachedContext(
369 - NULL,
370 - video_st->codec->width, video_st->codec->height,
371 + img_convert_ctx,
372 + buffer_width, buffer_height,
373 video_st->codec->pix_fmt,
374 - video_st->codec->width, video_st->codec->height,
375 - PIX_FMT_BGR24,
376 + buffer_width, buffer_height,
377 + AV_PIX_FMT_BGR24,
378 SWS_BICUBIC,
379 NULL, NULL, NULL
382 if (img_convert_ctx == NULL)
383 return false;//CV_Error(0, "Cannot initialize the conversion context!");
385 +#if USE_AV_FRAME_GET_BUFFER
386 + av_frame_unref(&rgb_picture);
387 + rgb_picture.format = AV_PIX_FMT_BGR24;
388 + rgb_picture.width = buffer_width;
389 + rgb_picture.height = buffer_height;
390 + if (0 != av_frame_get_buffer(&rgb_picture, 32))
392 + CV_WARN("OutOfMemory");
393 + return false;
395 +#else
396 + int aligns[AV_NUM_DATA_POINTERS];
397 + avcodec_align_dimensions2(video_st->codec, &buffer_width, &buffer_height, aligns);
398 + rgb_picture.data[0] = (uint8_t*)realloc(rgb_picture.data[0],
399 + avpicture_get_size( AV_PIX_FMT_BGR24,
400 + buffer_width, buffer_height ));
401 + avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
402 + AV_PIX_FMT_BGR24, buffer_width, buffer_height );
403 +#endif
404 + frame.width = video_st->codec->width;
405 + frame.height = video_st->codec->height;
406 + frame.cn = 3;
407 + frame.data = rgb_picture.data[0];
408 + frame.step = rgb_picture.linesize[0];
411 sws_scale(
412 img_convert_ctx,
413 picture->data,
414 picture->linesize,
415 - 0, video_st->codec->height,
416 + 0, video_st->codec->coded_height,
417 rgb_picture.data,
418 rgb_picture.linesize
420 @@ -1099,10 +1327,20 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo
421 uint8_t * picture_buf;
422 int size;
424 +#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
425 + ? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
426 + picture = av_frame_alloc();
427 +#else
428 picture = avcodec_alloc_frame();
429 +#endif
430 if (!picture)
431 return NULL;
432 - size = avpicture_get_size( (PixelFormat) pix_fmt, width, height);
434 + picture->format = pix_fmt;
435 + picture->width = width;
436 + picture->height = height;
438 + size = avpicture_get_size( (AVPixelFormat) pix_fmt, width, height);
439 if(alloc){
440 picture_buf = (uint8_t *) malloc(size);
441 if (!picture_buf)
442 @@ -1111,7 +1349,7 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo
443 return NULL;
445 avpicture_fill((AVPicture *)picture, picture_buf,
446 - (PixelFormat) pix_fmt, width, height);
447 + (AVPixelFormat) pix_fmt, width, height);
449 else {
451 @@ -1211,7 +1449,7 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
452 #endif
454 c->gop_size = 12; /* emit one intra frame every twelve frames at most */
455 - c->pix_fmt = (PixelFormat) pixel_format;
456 + c->pix_fmt = (AVPixelFormat) pixel_format;
458 if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO)) {
459 c->max_b_frames = 2;
460 @@ -1372,12 +1610,12 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
461 #endif
463 // check parameters
464 - if (input_pix_fmt == PIX_FMT_BGR24) {
465 + if (input_pix_fmt == AV_PIX_FMT_BGR24) {
466 if (cn != 3) {
467 return false;
470 - else if (input_pix_fmt == PIX_FMT_GRAY8) {
471 + else if (input_pix_fmt == AV_PIX_FMT_GRAY8) {
472 if (cn != 1) {
473 return false;
475 @@ -1390,13 +1628,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
476 assert( input_picture );
477 // let input_picture point to the raw data buffer of 'image'
478 avpicture_fill((AVPicture *)input_picture, (uint8_t *) data,
479 - (PixelFormat)input_pix_fmt, width, height);
480 + (AVPixelFormat)input_pix_fmt, width, height);
482 if( !img_convert_ctx )
484 img_convert_ctx = sws_getContext(width,
485 height,
486 - (PixelFormat)input_pix_fmt,
487 + (AVPixelFormat)input_pix_fmt,
488 c->width,
489 c->height,
490 c->pix_fmt,
491 @@ -1414,7 +1652,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
493 else{
494 avpicture_fill((AVPicture *)picture, (uint8_t *) data,
495 - (PixelFormat)input_pix_fmt, width, height);
496 + (AVPixelFormat)input_pix_fmt, width, height);
499 picture->pts = frame_idx;
500 @@ -1547,10 +1785,10 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
502 /* determine optimal pixel format */
503 if (is_color) {
504 - input_pix_fmt = PIX_FMT_BGR24;
505 + input_pix_fmt = AV_PIX_FMT_BGR24;
507 else {
508 - input_pix_fmt = PIX_FMT_GRAY8;
509 + input_pix_fmt = AV_PIX_FMT_GRAY8;
512 /* Lookup codec_id for given fourcc */
513 @@ -1587,21 +1825,21 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
514 break;
515 #endif
516 case CV_CODEC(CODEC_ID_HUFFYUV):
517 - codec_pix_fmt = PIX_FMT_YUV422P;
518 + codec_pix_fmt = AV_PIX_FMT_YUV422P;
519 break;
520 case CV_CODEC(CODEC_ID_MJPEG):
521 case CV_CODEC(CODEC_ID_LJPEG):
522 - codec_pix_fmt = PIX_FMT_YUVJ420P;
523 + codec_pix_fmt = AV_PIX_FMT_YUVJ420P;
524 bitrate_scale = 3;
525 break;
526 case CV_CODEC(CODEC_ID_RAWVIDEO):
527 - codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 ||
528 - input_pix_fmt == PIX_FMT_GRAY16LE ||
529 - input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P;
530 + codec_pix_fmt = input_pix_fmt == AV_PIX_FMT_GRAY8 ||
531 + input_pix_fmt == AV_PIX_FMT_GRAY16LE ||
532 + input_pix_fmt == AV_PIX_FMT_GRAY16BE ? input_pix_fmt : AV_PIX_FMT_YUV420P;
533 break;
534 default:
535 // good for lossy formats, MPEG, etc.
536 - codec_pix_fmt = PIX_FMT_YUV420P;
537 + codec_pix_fmt = AV_PIX_FMT_YUV420P;
538 break;
541 @@ -1826,7 +2064,7 @@ struct OutputMediaStream_FFMPEG
542 void write(unsigned char* data, int size, int keyFrame);
544 // add a video output stream to the container
545 - static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format);
546 + static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, AVPixelFormat pixel_format);
548 AVOutputFormat* fmt_;
549 AVFormatContext* oc_;
550 @@ -1873,7 +2111,7 @@ void OutputMediaStream_FFMPEG::close()
554 -AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format)
555 +AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, AVPixelFormat pixel_format)
557 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
558 AVStream* st = avformat_new_stream(oc, 0);
559 @@ -2011,7 +2249,7 @@ bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height,
560 oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG
562 // set a few optimal pixel formats for lossless codecs of interest..
563 - PixelFormat codec_pix_fmt = PIX_FMT_YUV420P;
564 + AVPixelFormat codec_pix_fmt = AV_PIX_FMT_YUV420P;
565 int bitrate_scale = 64;
567 // TODO -- safe to ignore output audio stream?
568 @@ -2150,6 +2388,10 @@ struct InputMediaStream_FFMPEG
569 AVFormatContext* ctx_;
570 int video_stream_id_;
571 AVPacket pkt_;
573 +#if USE_AV_INTERRUPT_CALLBACK
574 + AVInterruptCallbackMetadata interrupt_metadata;
575 +#endif
578 bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
579 @@ -2160,6 +2402,16 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
580 video_stream_id_ = -1;
581 memset(&pkt_, 0, sizeof(AVPacket));
583 +#if USE_AV_INTERRUPT_CALLBACK
584 + /* interrupt callback */
585 + interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
586 + get_monotonic_time(&interrupt_metadata.value);
588 + ctx_ = avformat_alloc_context();
589 + ctx_->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
590 + ctx_->interrupt_callback.opaque = &interrupt_metadata;
591 +#endif
593 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
594 avformat_network_init();
595 #endif
596 @@ -2220,15 +2472,15 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
598 switch (enc->pix_fmt)
600 - case PIX_FMT_YUV420P:
601 + case AV_PIX_FMT_YUV420P:
602 *chroma_format = ::VideoChromaFormat_YUV420;
603 break;
605 - case PIX_FMT_YUV422P:
606 + case AV_PIX_FMT_YUV422P:
607 *chroma_format = ::VideoChromaFormat_YUV422;
608 break;
610 - case PIX_FMT_YUV444P:
611 + case AV_PIX_FMT_YUV444P:
612 *chroma_format = ::VideoChromaFormat_YUV444;
613 break;
615 @@ -2276,11 +2528,23 @@ bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFi
616 // get the next frame
617 for (;;)
619 +#if USE_AV_INTERRUPT_CALLBACK
620 + if(interrupt_metadata.timeout)
622 + break;
624 +#endif
626 int ret = av_read_frame(ctx_, &pkt_);
628 if (ret == AVERROR(EAGAIN))
629 continue;
631 +#if USE_AV_INTERRUPT_CALLBACK
632 + // update interrupt value
633 + get_monotonic_time(&interrupt_metadata.value);
634 +#endif
636 if (ret < 0)
638 if (ret == (int)AVERROR_EOF)