Merge remote-tracking branch 'origin/2.4' into merge-2.4
[profile/ivi/opencv.git] / modules / highgui / src / cap_ffmpeg_impl.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                          License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "cap_ffmpeg_api.hpp"
44 #if !(defined(WIN32) || defined(_WIN32) || defined(WINCE))
45 # include <pthread.h>
46 #endif
47 #include <assert.h>
48 #include <algorithm>
49 #include <limits>
50
51 #define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c )
52
53 #if defined _MSC_VER && _MSC_VER >= 1200
54 #pragma warning( disable: 4244 4510 4512 4610 )
55 #endif
56
57 #ifdef __GNUC__
58 #  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
59 #endif
60
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
64
65 #include "ffmpeg_codecs.hpp"
66
67 #include <libavutil/mathematics.h>
68
69 #if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0)
70   #include <libavutil/opt.h>
71 #endif
72
73 #ifdef WIN32
74   #define HAVE_FFMPEG_SWSCALE 1
75   #include <libavcodec/avcodec.h>
76   #include <libswscale/swscale.h>
77 #else
78
79 #ifndef HAVE_FFMPEG_SWSCALE
80     #error "libswscale is necessary to build the newer OpenCV ffmpeg wrapper"
81 #endif
82
83 // if the header path is not specified explicitly, let's deduce it
84 #if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H
85
86 #if defined(HAVE_GENTOO_FFMPEG)
87   #define HAVE_LIBAVCODEC_AVCODEC_H 1
88   #if defined(HAVE_FFMPEG_SWSCALE)
89     #define HAVE_LIBSWSCALE_SWSCALE_H 1
90   #endif
91 #elif defined HAVE_FFMPEG
92   #define HAVE_FFMPEG_AVCODEC_H 1
93   #if defined(HAVE_FFMPEG_SWSCALE)
94     #define HAVE_FFMPEG_SWSCALE_H 1
95   #endif
96 #endif
97
98 #endif
99
100 #if defined(HAVE_FFMPEG_AVCODEC_H)
101   #include <ffmpeg/avcodec.h>
102 #endif
103 #if defined(HAVE_FFMPEG_SWSCALE_H)
104   #include <ffmpeg/swscale.h>
105 #endif
106
107 #if defined(HAVE_LIBAVCODEC_AVCODEC_H)
108   #include <libavcodec/avcodec.h>
109 #endif
110 #if defined(HAVE_LIBSWSCALE_SWSCALE_H)
111   #include <libswscale/swscale.h>
112 #endif
113
114 #endif
115
116 #ifdef __cplusplus
117 }
118 #endif
119
120 #if defined _MSC_VER && _MSC_VER >= 1200
121 #pragma warning( default: 4244 4510 4512 4610 )
122 #endif
123
124 #ifdef NDEBUG
125 #define CV_WARN(message)
126 #else
127 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
128 #endif
129
130 /* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */
131 #ifndef PIX_FMT_RGBA32
132 #define PIX_FMT_RGBA32 PIX_FMT_RGB32
133 #endif
134
135
136 #if defined WIN32 || defined _WIN32
137     #include <windows.h>
138 #elif defined __linux__ || defined __APPLE__
139     #include <unistd.h>
140     #include <stdio.h>
141     #include <sys/types.h>
142     #include <sys/sysctl.h>
143 #endif
144
145 #ifndef MIN
146 #define MIN(a, b) ((a) < (b) ? (a) : (b))
147 #endif
148
149 #if defined(__APPLE__)
150 #define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
151 #else
152 #define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE)
153 #endif
154
155 #ifndef AVERROR_EOF
156 #define AVERROR_EOF (-MKTAG( 'E','O','F',' '))
157 #endif
158
159 #if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0)
160 #  define CV_CODEC_ID AVCodecID
161 #  define CV_CODEC(name) AV_##name
162 #else
163 #  define CV_CODEC_ID CodecID
164 #  define CV_CODEC(name) name
165 #endif
166
167 static int get_number_of_cpus(void)
168 {
169 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0)
170     return 1;
171 #elif defined WIN32 || defined _WIN32
172     SYSTEM_INFO sysinfo;
173     GetSystemInfo( &sysinfo );
174
175     return (int)sysinfo.dwNumberOfProcessors;
176 #elif defined __linux__
177     return (int)sysconf( _SC_NPROCESSORS_ONLN );
178 #elif defined __APPLE__
179     int numCPU=0;
180     int mib[4];
181     size_t len = sizeof(numCPU);
182
183     // set the mib for hw.ncpu
184     mib[0] = CTL_HW;
185     mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
186
187     // get the number of CPUs from the system
188     sysctl(mib, 2, &numCPU, &len, NULL, 0);
189
190     if( numCPU < 1 )
191     {
192         mib[1] = HW_NCPU;
193         sysctl( mib, 2, &numCPU, &len, NULL, 0 );
194
195         if( numCPU < 1 )
196             numCPU = 1;
197     }
198
199     return (int)numCPU;
200 #else
201     return 1;
202 #endif
203 }
204
205
206 struct Image_FFMPEG
207 {
208     unsigned char* data;
209     int step;
210     int width;
211     int height;
212     int cn;
213 };
214
215
216 inline void _opencv_ffmpeg_free(void** ptr)
217 {
218     if(*ptr) free(*ptr);
219     *ptr = 0;
220 }
221
222
223 struct CvCapture_FFMPEG
224 {
225     bool open( const char* filename );
226     void close();
227
228     double getProperty(int);
229     bool setProperty(int, double);
230     bool grabFrame();
231     bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
232
233     void init();
234
235     void    seek(int64_t frame_number);
236     void    seek(double sec);
237     bool    slowSeek( int framenumber );
238
239     int64_t get_total_frames();
240     double  get_duration_sec();
241     double  get_fps();
242     int     get_bitrate();
243
244     double  r2d(AVRational r);
245     int64_t dts_to_frame_number(int64_t dts);
246     double  dts_to_sec(int64_t dts);
247
248     AVFormatContext * ic;
249     AVCodec         * avcodec;
250     int               video_stream;
251     AVStream        * video_st;
252     AVFrame         * picture;
253     AVFrame           rgb_picture;
254     int64_t           picture_pts;
255
256     AVPacket          packet;
257     Image_FFMPEG      frame;
258     struct SwsContext *img_convert_ctx;
259
260     int64_t frame_number, first_frame_number;
261
262     double eps_zero;
263 /*
264    'filename' contains the filename of the videosource,
265    'filename==NULL' indicates that ffmpeg's seek support works
266    for the particular file.
267    'filename!=NULL' indicates that the slow fallback function is used for seeking,
268    and so the filename is needed to reopen the file on backward seeking.
269 */
270     char              * filename;
271 };
272
273 void CvCapture_FFMPEG::init()
274 {
275     ic = 0;
276     video_stream = -1;
277     video_st = 0;
278     picture = 0;
279     picture_pts = AV_NOPTS_VALUE_;
280     first_frame_number = -1;
281     memset( &rgb_picture, 0, sizeof(rgb_picture) );
282     memset( &frame, 0, sizeof(frame) );
283     filename = 0;
284     memset(&packet, 0, sizeof(packet));
285     av_init_packet(&packet);
286     img_convert_ctx = 0;
287
288     avcodec = 0;
289     frame_number = 0;
290     eps_zero = 0.000025;
291 }
292
293
294 void CvCapture_FFMPEG::close()
295 {
296     if( img_convert_ctx )
297     {
298         sws_freeContext(img_convert_ctx);
299         img_convert_ctx = 0;
300     }
301
302     if( picture )
303         av_free(picture);
304
305     if( video_st )
306     {
307 #if LIBAVFORMAT_BUILD > 4628
308         avcodec_close( video_st->codec );
309
310 #else
311         avcodec_close( &(video_st->codec) );
312
313 #endif
314         video_st = NULL;
315     }
316
317     if( ic )
318     {
319 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
320         av_close_input_file(ic);
321 #else
322         avformat_close_input(&ic);
323 #endif
324
325         ic = NULL;
326     }
327
328     if( rgb_picture.data[0] )
329     {
330         free( rgb_picture.data[0] );
331         rgb_picture.data[0] = 0;
332     }
333
334     // free last packet if exist
335     if (packet.data) {
336         av_free_packet (&packet);
337         packet.data = NULL;
338     }
339
340     init();
341 }
342
343
344 #ifndef AVSEEK_FLAG_FRAME
345 #define AVSEEK_FLAG_FRAME 0
346 #endif
347 #ifndef AVSEEK_FLAG_ANY
348 #define AVSEEK_FLAG_ANY 1
349 #endif
350
351 class ImplMutex
352 {
353 public:
354     ImplMutex() { init(); }
355     ~ImplMutex() { destroy(); }
356
357     void init();
358     void destroy();
359
360     void lock();
361     bool trylock();
362     void unlock();
363
364     struct Impl;
365 protected:
366     Impl* impl;
367
368 private:
369     ImplMutex(const ImplMutex&);
370     ImplMutex& operator = (const ImplMutex& m);
371 };
372
373 #if defined WIN32 || defined _WIN32 || defined WINCE
374
375 struct ImplMutex::Impl
376 {
377     void init()
378     {
379 #if (_WIN32_WINNT >= 0x0600)
380         ::InitializeCriticalSectionEx(&cs, 1000, 0);
381 #else
382         ::InitializeCriticalSection(&cs);
383 #endif
384         refcount = 1;
385     }
386     void destroy() { DeleteCriticalSection(&cs); }
387
388     void lock() { EnterCriticalSection(&cs); }
389     bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
390     void unlock() { LeaveCriticalSection(&cs); }
391
392     CRITICAL_SECTION cs;
393     int refcount;
394 };
395
396 #ifndef __GNUC__
397 static int _interlockedExchangeAdd(int* addr, int delta)
398 {
399 #if defined _MSC_VER && _MSC_VER >= 1500
400     return (int)_InterlockedExchangeAdd((long volatile*)addr, delta);
401 #else
402     return (int)InterlockedExchangeAdd((long volatile*)addr, delta);
403 #endif
404 }
405 #endif // __GNUC__
406
407 #elif defined __APPLE__
408
409 #include <libkern/OSAtomic.h>
410
411 struct ImplMutex::Impl
412 {
413     void init() { sl = OS_SPINLOCK_INIT; refcount = 1; }
414     void destroy() { }
415
416     void lock() { OSSpinLockLock(&sl); }
417     bool trylock() { return OSSpinLockTry(&sl); }
418     void unlock() { OSSpinLockUnlock(&sl); }
419
420     OSSpinLock sl;
421     int refcount;
422 };
423
424 #elif defined __linux__ && !defined ANDROID
425
426 struct ImplMutex::Impl
427 {
428     void init() { pthread_spin_init(&sl, 0); refcount = 1; }
429     void destroy() { pthread_spin_destroy(&sl); }
430
431     void lock() { pthread_spin_lock(&sl); }
432     bool trylock() { return pthread_spin_trylock(&sl) == 0; }
433     void unlock() { pthread_spin_unlock(&sl); }
434
435     pthread_spinlock_t sl;
436     int refcount;
437 };
438
439 #else
440
441 struct ImplMutex::Impl
442 {
443     void init() { pthread_mutex_init(&sl, 0); refcount = 1; }
444     void destroy() { pthread_mutex_destroy(&sl); }
445
446     void lock() { pthread_mutex_lock(&sl); }
447     bool trylock() { return pthread_mutex_trylock(&sl) == 0; }
448     void unlock() { pthread_mutex_unlock(&sl); }
449
450     pthread_mutex_t sl;
451     int refcount;
452 };
453
454 #endif
455
456 void ImplMutex::init()
457 {
458     impl = (Impl*)malloc(sizeof(Impl));
459     impl->init();
460 }
461 void ImplMutex::destroy()
462 {
463     impl->destroy();
464     free(impl);
465     impl = NULL;
466 }
467 void ImplMutex::lock() { impl->lock(); }
468 void ImplMutex::unlock() { impl->unlock(); }
469 bool ImplMutex::trylock() { return impl->trylock(); }
470
471 static int LockCallBack(void **mutex, AVLockOp op)
472 {
473     ImplMutex* localMutex = reinterpret_cast<ImplMutex*>(*mutex);
474     switch (op)
475     {
476         case AV_LOCK_CREATE:
477             localMutex = reinterpret_cast<ImplMutex*>(malloc(sizeof(ImplMutex)));
478             localMutex->init();
479             *mutex = localMutex;
480             if (!*mutex)
481                 return 1;
482         break;
483
484         case AV_LOCK_OBTAIN:
485             localMutex->lock();
486         break;
487
488         case AV_LOCK_RELEASE:
489             localMutex->unlock();
490         break;
491
492         case AV_LOCK_DESTROY:
493             localMutex->destroy();
494             free(localMutex);
495             localMutex = NULL;
496         break;
497     }
498     return 0;
499 }
500
501 static ImplMutex _mutex;
502 static bool _initialized = false;
503
504 class InternalFFMpegRegister
505 {
506 public:
507     InternalFFMpegRegister()
508     {
509         _mutex.lock();
510         if (!_initialized)
511         {
512     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
513             avformat_network_init();
514     #endif
515
516             /* register all codecs, demux and protocols */
517             av_register_all();
518
519             /* register a callback function for synchronization */
520             av_lockmgr_register(&LockCallBack);
521
522             av_log_set_level(AV_LOG_ERROR);
523
524             _initialized = true;
525         }
526         _mutex.unlock();
527     }
528
529     ~InternalFFMpegRegister()
530     {
531         _initialized = false;
532         av_lockmgr_register(NULL);
533     }
534 };
535
536 static InternalFFMpegRegister _init;
537
538 bool CvCapture_FFMPEG::open( const char* _filename )
539 {
540     unsigned i;
541     bool valid = false;
542
543     close();
544
545 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
546     int err = avformat_open_input(&ic, _filename, NULL, NULL);
547 #else
548     int err = av_open_input_file(&ic, _filename, NULL, 0, NULL);
549 #endif
550
551     if (err < 0)
552     {
553         CV_WARN("Error opening file");
554         goto exit_func;
555     }
556     err =
557 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
558     avformat_find_stream_info(ic, NULL);
559 #else
560     av_find_stream_info(ic);
561 #endif
562     if (err < 0)
563     {
564         CV_WARN("Could not find codec parameters");
565         goto exit_func;
566     }
567     for(i = 0; i < ic->nb_streams; i++)
568     {
569 #if LIBAVFORMAT_BUILD > 4628
570         AVCodecContext *enc = ic->streams[i]->codec;
571 #else
572         AVCodecContext *enc = &ic->streams[i]->codec;
573 #endif
574
575 //#ifdef FF_API_THREAD_INIT
576 //        avcodec_thread_init(enc, get_number_of_cpus());
577 //#else
578         enc->thread_count = get_number_of_cpus();
579 //#endif
580
581 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
582 #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
583 #endif
584
585         if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0)
586         {
587             // backup encoder' width/height
588             int enc_width = enc->width;
589             int enc_height = enc->height;
590
591             AVCodec *codec = avcodec_find_decoder(enc->codec_id);
592             if (!codec ||
593 #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
594                 avcodec_open2(enc, codec, NULL)
595 #else
596                 avcodec_open(enc, codec)
597 #endif
598                 < 0)
599                 goto exit_func;
600
601             // checking width/height (since decoder can sometimes alter it, eg. vp6f)
602             if (enc_width && (enc->width != enc_width)) { enc->width = enc_width; }
603             if (enc_height && (enc->height != enc_height)) { enc->height = enc_height; }
604
605             video_stream = i;
606             video_st = ic->streams[i];
607             picture = avcodec_alloc_frame();
608
609             rgb_picture.data[0] = (uint8_t*)malloc(
610                     avpicture_get_size( PIX_FMT_BGR24,
611                                         enc->width, enc->height ));
612             avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
613                             PIX_FMT_BGR24, enc->width, enc->height );
614
615             frame.width = enc->width;
616             frame.height = enc->height;
617             frame.cn = 3;
618             frame.step = rgb_picture.linesize[0];
619             frame.data = rgb_picture.data[0];
620             break;
621         }
622     }
623
624     if(video_stream >= 0) valid = true;
625
626 exit_func:
627
628     if( !valid )
629         close();
630
631     return valid;
632 }
633
634
635 bool CvCapture_FFMPEG::grabFrame()
636 {
637     bool valid = false;
638     int got_picture;
639
640     int count_errs = 0;
641     const int max_number_of_attempts = 1 << 16;
642
643     if( !ic || !video_st )  return false;
644
645     if( ic->streams[video_stream]->nb_frames > 0 &&
646         frame_number > ic->streams[video_stream]->nb_frames )
647         return false;
648
649     av_free_packet (&packet);
650
651     picture_pts = AV_NOPTS_VALUE_;
652
653     // get the next frame
654     while (!valid)
655     {
656         int ret = av_read_frame(ic, &packet);
657         if (ret == AVERROR(EAGAIN)) continue;
658
659         /* else if (ret < 0) break; */
660
661         if( packet.stream_index != video_stream )
662         {
663             av_free_packet (&packet);
664             count_errs++;
665             if (count_errs > max_number_of_attempts)
666                 break;
667             continue;
668         }
669
670         // Decode video frame
671         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
672             avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
673         #elif LIBAVFORMAT_BUILD > 4628
674                 avcodec_decode_video(video_st->codec,
675                                      picture, &got_picture,
676                                      packet.data, packet.size);
677         #else
678                 avcodec_decode_video(&video_st->codec,
679                                      picture, &got_picture,
680                                      packet.data, packet.size);
681         #endif
682
683         // Did we get a video frame?
684         if(got_picture)
685         {
686             //picture_pts = picture->best_effort_timestamp;
687             if( picture_pts == AV_NOPTS_VALUE_ )
688                 picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts;
689             frame_number++;
690             valid = true;
691         }
692         else
693         {
694             count_errs++;
695             if (count_errs > max_number_of_attempts)
696                 break;
697         }
698
699         av_free_packet (&packet);
700     }
701
702     if( valid && first_frame_number < 0 )
703         first_frame_number = dts_to_frame_number(picture_pts);
704
705     // return if we have a new picture or not
706     return valid;
707 }
708
709
710 bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
711 {
712     if( !video_st || !picture->data[0] )
713         return false;
714
715     avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24,
716                    video_st->codec->width, video_st->codec->height);
717
718     if( img_convert_ctx == NULL ||
719         frame.width != video_st->codec->width ||
720         frame.height != video_st->codec->height )
721     {
722         if( img_convert_ctx )
723             sws_freeContext(img_convert_ctx);
724
725         frame.width = video_st->codec->width;
726         frame.height = video_st->codec->height;
727
728         img_convert_ctx = sws_getCachedContext(
729                 NULL,
730                 video_st->codec->width, video_st->codec->height,
731                 video_st->codec->pix_fmt,
732                 video_st->codec->width, video_st->codec->height,
733                 PIX_FMT_BGR24,
734                 SWS_BICUBIC,
735                 NULL, NULL, NULL
736                 );
737
738         if (img_convert_ctx == NULL)
739             return false;//CV_Error(0, "Cannot initialize the conversion context!");
740     }
741
742     sws_scale(
743             img_convert_ctx,
744             picture->data,
745             picture->linesize,
746             0, video_st->codec->height,
747             rgb_picture.data,
748             rgb_picture.linesize
749             );
750
751     *data = frame.data;
752     *step = frame.step;
753     *width = frame.width;
754     *height = frame.height;
755     *cn = frame.cn;
756
757     return true;
758 }
759
760
761 double CvCapture_FFMPEG::getProperty( int property_id )
762 {
763     if( !video_st ) return 0;
764
765     switch( property_id )
766     {
767     case CV_FFMPEG_CAP_PROP_POS_MSEC:
768         return 1000.0*(double)frame_number/get_fps();
769     case CV_FFMPEG_CAP_PROP_POS_FRAMES:
770         return (double)frame_number;
771     case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
772         return r2d(ic->streams[video_stream]->time_base);
773     case CV_FFMPEG_CAP_PROP_FRAME_COUNT:
774         return (double)get_total_frames();
775     case CV_FFMPEG_CAP_PROP_FRAME_WIDTH:
776         return (double)frame.width;
777     case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT:
778         return (double)frame.height;
779     case CV_FFMPEG_CAP_PROP_FPS:
780 #if LIBAVCODEC_BUILD > 4753
781         return av_q2d(video_st->r_frame_rate);
782 #else
783         return (double)video_st->codec.frame_rate
784                 / (double)video_st->codec.frame_rate_base;
785 #endif
786     case CV_FFMPEG_CAP_PROP_FOURCC:
787 #if LIBAVFORMAT_BUILD > 4628
788         return (double)video_st->codec->codec_tag;
789 #else
790         return (double)video_st->codec.codec_tag;
791 #endif
792     default:
793         break;
794     }
795
796     return 0;
797 }
798
799 double CvCapture_FFMPEG::r2d(AVRational r)
800 {
801     return r.num == 0 || r.den == 0 ? 0. : (double)r.num / (double)r.den;
802 }
803
804 double CvCapture_FFMPEG::get_duration_sec()
805 {
806     double sec = (double)ic->duration / (double)AV_TIME_BASE;
807
808     if (sec < eps_zero)
809     {
810         sec = (double)ic->streams[video_stream]->duration * r2d(ic->streams[video_stream]->time_base);
811     }
812
813     if (sec < eps_zero)
814     {
815         sec = (double)ic->streams[video_stream]->duration * r2d(ic->streams[video_stream]->time_base);
816     }
817
818     return sec;
819 }
820
821 int CvCapture_FFMPEG::get_bitrate()
822 {
823     return ic->bit_rate;
824 }
825
826 double CvCapture_FFMPEG::get_fps()
827 {
828     double fps = r2d(ic->streams[video_stream]->r_frame_rate);
829
830 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
831     if (fps < eps_zero)
832     {
833         fps = r2d(ic->streams[video_stream]->avg_frame_rate);
834     }
835 #endif
836
837     if (fps < eps_zero)
838     {
839         fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base);
840     }
841
842     return fps;
843 }
844
845 int64_t CvCapture_FFMPEG::get_total_frames()
846 {
847     int64_t nbf = ic->streams[video_stream]->nb_frames;
848
849     if (nbf == 0)
850     {
851         nbf = (int64_t)floor(get_duration_sec() * get_fps() + 0.5);
852     }
853     return nbf;
854 }
855
856 int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts)
857 {
858     double sec = dts_to_sec(dts);
859     return (int64_t)(get_fps() * sec + 0.5);
860 }
861
862 double CvCapture_FFMPEG::dts_to_sec(int64_t dts)
863 {
864     return (double)(dts - ic->streams[video_stream]->start_time) *
865         r2d(ic->streams[video_stream]->time_base);
866 }
867
868 void CvCapture_FFMPEG::seek(int64_t _frame_number)
869 {
870     _frame_number = std::min(_frame_number, get_total_frames());
871     int delta = 16;
872
873     // if we have not grabbed a single frame before first seek, let's read the first frame
874     // and get some valuable information during the process
875     if( first_frame_number < 0 && get_total_frames() > 1 )
876         grabFrame();
877
878     for(;;)
879     {
880         int64_t _frame_number_temp = std::max(_frame_number-delta, (int64_t)0);
881         double sec = (double)_frame_number_temp / get_fps();
882         int64_t time_stamp = ic->streams[video_stream]->start_time;
883         double  time_base  = r2d(ic->streams[video_stream]->time_base);
884         time_stamp += (int64_t)(sec / time_base + 0.5);
885         if (get_total_frames() > 1) av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_BACKWARD);
886         avcodec_flush_buffers(ic->streams[video_stream]->codec);
887         if( _frame_number > 0 )
888         {
889             grabFrame();
890
891             if( _frame_number > 1 )
892             {
893                 frame_number = dts_to_frame_number(picture_pts) - first_frame_number;
894                 //printf("_frame_number = %d, frame_number = %d, delta = %d\n",
895                 //       (int)_frame_number, (int)frame_number, delta);
896
897                 if( frame_number < 0 || frame_number > _frame_number-1 )
898                 {
899                     if( _frame_number_temp == 0 || delta >= INT_MAX/4 )
900                         break;
901                     delta = delta < 16 ? delta*2 : delta*3/2;
902                     continue;
903                 }
904                 while( frame_number < _frame_number-1 )
905                 {
906                     if(!grabFrame())
907                         break;
908                 }
909                 frame_number++;
910                 break;
911             }
912             else
913             {
914                 frame_number = 1;
915                 break;
916             }
917         }
918         else
919         {
920             frame_number = 0;
921             break;
922         }
923     }
924 }
925
926 void CvCapture_FFMPEG::seek(double sec)
927 {
928     seek((int64_t)(sec * get_fps() + 0.5));
929 }
930
931 bool CvCapture_FFMPEG::setProperty( int property_id, double value )
932 {
933     if( !video_st ) return false;
934
935     switch( property_id )
936     {
937     case CV_FFMPEG_CAP_PROP_POS_MSEC:
938     case CV_FFMPEG_CAP_PROP_POS_FRAMES:
939     case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
940         {
941             switch( property_id )
942             {
943             case CV_FFMPEG_CAP_PROP_POS_FRAMES:
944                 seek((int64_t)value);
945                 break;
946
947             case CV_FFMPEG_CAP_PROP_POS_MSEC:
948                 seek(value/1000.0);
949                 break;
950
951             case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
952                 seek((int64_t)(value*ic->duration));
953                 break;
954             }
955
956             picture_pts=(int64_t)value;
957         }
958         break;
959     default:
960         return false;
961     }
962
963     return true;
964 }
965
966
967 ///////////////// FFMPEG CvVideoWriter implementation //////////////////////////
968 struct CvVideoWriter_FFMPEG
969 {
970     bool open( const char* filename, int fourcc,
971                double fps, int width, int height, bool isColor );
972     void close();
973     bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin );
974
975     void init();
976
977     AVOutputFormat  * fmt;
978     AVFormatContext * oc;
979     uint8_t         * outbuf;
980     uint32_t          outbuf_size;
981     FILE            * outfile;
982     AVFrame         * picture;
983     AVFrame         * input_picture;
984     uint8_t         * picbuf;
985     AVStream        * video_st;
986     int               input_pix_fmt;
987     Image_FFMPEG      temp_image;
988     int               frame_width, frame_height;
989     bool              ok;
990     struct SwsContext *img_convert_ctx;
991 };
992
993 static const char * icvFFMPEGErrStr(int err)
994 {
995 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
996     switch(err) {
997     case AVERROR_BSF_NOT_FOUND:
998         return "Bitstream filter not found";
999     case AVERROR_DECODER_NOT_FOUND:
1000         return "Decoder not found";
1001     case AVERROR_DEMUXER_NOT_FOUND:
1002         return "Demuxer not found";
1003     case AVERROR_ENCODER_NOT_FOUND:
1004         return "Encoder not found";
1005     case AVERROR_EOF:
1006         return "End of file";
1007     case AVERROR_EXIT:
1008         return "Immediate exit was requested; the called function should not be restarted";
1009     case AVERROR_FILTER_NOT_FOUND:
1010         return "Filter not found";
1011     case AVERROR_INVALIDDATA:
1012         return "Invalid data found when processing input";
1013     case AVERROR_MUXER_NOT_FOUND:
1014         return "Muxer not found";
1015     case AVERROR_OPTION_NOT_FOUND:
1016         return "Option not found";
1017     case AVERROR_PATCHWELCOME:
1018         return "Not yet implemented in FFmpeg, patches welcome";
1019     case AVERROR_PROTOCOL_NOT_FOUND:
1020         return "Protocol not found";
1021     case AVERROR_STREAM_NOT_FOUND:
1022         return "Stream not found";
1023     default:
1024         break;
1025     }
1026 #else
1027     switch(err) {
1028     case AVERROR_NUMEXPECTED:
1029         return "Incorrect filename syntax";
1030     case AVERROR_INVALIDDATA:
1031         return "Invalid data in header";
1032     case AVERROR_NOFMT:
1033         return "Unknown format";
1034     case AVERROR_IO:
1035         return "I/O error occurred";
1036     case AVERROR_NOMEM:
1037         return "Memory allocation error";
1038     default:
1039         break;
1040     }
1041 #endif
1042
1043     return "Unspecified error";
1044 }
1045
1046 /* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/
1047 extern "C" {
1048     enum CV_CODEC_ID codec_get_bmp_id(unsigned int tag);
1049 }
1050
1051 void CvVideoWriter_FFMPEG::init()
1052 {
1053     fmt = 0;
1054     oc = 0;
1055     outbuf = 0;
1056     outbuf_size = 0;
1057     outfile = 0;
1058     picture = 0;
1059     input_picture = 0;
1060     picbuf = 0;
1061     video_st = 0;
1062     input_pix_fmt = 0;
1063     memset(&temp_image, 0, sizeof(temp_image));
1064     img_convert_ctx = 0;
1065     frame_width = frame_height = 0;
1066     ok = false;
1067 }
1068
1069 /**
1070  * the following function is a modified version of code
1071  * found in ffmpeg-0.4.9-pre1/output_example.c
1072  */
1073 static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc)
1074 {
1075     AVFrame * picture;
1076     uint8_t * picture_buf;
1077     int size;
1078
1079     picture = avcodec_alloc_frame();
1080     if (!picture)
1081         return NULL;
1082     size = avpicture_get_size( (PixelFormat) pix_fmt, width, height);
1083     if(alloc){
1084         picture_buf = (uint8_t *) malloc(size);
1085         if (!picture_buf)
1086         {
1087             av_free(picture);
1088             return NULL;
1089         }
1090         avpicture_fill((AVPicture *)picture, picture_buf,
1091                        (PixelFormat) pix_fmt, width, height);
1092     }
1093     else {
1094     }
1095     return picture;
1096 }
1097
1098 /* add a video output stream to the container */
1099 static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
1100                                              CV_CODEC_ID codec_id,
1101                                              int w, int h, int bitrate,
1102                                              double fps, int pixel_format)
1103 {
1104     AVCodecContext *c;
1105     AVStream *st;
1106     int frame_rate, frame_rate_base;
1107     AVCodec *codec;
1108
1109 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
1110     st = avformat_new_stream(oc, 0);
1111 #else
1112     st = av_new_stream(oc, 0);
1113 #endif
1114
1115     if (!st) {
1116         CV_WARN("Could not allocate stream");
1117         return NULL;
1118     }
1119
1120 #if LIBAVFORMAT_BUILD > 4628
1121     c = st->codec;
1122 #else
1123     c = &(st->codec);
1124 #endif
1125
1126 #if LIBAVFORMAT_BUILD > 4621
1127     c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
1128 #else
1129     c->codec_id = oc->oformat->video_codec;
1130 #endif
1131
1132     if(codec_id != CV_CODEC(CODEC_ID_NONE)){
1133         c->codec_id = codec_id;
1134     }
1135
1136     //if(codec_tag) c->codec_tag=codec_tag;
1137     codec = avcodec_find_encoder(c->codec_id);
1138
1139     c->codec_type = AVMEDIA_TYPE_VIDEO;
1140
1141 #if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0)
1142     // Set per-codec defaults
1143     AVCodecID c_id = c->codec_id;
1144     avcodec_get_context_defaults3(c, codec);
1145     // avcodec_get_context_defaults3 erases codec_id for some reason
1146     c->codec_id = c_id;
1147 #endif
1148
1149     /* put sample parameters */
1150     int64_t lbit_rate = (int64_t)bitrate;
1151     lbit_rate += (bitrate / 2);
1152     lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX);
1153     c->bit_rate = lbit_rate;
1154
1155     // took advice from
1156     // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html
1157     c->qmin = 3;
1158
1159     /* resolution must be a multiple of two */
1160     c->width = w;
1161     c->height = h;
1162
1163     /* time base: this is the fundamental unit of time (in seconds) in terms
1164        of which frame timestamps are represented. for fixed-fps content,
1165        timebase should be 1/framerate and timestamp increments should be
1166        identically 1. */
1167     frame_rate=(int)(fps+0.5);
1168     frame_rate_base=1;
1169     while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){
1170         frame_rate_base*=10;
1171         frame_rate=(int)(fps*frame_rate_base + 0.5);
1172     }
1173 #if LIBAVFORMAT_BUILD > 4752
1174     c->time_base.den = frame_rate;
1175     c->time_base.num = frame_rate_base;
1176     /* adjust time base for supported framerates */
1177     if(codec && codec->supported_framerates){
1178         const AVRational *p= codec->supported_framerates;
1179         AVRational req = {frame_rate, frame_rate_base};
1180         const AVRational *best=NULL;
1181         AVRational best_error= {INT_MAX, 1};
1182         for(; p->den!=0; p++){
1183             AVRational error= av_sub_q(req, *p);
1184             if(error.num <0) error.num *= -1;
1185             if(av_cmp_q(error, best_error) < 0){
1186                 best_error= error;
1187                 best= p;
1188             }
1189         }
1190         c->time_base.den= best->num;
1191         c->time_base.num= best->den;
1192     }
1193 #else
1194     c->frame_rate = frame_rate;
1195     c->frame_rate_base = frame_rate_base;
1196 #endif
1197
1198     c->gop_size = 12; /* emit one intra frame every twelve frames at most */
1199     c->pix_fmt = (PixelFormat) pixel_format;
1200
1201     if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO)) {
1202         c->max_b_frames = 2;
1203     }
1204     if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3)){
1205         /* needed to avoid using macroblocks in which some coeffs overflow
1206            this doesnt happen with normal video, it just happens here as the
1207            motion of the chroma plane doesnt match the luma plane */
1208         /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */
1209         c->mb_decision=2;
1210     }
1211
1212 #if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0)
1213     /* Some settings for libx264 encoding, restore dummy values for gop_size
1214      and qmin since they will be set to reasonable defaults by the libx264
1215      preset system. Also, use a crf encode with the default quality rating,
1216      this seems easier than finding an appropriate default bitrate. */
1217     if (c->codec_id == CODEC_ID_H264) {
1218       c->gop_size = -1;
1219       c->qmin = -1;
1220       c->bit_rate = 0;
1221       av_opt_set(c->priv_data,"crf","23", 0);
1222     }
1223 #endif
1224
1225 #if LIBAVCODEC_VERSION_INT>0x000409
1226     // some formats want stream headers to be seperate
1227     if(oc->oformat->flags & AVFMT_GLOBALHEADER)
1228     {
1229         c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1230     }
1231 #endif
1232
1233     return st;
1234 }
1235
1236 static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000;
1237
1238 static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture )
1239 {
1240 #if LIBAVFORMAT_BUILD > 4628
1241     AVCodecContext * c = video_st->codec;
1242 #else
1243     AVCodecContext * c = &(video_st->codec);
1244 #endif
1245     int out_size;
1246     int ret = 0;
1247
1248     if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1249         /* raw video case. The API will change slightly in the near
1250            futur for that */
1251         AVPacket pkt;
1252         av_init_packet(&pkt);
1253
1254 #ifndef PKT_FLAG_KEY
1255 #define PKT_FLAG_KEY AV_PKT_FLAG_KEY
1256 #endif
1257
1258         pkt.flags |= PKT_FLAG_KEY;
1259         pkt.stream_index= video_st->index;
1260         pkt.data= (uint8_t *)picture;
1261         pkt.size= sizeof(AVPicture);
1262
1263         ret = av_write_frame(oc, &pkt);
1264     } else {
1265         /* encode the image */
1266         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
1267         /* if zero size, it means the image was buffered */
1268         if (out_size > 0) {
1269             AVPacket pkt;
1270             av_init_packet(&pkt);
1271
1272 #if LIBAVFORMAT_BUILD > 4752
1273             if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE)
1274                 pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
1275 #else
1276             pkt.pts = c->coded_frame->pts;
1277 #endif
1278             if(c->coded_frame->key_frame)
1279                 pkt.flags |= PKT_FLAG_KEY;
1280             pkt.stream_index= video_st->index;
1281             pkt.data= outbuf;
1282             pkt.size= out_size;
1283
1284             /* write the compressed frame in the media file */
1285             ret = av_write_frame(oc, &pkt);
1286         } else {
1287             ret = OPENCV_NO_FRAMES_WRITTEN_CODE;
1288         }
1289     }
1290     return ret;
1291 }
1292
1293 /// write a frame with FFMPEG
1294 bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin )
1295 {
1296     bool ret = false;
1297
1298     if( (width & -2) != frame_width || (height & -2) != frame_height || !data )
1299         return false;
1300     width = frame_width;
1301     height = frame_height;
1302
1303     // typecast from opaque data type to implemented struct
1304 #if LIBAVFORMAT_BUILD > 4628
1305     AVCodecContext *c = video_st->codec;
1306 #else
1307     AVCodecContext *c = &(video_st->codec);
1308 #endif
1309
1310 #if LIBAVFORMAT_BUILD < 5231
1311     // It is not needed in the latest versions of the ffmpeg
1312     if( c->codec_id == CV_CODEC(CODEC_ID_RAWVIDEO) && origin != 1 )
1313     {
1314         if( !temp_image.data )
1315         {
1316             temp_image.step = (width*cn + 3) & -4;
1317             temp_image.width = width;
1318             temp_image.height = height;
1319             temp_image.cn = cn;
1320             temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
1321         }
1322         for( int y = 0; y < height; y++ )
1323             memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn);
1324         data = temp_image.data;
1325         step = temp_image.step;
1326     }
1327 #else
1328     if( width*cn != step )
1329     {
1330         if( !temp_image.data )
1331         {
1332             temp_image.step = width*cn;
1333             temp_image.width = width;
1334             temp_image.height = height;
1335             temp_image.cn = cn;
1336             temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
1337         }
1338         if (origin == 1)
1339             for( int y = 0; y < height; y++ )
1340                 memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step);
1341         else
1342             for( int y = 0; y < height; y++ )
1343                 memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step);
1344         data = temp_image.data;
1345         step = temp_image.step;
1346     }
1347 #endif
1348
1349     // check parameters
1350     if (input_pix_fmt == PIX_FMT_BGR24) {
1351         if (cn != 3) {
1352             return false;
1353         }
1354     }
1355     else if (input_pix_fmt == PIX_FMT_GRAY8) {
1356         if (cn != 1) {
1357             return false;
1358         }
1359     }
1360     else {
1361         assert(false);
1362     }
1363
1364     if ( c->pix_fmt != input_pix_fmt ) {
1365         assert( input_picture );
1366         // let input_picture point to the raw data buffer of 'image'
1367         avpicture_fill((AVPicture *)input_picture, (uint8_t *) data,
1368                        (PixelFormat)input_pix_fmt, width, height);
1369
1370         if( !img_convert_ctx )
1371         {
1372             img_convert_ctx = sws_getContext(width,
1373                                              height,
1374                                              (PixelFormat)input_pix_fmt,
1375                                              c->width,
1376                                              c->height,
1377                                              c->pix_fmt,
1378                                              SWS_BICUBIC,
1379                                              NULL, NULL, NULL);
1380             if( !img_convert_ctx )
1381                 return false;
1382         }
1383
1384         if ( sws_scale(img_convert_ctx, input_picture->data,
1385                        input_picture->linesize, 0,
1386                        height,
1387                        picture->data, picture->linesize) < 0 )
1388             return false;
1389     }
1390     else{
1391         avpicture_fill((AVPicture *)picture, (uint8_t *) data,
1392                        (PixelFormat)input_pix_fmt, width, height);
1393     }
1394
1395     ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0;
1396
1397     return ret;
1398 }
1399
1400 /// close video output stream and free associated memory
1401 void CvVideoWriter_FFMPEG::close()
1402 {
1403     // nothing to do if already released
1404     if ( !picture )
1405         return;
1406
1407     /* no more frame to compress. The codec has a latency of a few
1408        frames if using B frames, so we get the last frames by
1409        passing the same picture again */
1410     // TODO -- do we need to account for latency here?
1411
1412     /* write the trailer, if any */
1413     if(ok && oc)
1414     {
1415         if( (oc->oformat->flags & AVFMT_RAWPICTURE) == 0 )
1416         {
1417             for(;;)
1418             {
1419                 int ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, NULL);
1420                 if( ret == OPENCV_NO_FRAMES_WRITTEN_CODE || ret < 0 )
1421                     break;
1422             }
1423         }
1424         av_write_trailer(oc);
1425     }
1426
1427     if( img_convert_ctx )
1428     {
1429         sws_freeContext(img_convert_ctx);
1430         img_convert_ctx = 0;
1431     }
1432
1433     // free pictures
1434 #if LIBAVFORMAT_BUILD > 4628
1435     if( video_st->codec->pix_fmt != input_pix_fmt)
1436 #else
1437     if( video_st->codec.pix_fmt != input_pix_fmt)
1438 #endif
1439     {
1440         if(picture->data[0])
1441             free(picture->data[0]);
1442         picture->data[0] = 0;
1443     }
1444     av_free(picture);
1445
1446     if (input_picture)
1447         av_free(input_picture);
1448
1449     /* close codec */
1450 #if LIBAVFORMAT_BUILD > 4628
1451     avcodec_close(video_st->codec);
1452 #else
1453     avcodec_close(&(video_st->codec));
1454 #endif
1455
1456     av_free(outbuf);
1457
1458     if (!(fmt->flags & AVFMT_NOFILE))
1459     {
1460         /* close the output file */
1461
1462 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
1463 #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1464         url_fclose(oc->pb);
1465 #else
1466         url_fclose(&oc->pb);
1467 #endif
1468 #else
1469         avio_close(oc->pb);
1470 #endif
1471
1472     }
1473
1474     /* free the stream */
1475     avformat_free_context(oc);
1476
1477     if( temp_image.data )
1478     {
1479         free(temp_image.data);
1480         temp_image.data = 0;
1481     }
1482
1483     init();
1484 }
1485
1486 /// Create a video writer object that uses FFMPEG
1487 bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
1488                                  double fps, int width, int height, bool is_color )
1489 {
1490     CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_NONE);
1491     int err, codec_pix_fmt;
1492     double bitrate_scale = 1;
1493
1494     close();
1495
1496     // check arguments
1497     if( !filename )
1498         return false;
1499     if(fps <= 0)
1500         return false;
1501
1502     // we allow frames of odd width or height, but in this case we truncate
1503     // the rightmost column/the bottom row. Probably, this should be handled more elegantly,
1504     // but some internal functions inside FFMPEG swscale require even width/height.
1505     width &= -2;
1506     height &= -2;
1507     if( width <= 0 || height <= 0 )
1508         return false;
1509
1510     /* auto detect the output format from the name and fourcc code. */
1511
1512 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1513     fmt = av_guess_format(NULL, filename, NULL);
1514 #else
1515     fmt = guess_format(NULL, filename, NULL);
1516 #endif
1517
1518     if (!fmt)
1519         return false;
1520
1521     /* determine optimal pixel format */
1522     if (is_color) {
1523         input_pix_fmt = PIX_FMT_BGR24;
1524     }
1525     else {
1526         input_pix_fmt = PIX_FMT_GRAY8;
1527     }
1528
1529     /* Lookup codec_id for given fourcc */
1530 #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
1531     if( (codec_id = codec_get_bmp_id( fourcc )) == CV_CODEC(CODEC_ID_NONE) )
1532         return false;
1533 #else
1534     const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
1535     if( (codec_id = av_codec_get_id(tags, fourcc)) == CV_CODEC(CODEC_ID_NONE) )
1536         return false;
1537 #endif
1538
1539     // alloc memory for context
1540 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1541     oc = avformat_alloc_context();
1542 #else
1543     oc = av_alloc_format_context();
1544 #endif
1545     assert (oc);
1546
1547     /* set file name */
1548     oc->oformat = fmt;
1549     snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
1550
1551     /* set some options */
1552     oc->max_delay = (int)(0.7*AV_TIME_BASE);  /* This reduces buffer underrun warnings with MPEG */
1553
1554     // set a few optimal pixel formats for lossless codecs of interest..
1555     switch (codec_id) {
1556 #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
1557     case CV_CODEC(CODEC_ID_JPEGLS):
1558         // BGR24 or GRAY8 depending on is_color...
1559         codec_pix_fmt = input_pix_fmt;
1560         break;
1561 #endif
1562     case CV_CODEC(CODEC_ID_HUFFYUV):
1563         codec_pix_fmt = PIX_FMT_YUV422P;
1564         break;
1565     case CV_CODEC(CODEC_ID_MJPEG):
1566     case CV_CODEC(CODEC_ID_LJPEG):
1567         codec_pix_fmt = PIX_FMT_YUVJ420P;
1568         bitrate_scale = 3;
1569         break;
1570     case CV_CODEC(CODEC_ID_RAWVIDEO):
1571         codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 ||
1572                         input_pix_fmt == PIX_FMT_GRAY16LE ||
1573                         input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P;
1574         break;
1575     default:
1576         // good for lossy formats, MPEG, etc.
1577         codec_pix_fmt = PIX_FMT_YUV420P;
1578         break;
1579     }
1580
1581     double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2);
1582
1583     // TODO -- safe to ignore output audio stream?
1584     video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
1585                                            width, height, (int)(bitrate + 0.5),
1586                                            fps, codec_pix_fmt);
1587
1588     /* set the output parameters (must be done even if no
1589    parameters). */
1590 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1591     if (av_set_parameters(oc, NULL) < 0) {
1592         return false;
1593     }
1594 #endif
1595
1596 #if 0
1597 #if FF_API_DUMP_FORMAT
1598     dump_format(oc, 0, filename, 1);
1599 #else
1600     av_dump_format(oc, 0, filename, 1);
1601 #endif
1602 #endif
1603
1604     /* now that all the parameters are set, we can open the audio and
1605      video codecs and allocate the necessary encode buffers */
1606     if (!video_st){
1607         return false;
1608     }
1609
1610     AVCodec *codec;
1611     AVCodecContext *c;
1612
1613 #if LIBAVFORMAT_BUILD > 4628
1614     c = (video_st->codec);
1615 #else
1616     c = &(video_st->codec);
1617 #endif
1618
1619     c->codec_tag = fourcc;
1620     /* find the video encoder */
1621     codec = avcodec_find_encoder(c->codec_id);
1622     if (!codec) {
1623         fprintf(stderr, "Could not find encoder for codec id %d: %s", c->codec_id, icvFFMPEGErrStr(
1624         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1625                 AVERROR_ENCODER_NOT_FOUND
1626         #else
1627                 -1
1628         #endif
1629                 ));
1630         return false;
1631     }
1632
1633     int64_t lbit_rate = (int64_t)c->bit_rate;
1634     lbit_rate += (bitrate / 2);
1635     lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX);
1636     c->bit_rate_tolerance = (int)lbit_rate;
1637     c->bit_rate = (int)lbit_rate;
1638
1639     /* open the codec */
1640     if ((err=
1641 #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
1642          avcodec_open2(c, codec, NULL)
1643 #else
1644          avcodec_open(c, codec)
1645 #endif
1646          ) < 0) {
1647         fprintf(stderr, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err));
1648         return false;
1649     }
1650
1651     outbuf = NULL;
1652
1653     if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
1654         /* allocate output buffer */
1655         /* assume we will never get codec output with more than 4 bytes per pixel... */
1656         outbuf_size = width*height*4;
1657         outbuf = (uint8_t *) av_malloc(outbuf_size);
1658     }
1659
1660     bool need_color_convert;
1661     need_color_convert = (c->pix_fmt != input_pix_fmt);
1662
1663     /* allocate the encoded raw picture */
1664     picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert);
1665     if (!picture) {
1666         return false;
1667     }
1668
1669     /* if the output format is not our input format, then a temporary
1670    picture of the input format is needed too. It is then converted
1671    to the required output format */
1672     input_picture = NULL;
1673     if ( need_color_convert ) {
1674         input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false);
1675         if (!input_picture) {
1676             return false;
1677         }
1678     }
1679
1680     /* open the output file, if needed */
1681     if (!(fmt->flags & AVFMT_NOFILE)) {
1682 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1683         if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
1684 #else
1685             if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0)
1686 #endif
1687             {
1688             return false;
1689         }
1690     }
1691
1692 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
1693     /* write the stream header, if any */
1694     err=avformat_write_header(oc, NULL);
1695 #else
1696     err=av_write_header( oc );
1697 #endif
1698
1699     if(err < 0)
1700     {
1701         close();
1702         remove(filename);
1703         return false;
1704     }
1705     frame_width = width;
1706     frame_height = height;
1707     ok = true;
1708
1709     return true;
1710 }
1711
1712
1713
1714 CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
1715 {
1716     CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture));
1717     capture->init();
1718     if( capture->open( filename ))
1719         return capture;
1720
1721     capture->close();
1722     free(capture);
1723     return 0;
1724 }
1725
1726
1727 void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture)
1728 {
1729     if( capture && *capture )
1730     {
1731         (*capture)->close();
1732         free(*capture);
1733         *capture = 0;
1734     }
1735 }
1736
1737 int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value)
1738 {
1739     return capture->setProperty(prop_id, value);
1740 }
1741
1742 double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id)
1743 {
1744     return capture->getProperty(prop_id);
1745 }
1746
1747 int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture)
1748 {
1749     return capture->grabFrame();
1750 }
1751
1752 int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn)
1753 {
1754     return capture->retrieveFrame(0, data, step, width, height, cn);
1755 }
1756
1757 CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
1758                                                   int width, int height, int isColor )
1759 {
1760     CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer));
1761     writer->init();
1762     if( writer->open( filename, fourcc, fps, width, height, isColor != 0 ))
1763         return writer;
1764     writer->close();
1765     free(writer);
1766     return 0;
1767 }
1768
1769 void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
1770 {
1771     if( writer && *writer )
1772     {
1773         (*writer)->close();
1774         free(*writer);
1775         *writer = 0;
1776     }
1777 }
1778
1779
1780 int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer,
1781                          const unsigned char* data, int step,
1782                          int width, int height, int cn, int origin)
1783 {
1784     return writer->writeFrame(data, step, width, height, cn, origin);
1785 }
1786
1787
1788
1789 /*
1790  * For CUDA encoder
1791  */
1792
1793 struct OutputMediaStream_FFMPEG
1794 {
1795     bool open(const char* fileName, int width, int height, double fps);
1796     void close();
1797
1798     void write(unsigned char* data, int size, int keyFrame);
1799
1800     // add a video output stream to the container
1801     static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format);
1802
1803     AVOutputFormat* fmt_;
1804     AVFormatContext* oc_;
1805     AVStream* video_st_;
1806 };
1807
1808 void OutputMediaStream_FFMPEG::close()
1809 {
1810     // no more frame to compress. The codec has a latency of a few
1811     // frames if using B frames, so we get the last frames by
1812     // passing the same picture again
1813
1814     // TODO -- do we need to account for latency here?
1815
1816     if (oc_)
1817     {
1818         // write the trailer, if any
1819         av_write_trailer(oc_);
1820
1821         // free the streams
1822         for (unsigned int i = 0; i < oc_->nb_streams; ++i)
1823         {
1824             av_freep(&oc_->streams[i]->codec);
1825             av_freep(&oc_->streams[i]);
1826         }
1827
1828         if (!(fmt_->flags & AVFMT_NOFILE) && oc_->pb)
1829         {
1830             // close the output file
1831
1832             #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
1833                 #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1834                     url_fclose(oc_->pb);
1835                 #else
1836                     url_fclose(&oc_->pb);
1837                 #endif
1838             #else
1839                 avio_close(oc_->pb);
1840             #endif
1841         }
1842
1843         // free the stream
1844         av_free(oc_);
1845     }
1846 }
1847
1848 AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format)
1849 {
1850     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
1851         AVStream* st = avformat_new_stream(oc, 0);
1852     #else
1853         AVStream* st = av_new_stream(oc, 0);
1854     #endif
1855     if (!st)
1856         return 0;
1857
1858     #if LIBAVFORMAT_BUILD > 4628
1859         AVCodecContext* c = st->codec;
1860     #else
1861         AVCodecContext* c = &(st->codec);
1862     #endif
1863
1864     c->codec_id = codec_id;
1865     c->codec_type = AVMEDIA_TYPE_VIDEO;
1866
1867     // put sample parameters
1868     unsigned long long lbit_rate = static_cast<unsigned long long>(bitrate);
1869     lbit_rate += (bitrate / 4);
1870     lbit_rate = std::min(lbit_rate, static_cast<unsigned long long>(std::numeric_limits<int>::max()));
1871     c->bit_rate = bitrate;
1872
1873     // took advice from
1874     // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html
1875     c->qmin = 3;
1876
1877     // resolution must be a multiple of two
1878     c->width = w;
1879     c->height = h;
1880
1881     AVCodec* codec = avcodec_find_encoder(c->codec_id);
1882
1883     // time base: this is the fundamental unit of time (in seconds) in terms
1884     // of which frame timestamps are represented. for fixed-fps content,
1885     // timebase should be 1/framerate and timestamp increments should be
1886     // identically 1
1887
1888     int frame_rate = static_cast<int>(fps+0.5);
1889     int frame_rate_base = 1;
1890     while (fabs(static_cast<double>(frame_rate)/frame_rate_base) - fps > 0.001)
1891     {
1892         frame_rate_base *= 10;
1893         frame_rate = static_cast<int>(fps*frame_rate_base + 0.5);
1894     }
1895     c->time_base.den = frame_rate;
1896     c->time_base.num = frame_rate_base;
1897
1898     #if LIBAVFORMAT_BUILD > 4752
1899         // adjust time base for supported framerates
1900         if (codec && codec->supported_framerates)
1901         {
1902             AVRational req = {frame_rate, frame_rate_base};
1903             const AVRational* best = NULL;
1904             AVRational best_error = {INT_MAX, 1};
1905
1906             for (const AVRational* p = codec->supported_framerates; p->den!=0; ++p)
1907             {
1908                 AVRational error = av_sub_q(req, *p);
1909
1910                 if (error.num < 0)
1911                     error.num *= -1;
1912
1913                 if (av_cmp_q(error, best_error) < 0)
1914                 {
1915                     best_error= error;
1916                     best= p;
1917                 }
1918             }
1919
1920             c->time_base.den= best->num;
1921             c->time_base.num= best->den;
1922         }
1923     #endif
1924
1925     c->gop_size = 12; // emit one intra frame every twelve frames at most
1926     c->pix_fmt = pixel_format;
1927
1928     if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO))
1929         c->max_b_frames = 2;
1930
1931     if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3))
1932     {
1933         // needed to avoid using macroblocks in which some coeffs overflow
1934         // this doesnt happen with normal video, it just happens here as the
1935         // motion of the chroma plane doesnt match the luma plane
1936
1937         // avoid FFMPEG warning 'clipping 1 dct coefficients...'
1938
1939         c->mb_decision = 2;
1940     }
1941
1942     #if LIBAVCODEC_VERSION_INT > 0x000409
1943         // some formats want stream headers to be seperate
1944         if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1945         {
1946             c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1947         }
1948     #endif
1949
1950     return st;
1951 }
1952
1953 bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, double fps)
1954 {
1955     fmt_ = 0;
1956     oc_ = 0;
1957     video_st_ = 0;
1958
1959     // auto detect the output format from the name and fourcc code
1960     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1961         fmt_ = av_guess_format(NULL, fileName, NULL);
1962     #else
1963         fmt_ = guess_format(NULL, fileName, NULL);
1964     #endif
1965     if (!fmt_)
1966         return false;
1967
1968     CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_H264);
1969
1970     // alloc memory for context
1971     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1972         oc_ = avformat_alloc_context();
1973     #else
1974         oc_ = av_alloc_format_context();
1975     #endif
1976     if (!oc_)
1977         return false;
1978
1979     // set some options
1980     oc_->oformat = fmt_;
1981     snprintf(oc_->filename, sizeof(oc_->filename), "%s", fileName);
1982
1983     oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG
1984
1985     // set a few optimal pixel formats for lossless codecs of interest..
1986     PixelFormat codec_pix_fmt = PIX_FMT_YUV420P;
1987     int bitrate_scale = 64;
1988
1989     // TODO -- safe to ignore output audio stream?
1990     video_st_ = addVideoStream(oc_, codec_id, width, height, width * height * bitrate_scale, fps, codec_pix_fmt);
1991     if (!video_st_)
1992         return false;
1993
1994     // set the output parameters (must be done even if no parameters)
1995     #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1996         if (av_set_parameters(oc_, NULL) < 0)
1997             return false;
1998     #endif
1999
2000     // now that all the parameters are set, we can open the audio and
2001     // video codecs and allocate the necessary encode buffers
2002
2003     #if LIBAVFORMAT_BUILD > 4628
2004         AVCodecContext* c = (video_st_->codec);
2005     #else
2006         AVCodecContext* c = &(video_st_->codec);
2007     #endif
2008
2009     c->codec_tag = MKTAG('H', '2', '6', '4');
2010     c->bit_rate_tolerance = c->bit_rate;
2011
2012     // open the output file, if needed
2013     if (!(fmt_->flags & AVFMT_NOFILE))
2014     {
2015         #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2016             int err = url_fopen(&oc_->pb, fileName, URL_WRONLY);
2017         #else
2018             int err = avio_open(&oc_->pb, fileName, AVIO_FLAG_WRITE);
2019         #endif
2020
2021         if (err != 0)
2022             return false;
2023     }
2024
2025     // write the stream header, if any
2026     #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2027         av_write_header(oc_);
2028     #else
2029         avformat_write_header(oc_, NULL);
2030     #endif
2031
2032     return true;
2033 }
2034
2035 void OutputMediaStream_FFMPEG::write(unsigned char* data, int size, int keyFrame)
2036 {
2037     // if zero size, it means the image was buffered
2038     if (size > 0)
2039     {
2040         AVPacket pkt;
2041         av_init_packet(&pkt);
2042
2043         if (keyFrame)
2044             pkt.flags |= PKT_FLAG_KEY;
2045
2046         pkt.stream_index = video_st_->index;
2047         pkt.data = data;
2048         pkt.size = size;
2049
2050         // write the compressed frame in the media file
2051         av_write_frame(oc_, &pkt);
2052     }
2053 }
2054
2055 struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps)
2056 {
2057     OutputMediaStream_FFMPEG* stream = (OutputMediaStream_FFMPEG*) malloc(sizeof(OutputMediaStream_FFMPEG));
2058
2059     if (stream->open(fileName, width, height, fps))
2060         return stream;
2061
2062     stream->close();
2063     free(stream);
2064
2065     return 0;
2066 }
2067
2068 void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream)
2069 {
2070     stream->close();
2071     free(stream);
2072 }
2073
2074 void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame)
2075 {
2076     stream->write(data, size, keyFrame);
2077 }
2078
2079 /*
2080  * For CUDA decoder
2081  */
2082
2083 enum
2084 {
2085     VideoCodec_MPEG1 = 0,
2086     VideoCodec_MPEG2,
2087     VideoCodec_MPEG4,
2088     VideoCodec_VC1,
2089     VideoCodec_H264,
2090     VideoCodec_JPEG,
2091     VideoCodec_H264_SVC,
2092     VideoCodec_H264_MVC,
2093
2094     // Uncompressed YUV
2095     VideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')),   // Y,U,V (4:2:0)
2096     VideoCodec_YV12   = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')),   // Y,V,U (4:2:0)
2097     VideoCodec_NV12   = (('N'<<24)|('V'<<16)|('1'<<8)|('2')),   // Y,UV  (4:2:0)
2098     VideoCodec_YUYV   = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')),   // YUYV/YUY2 (4:2:2)
2099     VideoCodec_UYVY   = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')),   // UYVY (4:2:2)
2100 };
2101
2102 enum
2103 {
2104     VideoChromaFormat_Monochrome = 0,
2105     VideoChromaFormat_YUV420,
2106     VideoChromaFormat_YUV422,
2107     VideoChromaFormat_YUV444,
2108 };
2109
2110 struct InputMediaStream_FFMPEG
2111 {
2112 public:
2113     bool open(const char* fileName, int* codec, int* chroma_format, int* width, int* height);
2114     void close();
2115
2116     bool read(unsigned char** data, int* size, int* endOfFile);
2117
2118 private:
2119     InputMediaStream_FFMPEG(const InputMediaStream_FFMPEG&);
2120     InputMediaStream_FFMPEG& operator =(const InputMediaStream_FFMPEG&);
2121
2122     AVFormatContext* ctx_;
2123     int video_stream_id_;
2124     AVPacket pkt_;
2125 };
2126
2127 bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
2128 {
2129     int err;
2130
2131     ctx_ = 0;
2132     video_stream_id_ = -1;
2133     memset(&pkt_, 0, sizeof(AVPacket));
2134
2135     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
2136         avformat_network_init();
2137     #endif
2138
2139     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
2140         err = avformat_open_input(&ctx_, fileName, 0, 0);
2141     #else
2142         err = av_open_input_file(&ctx_, fileName, 0, 0, 0);
2143     #endif
2144     if (err < 0)
2145         return false;
2146
2147     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
2148         err = avformat_find_stream_info(ctx_, 0);
2149     #else
2150         err = av_find_stream_info(ctx_);
2151     #endif
2152     if (err < 0)
2153         return false;
2154
2155     for (unsigned int i = 0; i < ctx_->nb_streams; ++i)
2156     {
2157         #if LIBAVFORMAT_BUILD > 4628
2158             AVCodecContext *enc = ctx_->streams[i]->codec;
2159         #else
2160             AVCodecContext *enc = &ctx_->streams[i]->codec;
2161         #endif
2162
2163         if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
2164         {
2165             video_stream_id_ = static_cast<int>(i);
2166
2167             switch (enc->codec_id)
2168             {
2169             case CV_CODEC(CODEC_ID_MPEG1VIDEO):
2170                 *codec = ::VideoCodec_MPEG1;
2171                 break;
2172
2173             case CV_CODEC(CODEC_ID_MPEG2VIDEO):
2174                 *codec = ::VideoCodec_MPEG2;
2175                 break;
2176
2177             case CV_CODEC(CODEC_ID_MPEG4):
2178                 *codec = ::VideoCodec_MPEG4;
2179                 break;
2180
2181             case CV_CODEC(CODEC_ID_VC1):
2182                 *codec = ::VideoCodec_VC1;
2183                 break;
2184
2185             case CV_CODEC(CODEC_ID_H264):
2186                 *codec = ::VideoCodec_H264;
2187                 break;
2188
2189             default:
2190                 return false;
2191             };
2192
2193             switch (enc->pix_fmt)
2194             {
2195             case PIX_FMT_YUV420P:
2196                 *chroma_format = ::VideoChromaFormat_YUV420;
2197                 break;
2198
2199             case PIX_FMT_YUV422P:
2200                 *chroma_format = ::VideoChromaFormat_YUV422;
2201                 break;
2202
2203             case PIX_FMT_YUV444P:
2204                 *chroma_format = ::VideoChromaFormat_YUV444;
2205                 break;
2206
2207             default:
2208                 return false;
2209             }
2210
2211             *width = enc->coded_width;
2212             *height = enc->coded_height;
2213
2214             break;
2215         }
2216     }
2217
2218     if (video_stream_id_ < 0)
2219         return false;
2220
2221     av_init_packet(&pkt_);
2222
2223     return true;
2224 }
2225
2226 void InputMediaStream_FFMPEG::close()
2227 {
2228     if (ctx_)
2229     {
2230         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 24, 2)
2231             avformat_close_input(&ctx_);
2232         #else
2233             av_close_input_file(ctx_);
2234         #endif
2235     }
2236
2237     // free last packet if exist
2238     if (pkt_.data)
2239         av_free_packet(&pkt_);
2240 }
2241
2242 bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFile)
2243 {
2244     // free last packet if exist
2245     if (pkt_.data)
2246         av_free_packet(&pkt_);
2247
2248     // get the next frame
2249     for (;;)
2250     {
2251         int ret = av_read_frame(ctx_, &pkt_);
2252
2253         if (ret == AVERROR(EAGAIN))
2254             continue;
2255
2256         if (ret < 0)
2257         {
2258             if (ret == (int)AVERROR_EOF)
2259                 *endOfFile = true;
2260             return false;
2261         }
2262
2263         if (pkt_.stream_index != video_stream_id_)
2264         {
2265             av_free_packet(&pkt_);
2266             continue;
2267         }
2268
2269         break;
2270     }
2271
2272     *data = pkt_.data;
2273     *size = pkt_.size;
2274     *endOfFile = false;
2275
2276     return true;
2277 }
2278
2279 InputMediaStream_FFMPEG* create_InputMediaStream_FFMPEG(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
2280 {
2281     InputMediaStream_FFMPEG* stream = (InputMediaStream_FFMPEG*) malloc(sizeof(InputMediaStream_FFMPEG));
2282
2283     if (stream && stream->open(fileName, codec, chroma_format, width, height))
2284         return stream;
2285
2286     stream->close();
2287     free(stream);
2288
2289     return 0;
2290 }
2291
2292 void release_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream)
2293 {
2294     stream->close();
2295     free(stream);
2296 }
2297
2298 int read_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile)
2299 {
2300     return stream->read(data, size, endOfFile);
2301 }