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