CLAHE Python bindings
[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     unsigned i;
1366
1367     // nothing to do if already released
1368     if ( !picture )
1369         return;
1370
1371     /* no more frame to compress. The codec has a latency of a few
1372        frames if using B frames, so we get the last frames by
1373        passing the same picture again */
1374     // TODO -- do we need to account for latency here?
1375
1376     /* write the trailer, if any */
1377     if(ok && oc)
1378     {
1379         if( (oc->oformat->flags & AVFMT_RAWPICTURE) == 0 )
1380         {
1381             for(;;)
1382             {
1383                 int ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, NULL);
1384                 if( ret == OPENCV_NO_FRAMES_WRITTEN_CODE || ret < 0 )
1385                     break;
1386             }
1387         }
1388         av_write_trailer(oc);
1389     }
1390
1391     if( img_convert_ctx )
1392     {
1393         sws_freeContext(img_convert_ctx);
1394         img_convert_ctx = 0;
1395     }
1396
1397     // free pictures
1398 #if LIBAVFORMAT_BUILD > 4628
1399     if( video_st->codec->pix_fmt != input_pix_fmt)
1400 #else
1401     if( video_st->codec.pix_fmt != input_pix_fmt)
1402 #endif
1403     {
1404         if(picture->data[0])
1405             free(picture->data[0]);
1406         picture->data[0] = 0;
1407     }
1408     av_free(picture);
1409
1410     if (input_picture)
1411         av_free(input_picture);
1412
1413     /* close codec */
1414 #if LIBAVFORMAT_BUILD > 4628
1415     avcodec_close(video_st->codec);
1416 #else
1417     avcodec_close(&(video_st->codec));
1418 #endif
1419
1420     av_free(outbuf);
1421
1422     /* free the streams */
1423     for(i = 0; i < oc->nb_streams; i++)
1424     {
1425         av_freep(&oc->streams[i]->codec);
1426         av_freep(&oc->streams[i]);
1427     }
1428
1429     if (!(fmt->flags & AVFMT_NOFILE))
1430     {
1431         /* close the output file */
1432
1433 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
1434 #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1435         url_fclose(oc->pb);
1436 #else
1437         url_fclose(&oc->pb);
1438 #endif
1439 #else
1440         avio_close(oc->pb);
1441 #endif
1442
1443     }
1444
1445     /* free the stream */
1446     av_free(oc);
1447
1448     if( temp_image.data )
1449     {
1450         free(temp_image.data);
1451         temp_image.data = 0;
1452     }
1453
1454     init();
1455 }
1456
1457 /// Create a video writer object that uses FFMPEG
1458 bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
1459                                  double fps, int width, int height, bool is_color )
1460 {
1461     CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_NONE);
1462     int err, codec_pix_fmt;
1463     double bitrate_scale = 1;
1464
1465     close();
1466
1467     // check arguments
1468     if( !filename )
1469         return false;
1470     if(fps <= 0)
1471         return false;
1472
1473     // we allow frames of odd width or height, but in this case we truncate
1474     // the rightmost column/the bottom row. Probably, this should be handled more elegantly,
1475     // but some internal functions inside FFMPEG swscale require even width/height.
1476     width &= -2;
1477     height &= -2;
1478     if( width <= 0 || height <= 0 )
1479         return false;
1480
1481     /* auto detect the output format from the name and fourcc code. */
1482
1483 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1484     fmt = av_guess_format(NULL, filename, NULL);
1485 #else
1486     fmt = guess_format(NULL, filename, NULL);
1487 #endif
1488
1489     if (!fmt)
1490         return false;
1491
1492     /* determine optimal pixel format */
1493     if (is_color) {
1494         input_pix_fmt = PIX_FMT_BGR24;
1495     }
1496     else {
1497         input_pix_fmt = PIX_FMT_GRAY8;
1498     }
1499
1500     /* Lookup codec_id for given fourcc */
1501 #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
1502     if( (codec_id = codec_get_bmp_id( fourcc )) == CV_CODEC(CODEC_ID_NONE) )
1503         return false;
1504 #else
1505     const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
1506     if( (codec_id = av_codec_get_id(tags, fourcc)) == CV_CODEC(CODEC_ID_NONE) )
1507         return false;
1508 #endif
1509
1510     // alloc memory for context
1511 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1512     oc = avformat_alloc_context();
1513 #else
1514     oc = av_alloc_format_context();
1515 #endif
1516     assert (oc);
1517
1518     /* set file name */
1519     oc->oformat = fmt;
1520     snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
1521
1522     /* set some options */
1523     oc->max_delay = (int)(0.7*AV_TIME_BASE);  /* This reduces buffer underrun warnings with MPEG */
1524
1525     // set a few optimal pixel formats for lossless codecs of interest..
1526     switch (codec_id) {
1527 #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
1528     case CV_CODEC(CODEC_ID_JPEGLS):
1529         // BGR24 or GRAY8 depending on is_color...
1530         codec_pix_fmt = input_pix_fmt;
1531         break;
1532 #endif
1533     case CV_CODEC(CODEC_ID_HUFFYUV):
1534         codec_pix_fmt = PIX_FMT_YUV422P;
1535         break;
1536     case CV_CODEC(CODEC_ID_MJPEG):
1537     case CV_CODEC(CODEC_ID_LJPEG):
1538         codec_pix_fmt = PIX_FMT_YUVJ420P;
1539         bitrate_scale = 3;
1540         break;
1541     case CV_CODEC(CODEC_ID_RAWVIDEO):
1542         codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 ||
1543                         input_pix_fmt == PIX_FMT_GRAY16LE ||
1544                         input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P;
1545         break;
1546     default:
1547         // good for lossy formats, MPEG, etc.
1548         codec_pix_fmt = PIX_FMT_YUV420P;
1549         break;
1550     }
1551
1552     double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2);
1553
1554     // TODO -- safe to ignore output audio stream?
1555     video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
1556                                            width, height, (int)(bitrate + 0.5),
1557                                            fps, codec_pix_fmt);
1558
1559     /* set the output parameters (must be done even if no
1560    parameters). */
1561 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1562     if (av_set_parameters(oc, NULL) < 0) {
1563         return false;
1564     }
1565 #endif
1566
1567 #if 0
1568 #if FF_API_DUMP_FORMAT
1569     dump_format(oc, 0, filename, 1);
1570 #else
1571     av_dump_format(oc, 0, filename, 1);
1572 #endif
1573 #endif
1574
1575     /* now that all the parameters are set, we can open the audio and
1576      video codecs and allocate the necessary encode buffers */
1577     if (!video_st){
1578         return false;
1579     }
1580
1581     AVCodec *codec;
1582     AVCodecContext *c;
1583
1584 #if LIBAVFORMAT_BUILD > 4628
1585     c = (video_st->codec);
1586 #else
1587     c = &(video_st->codec);
1588 #endif
1589
1590     c->codec_tag = fourcc;
1591     /* find the video encoder */
1592     codec = avcodec_find_encoder(c->codec_id);
1593     if (!codec) {
1594         fprintf(stderr, "Could not find encoder for codec id %d: %s", c->codec_id, icvFFMPEGErrStr(
1595         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1596                 AVERROR_ENCODER_NOT_FOUND
1597         #else
1598                 -1
1599         #endif
1600                 ));
1601         return false;
1602     }
1603
1604     int64_t lbit_rate = (int64_t)c->bit_rate;
1605     lbit_rate += (bitrate / 2);
1606     lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX);
1607     c->bit_rate_tolerance = (int)lbit_rate;
1608     c->bit_rate = (int)lbit_rate;
1609
1610     /* open the codec */
1611     if ((err=
1612 #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
1613          avcodec_open2(c, codec, NULL)
1614 #else
1615          avcodec_open(c, codec)
1616 #endif
1617          ) < 0) {
1618         fprintf(stderr, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err));
1619         return false;
1620     }
1621
1622     outbuf = NULL;
1623
1624     if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
1625         /* allocate output buffer */
1626         /* assume we will never get codec output with more than 4 bytes per pixel... */
1627         outbuf_size = width*height*4;
1628         outbuf = (uint8_t *) av_malloc(outbuf_size);
1629     }
1630
1631     bool need_color_convert;
1632     need_color_convert = (c->pix_fmt != input_pix_fmt);
1633
1634     /* allocate the encoded raw picture */
1635     picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert);
1636     if (!picture) {
1637         return false;
1638     }
1639
1640     /* if the output format is not our input format, then a temporary
1641    picture of the input format is needed too. It is then converted
1642    to the required output format */
1643     input_picture = NULL;
1644     if ( need_color_convert ) {
1645         input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false);
1646         if (!input_picture) {
1647             return false;
1648         }
1649     }
1650
1651     /* open the output file, if needed */
1652     if (!(fmt->flags & AVFMT_NOFILE)) {
1653 #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1654         if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
1655 #else
1656             if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0)
1657 #endif
1658             {
1659             return false;
1660         }
1661     }
1662
1663 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
1664     /* write the stream header, if any */
1665     err=avformat_write_header(oc, NULL);
1666 #else
1667     err=av_write_header( oc );
1668 #endif
1669
1670     if(err < 0)
1671     {
1672         close();
1673         remove(filename);
1674         return false;
1675     }
1676     frame_width = width;
1677     frame_height = height;
1678     ok = true;
1679
1680     return true;
1681 }
1682
1683
1684
1685 CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
1686 {
1687     CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture));
1688     capture->init();
1689     if( capture->open( filename ))
1690         return capture;
1691
1692     capture->close();
1693     free(capture);
1694     return 0;
1695 }
1696
1697
1698 void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture)
1699 {
1700     if( capture && *capture )
1701     {
1702         (*capture)->close();
1703         free(*capture);
1704         *capture = 0;
1705     }
1706 }
1707
1708 int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value)
1709 {
1710     return capture->setProperty(prop_id, value);
1711 }
1712
1713 double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id)
1714 {
1715     return capture->getProperty(prop_id);
1716 }
1717
1718 int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture)
1719 {
1720     return capture->grabFrame();
1721 }
1722
1723 int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn)
1724 {
1725     return capture->retrieveFrame(0, data, step, width, height, cn);
1726 }
1727
1728 CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
1729                                                   int width, int height, int isColor )
1730 {
1731     CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer));
1732     writer->init();
1733     if( writer->open( filename, fourcc, fps, width, height, isColor != 0 ))
1734         return writer;
1735     writer->close();
1736     free(writer);
1737     return 0;
1738 }
1739
1740 void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
1741 {
1742     if( writer && *writer )
1743     {
1744         (*writer)->close();
1745         free(*writer);
1746         *writer = 0;
1747     }
1748 }
1749
1750
1751 int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer,
1752                          const unsigned char* data, int step,
1753                          int width, int height, int cn, int origin)
1754 {
1755     return writer->writeFrame(data, step, width, height, cn, origin);
1756 }
1757
1758
1759
1760 /*
1761  * For CUDA encoder
1762  */
1763
1764 struct OutputMediaStream_FFMPEG
1765 {
1766     bool open(const char* fileName, int width, int height, double fps);
1767     void close();
1768
1769     void write(unsigned char* data, int size, int keyFrame);
1770
1771     // add a video output stream to the container
1772     static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format);
1773
1774     AVOutputFormat* fmt_;
1775     AVFormatContext* oc_;
1776     AVStream* video_st_;
1777 };
1778
1779 void OutputMediaStream_FFMPEG::close()
1780 {
1781     // no more frame to compress. The codec has a latency of a few
1782     // frames if using B frames, so we get the last frames by
1783     // passing the same picture again
1784
1785     // TODO -- do we need to account for latency here?
1786
1787     if (oc_)
1788     {
1789         // write the trailer, if any
1790         av_write_trailer(oc_);
1791
1792         // free the streams
1793         for (unsigned int i = 0; i < oc_->nb_streams; ++i)
1794         {
1795             av_freep(&oc_->streams[i]->codec);
1796             av_freep(&oc_->streams[i]);
1797         }
1798
1799         if (!(fmt_->flags & AVFMT_NOFILE) && oc_->pb)
1800         {
1801             // close the output file
1802
1803             #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
1804                 #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1805                     url_fclose(oc_->pb);
1806                 #else
1807                     url_fclose(&oc_->pb);
1808                 #endif
1809             #else
1810                 avio_close(oc_->pb);
1811             #endif
1812         }
1813
1814         // free the stream
1815         av_free(oc_);
1816     }
1817 }
1818
1819 AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, PixelFormat pixel_format)
1820 {
1821     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
1822         AVStream* st = avformat_new_stream(oc, 0);
1823     #else
1824         AVStream* st = av_new_stream(oc, 0);
1825     #endif
1826     if (!st)
1827         return 0;
1828
1829     #if LIBAVFORMAT_BUILD > 4628
1830         AVCodecContext* c = st->codec;
1831     #else
1832         AVCodecContext* c = &(st->codec);
1833     #endif
1834
1835     c->codec_id = codec_id;
1836     c->codec_type = AVMEDIA_TYPE_VIDEO;
1837
1838     // put sample parameters
1839     unsigned long long lbit_rate = static_cast<unsigned long long>(bitrate);
1840     lbit_rate += (bitrate / 4);
1841     lbit_rate = std::min(lbit_rate, static_cast<unsigned long long>(std::numeric_limits<int>::max()));
1842     c->bit_rate = bitrate;
1843
1844     // took advice from
1845     // http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html
1846     c->qmin = 3;
1847
1848     // resolution must be a multiple of two
1849     c->width = w;
1850     c->height = h;
1851
1852     AVCodec* codec = avcodec_find_encoder(c->codec_id);
1853
1854     // time base: this is the fundamental unit of time (in seconds) in terms
1855     // of which frame timestamps are represented. for fixed-fps content,
1856     // timebase should be 1/framerate and timestamp increments should be
1857     // identically 1
1858
1859     int frame_rate = static_cast<int>(fps+0.5);
1860     int frame_rate_base = 1;
1861     while (fabs(static_cast<double>(frame_rate)/frame_rate_base) - fps > 0.001)
1862     {
1863         frame_rate_base *= 10;
1864         frame_rate = static_cast<int>(fps*frame_rate_base + 0.5);
1865     }
1866     c->time_base.den = frame_rate;
1867     c->time_base.num = frame_rate_base;
1868
1869     #if LIBAVFORMAT_BUILD > 4752
1870         // adjust time base for supported framerates
1871         if (codec && codec->supported_framerates)
1872         {
1873             AVRational req = {frame_rate, frame_rate_base};
1874             const AVRational* best = NULL;
1875             AVRational best_error = {INT_MAX, 1};
1876
1877             for (const AVRational* p = codec->supported_framerates; p->den!=0; ++p)
1878             {
1879                 AVRational error = av_sub_q(req, *p);
1880
1881                 if (error.num < 0)
1882                     error.num *= -1;
1883
1884                 if (av_cmp_q(error, best_error) < 0)
1885                 {
1886                     best_error= error;
1887                     best= p;
1888                 }
1889             }
1890
1891             c->time_base.den= best->num;
1892             c->time_base.num= best->den;
1893         }
1894     #endif
1895
1896     c->gop_size = 12; // emit one intra frame every twelve frames at most
1897     c->pix_fmt = pixel_format;
1898
1899     if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO))
1900         c->max_b_frames = 2;
1901
1902     if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3))
1903     {
1904         // needed to avoid using macroblocks in which some coeffs overflow
1905         // this doesnt happen with normal video, it just happens here as the
1906         // motion of the chroma plane doesnt match the luma plane
1907
1908         // avoid FFMPEG warning 'clipping 1 dct coefficients...'
1909
1910         c->mb_decision = 2;
1911     }
1912
1913     #if LIBAVCODEC_VERSION_INT > 0x000409
1914         // some formats want stream headers to be seperate
1915         if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1916         {
1917             c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1918         }
1919     #endif
1920
1921     return st;
1922 }
1923
1924 bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, double fps)
1925 {
1926     fmt_ = 0;
1927     oc_ = 0;
1928     video_st_ = 0;
1929
1930     // auto detect the output format from the name and fourcc code
1931     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1932         fmt_ = av_guess_format(NULL, fileName, NULL);
1933     #else
1934         fmt_ = guess_format(NULL, fileName, NULL);
1935     #endif
1936     if (!fmt_)
1937         return false;
1938
1939     CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_H264);
1940
1941     // alloc memory for context
1942     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1943         oc_ = avformat_alloc_context();
1944     #else
1945         oc_ = av_alloc_format_context();
1946     #endif
1947     if (!oc_)
1948         return false;
1949
1950     // set some options
1951     oc_->oformat = fmt_;
1952     snprintf(oc_->filename, sizeof(oc_->filename), "%s", fileName);
1953
1954     oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG
1955
1956     // set a few optimal pixel formats for lossless codecs of interest..
1957     PixelFormat codec_pix_fmt = PIX_FMT_YUV420P;
1958     int bitrate_scale = 64;
1959
1960     // TODO -- safe to ignore output audio stream?
1961     video_st_ = addVideoStream(oc_, codec_id, width, height, width * height * bitrate_scale, fps, codec_pix_fmt);
1962     if (!video_st_)
1963         return false;
1964
1965     // set the output parameters (must be done even if no parameters)
1966     #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1967         if (av_set_parameters(oc_, NULL) < 0)
1968             return false;
1969     #endif
1970
1971     // now that all the parameters are set, we can open the audio and
1972     // video codecs and allocate the necessary encode buffers
1973
1974     #if LIBAVFORMAT_BUILD > 4628
1975         AVCodecContext* c = (video_st_->codec);
1976     #else
1977         AVCodecContext* c = &(video_st_->codec);
1978     #endif
1979
1980     c->codec_tag = MKTAG('H', '2', '6', '4');
1981     c->bit_rate_tolerance = c->bit_rate;
1982
1983     // open the output file, if needed
1984     if (!(fmt_->flags & AVFMT_NOFILE))
1985     {
1986         #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1987             int err = url_fopen(&oc_->pb, fileName, URL_WRONLY);
1988         #else
1989             int err = avio_open(&oc_->pb, fileName, AVIO_FLAG_WRITE);
1990         #endif
1991
1992         if (err != 0)
1993             return false;
1994     }
1995
1996     // write the stream header, if any
1997     #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1998         av_write_header(oc_);
1999     #else
2000         avformat_write_header(oc_, NULL);
2001     #endif
2002
2003     return true;
2004 }
2005
2006 void OutputMediaStream_FFMPEG::write(unsigned char* data, int size, int keyFrame)
2007 {
2008     // if zero size, it means the image was buffered
2009     if (size > 0)
2010     {
2011         AVPacket pkt;
2012         av_init_packet(&pkt);
2013
2014         if (keyFrame)
2015             pkt.flags |= PKT_FLAG_KEY;
2016
2017         pkt.stream_index = video_st_->index;
2018         pkt.data = data;
2019         pkt.size = size;
2020
2021         // write the compressed frame in the media file
2022         av_write_frame(oc_, &pkt);
2023     }
2024 }
2025
2026 struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps)
2027 {
2028     OutputMediaStream_FFMPEG* stream = (OutputMediaStream_FFMPEG*) malloc(sizeof(OutputMediaStream_FFMPEG));
2029
2030     if (stream->open(fileName, width, height, fps))
2031         return stream;
2032
2033     stream->close();
2034     free(stream);
2035
2036     return 0;
2037 }
2038
2039 void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream)
2040 {
2041     stream->close();
2042     free(stream);
2043 }
2044
2045 void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame)
2046 {
2047     stream->write(data, size, keyFrame);
2048 }
2049
2050 /*
2051  * For CUDA decoder
2052  */
2053
2054 enum
2055 {
2056     VideoCodec_MPEG1 = 0,
2057     VideoCodec_MPEG2,
2058     VideoCodec_MPEG4,
2059     VideoCodec_VC1,
2060     VideoCodec_H264,
2061     VideoCodec_JPEG,
2062     VideoCodec_H264_SVC,
2063     VideoCodec_H264_MVC,
2064
2065     // Uncompressed YUV
2066     VideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')),   // Y,U,V (4:2:0)
2067     VideoCodec_YV12   = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')),   // Y,V,U (4:2:0)
2068     VideoCodec_NV12   = (('N'<<24)|('V'<<16)|('1'<<8)|('2')),   // Y,UV  (4:2:0)
2069     VideoCodec_YUYV   = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')),   // YUYV/YUY2 (4:2:2)
2070     VideoCodec_UYVY   = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')),   // UYVY (4:2:2)
2071 };
2072
2073 enum
2074 {
2075     VideoChromaFormat_Monochrome = 0,
2076     VideoChromaFormat_YUV420,
2077     VideoChromaFormat_YUV422,
2078     VideoChromaFormat_YUV444,
2079 };
2080
2081 struct InputMediaStream_FFMPEG
2082 {
2083 public:
2084     bool open(const char* fileName, int* codec, int* chroma_format, int* width, int* height);
2085     void close();
2086
2087     bool read(unsigned char** data, int* size, int* endOfFile);
2088
2089 private:
2090     InputMediaStream_FFMPEG(const InputMediaStream_FFMPEG&);
2091     InputMediaStream_FFMPEG& operator =(const InputMediaStream_FFMPEG&);
2092
2093     AVFormatContext* ctx_;
2094     int video_stream_id_;
2095     AVPacket pkt_;
2096 };
2097
2098 bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
2099 {
2100     int err;
2101
2102     ctx_ = 0;
2103     video_stream_id_ = -1;
2104     memset(&pkt_, 0, sizeof(AVPacket));
2105
2106     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
2107         avformat_network_init();
2108     #endif
2109
2110     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
2111         err = avformat_open_input(&ctx_, fileName, 0, 0);
2112     #else
2113         err = av_open_input_file(&ctx_, fileName, 0, 0, 0);
2114     #endif
2115     if (err < 0)
2116         return false;
2117
2118     #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 3, 0)
2119         err = avformat_find_stream_info(ctx_, 0);
2120     #else
2121         err = av_find_stream_info(ctx_);
2122     #endif
2123     if (err < 0)
2124         return false;
2125
2126     for (unsigned int i = 0; i < ctx_->nb_streams; ++i)
2127     {
2128         #if LIBAVFORMAT_BUILD > 4628
2129             AVCodecContext *enc = ctx_->streams[i]->codec;
2130         #else
2131             AVCodecContext *enc = &ctx_->streams[i]->codec;
2132         #endif
2133
2134         if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
2135         {
2136             video_stream_id_ = static_cast<int>(i);
2137
2138             switch (enc->codec_id)
2139             {
2140             case CV_CODEC(CODEC_ID_MPEG1VIDEO):
2141                 *codec = ::VideoCodec_MPEG1;
2142                 break;
2143
2144             case CV_CODEC(CODEC_ID_MPEG2VIDEO):
2145                 *codec = ::VideoCodec_MPEG2;
2146                 break;
2147
2148             case CV_CODEC(CODEC_ID_MPEG4):
2149                 *codec = ::VideoCodec_MPEG4;
2150                 break;
2151
2152             case CV_CODEC(CODEC_ID_VC1):
2153                 *codec = ::VideoCodec_VC1;
2154                 break;
2155
2156             case CV_CODEC(CODEC_ID_H264):
2157                 *codec = ::VideoCodec_H264;
2158                 break;
2159
2160             default:
2161                 return false;
2162             };
2163
2164             switch (enc->pix_fmt)
2165             {
2166             case PIX_FMT_YUV420P:
2167                 *chroma_format = ::VideoChromaFormat_YUV420;
2168                 break;
2169
2170             case PIX_FMT_YUV422P:
2171                 *chroma_format = ::VideoChromaFormat_YUV422;
2172                 break;
2173
2174             case PIX_FMT_YUV444P:
2175                 *chroma_format = ::VideoChromaFormat_YUV444;
2176                 break;
2177
2178             default:
2179                 return false;
2180             }
2181
2182             *width = enc->coded_width;
2183             *height = enc->coded_height;
2184
2185             break;
2186         }
2187     }
2188
2189     if (video_stream_id_ < 0)
2190         return false;
2191
2192     av_init_packet(&pkt_);
2193
2194     return true;
2195 }
2196
2197 void InputMediaStream_FFMPEG::close()
2198 {
2199     if (ctx_)
2200     {
2201         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 24, 2)
2202             avformat_close_input(&ctx_);
2203         #else
2204             av_close_input_file(ctx_);
2205         #endif
2206     }
2207
2208     // free last packet if exist
2209     if (pkt_.data)
2210         av_free_packet(&pkt_);
2211 }
2212
2213 bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFile)
2214 {
2215     // free last packet if exist
2216     if (pkt_.data)
2217         av_free_packet(&pkt_);
2218
2219     // get the next frame
2220     for (;;)
2221     {
2222         int ret = av_read_frame(ctx_, &pkt_);
2223
2224         if (ret == AVERROR(EAGAIN))
2225             continue;
2226
2227         if (ret < 0)
2228         {
2229             if (ret == (int)AVERROR_EOF)
2230                 *endOfFile = true;
2231             return false;
2232         }
2233
2234         if (pkt_.stream_index != video_stream_id_)
2235         {
2236             av_free_packet(&pkt_);
2237             continue;
2238         }
2239
2240         break;
2241     }
2242
2243     *data = pkt_.data;
2244     *size = pkt_.size;
2245     *endOfFile = false;
2246
2247     return true;
2248 }
2249
2250 InputMediaStream_FFMPEG* create_InputMediaStream_FFMPEG(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
2251 {
2252     InputMediaStream_FFMPEG* stream = (InputMediaStream_FFMPEG*) malloc(sizeof(InputMediaStream_FFMPEG));
2253
2254     if (stream && stream->open(fileName, codec, chroma_format, width, height))
2255         return stream;
2256
2257     stream->close();
2258     free(stream);
2259
2260     return 0;
2261 }
2262
2263 void release_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream)
2264 {
2265     stream->close();
2266     free(stream);
2267 }
2268
2269 int read_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile)
2270 {
2271     return stream->read(data, size, endOfFile);
2272 }