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