Updated license text in highgui files
[profile/ivi/opencv.git] / modules / highgui / src / cap_ffmpeg_impl_v2.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
47 #if defined _MSC_VER && _MSC_VER >= 1200
48 #pragma warning( disable: 4244 4510 4512 4610 )
49 #endif
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 #if !defined(WIN32) || defined(__MINGW32__)
56 // some versions of FFMPEG assume a C99 compiler, and don't define INT64_C
57 #if !defined INT64_C || !defined UINT64_C
58 #define INT64_C
59 #define UINT64_C
60 #define __STDC_CONSTANT_MACROS
61 // force re-inclusion of stdint.h to get INT64_C macro
62 #undef _STDINT_H
63 #include <stdint.h>
64 #endif
65 #include <errno.h>
66 #endif
67
68 #ifdef WIN32
69   #define HAVE_FFMPEG_SWSCALE 1
70   #include <libavformat/avformat.h>
71   #include <libavcodec/avcodec.h>
72   #include <libswscale/swscale.h>
73 #else
74
75 // if the header path is not specified explicitly, let's deduce it
76 #if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H
77
78 #if defined(HAVE_GENTOO_FFMPEG)
79   #define HAVE_LIBAVCODEC_AVCODEC_H 1
80   #define HAVE_LIBAVFORMAT_AVFORMAT_H 1
81   #if defined(HAVE_FFMPEG_SWSCALE)
82     #define HAVE_LIBSWSCALE_SWSCALE_H 1
83   #endif
84 #elif defined HAVE_FFMPEG
85   #define HAVE_FFMPEG_AVCODEC_H 1
86   #define HAVE_FFMPEG_AVFORMAT_H 1
87   #if defined(HAVE_FFMPEG_SWSCALE)
88     #define HAVE_FFMPEG_SWSCALE_H 1
89   #endif
90 #endif
91
92 #endif
93
94 #if defined(HAVE_FFMPEG_AVCODEC_H)
95   #include <ffmpeg/avcodec.h>
96 #endif
97 #if defined(HAVE_FFMPEG_AVFORMAT_H)
98   #include <ffmpeg/avformat.h>
99 #endif
100 #if defined(HAVE_FFMPEG_SWSCALE_H)
101   #include <ffmpeg/swscale.h>
102 #endif
103
104 #if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
105   #include <libavformat/avformat.h>
106 #endif
107 #if defined(HAVE_LIBAVCODEC_AVCODEC_H)
108   #include <libavcodec/avcodec.h>
109 #endif
110 #if defined(HAVE_LIBSWSCALE_SWSCALE_H)
111   #include <libswscale/swscale.h>
112 #endif
113
114 #endif
115
116 #ifdef __cplusplus
117 }
118 #endif
119
120 #if defined _MSC_VER && _MSC_VER >= 1200
121 #pragma warning( default: 4244 4510 4512 4610 )
122 #endif
123
124 #ifdef NDEBUG
125 #define CV_WARN(message)
126 #else
127 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
128 #endif
129
130
131 #ifndef MKTAG
132 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
133 #endif
134
135 /* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */
136 #ifndef PIX_FMT_RGBA32
137 #define PIX_FMT_RGBA32 PIX_FMT_RGB32
138 #endif
139
140 #define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c )
141
142 #if defined WIN32 || defined _WIN32
143     #include <windows.h>
144 #elif defined __linux__ || defined __APPLE__
145     #include <unistd.h>
146     #include <stdio.h>
147     #include <sys/types.h>
148     #include <sys/sysctl.h>
149 #endif
150
151 int get_number_of_cpus(void)
152 {
153 #if defined WIN32 || defined _WIN32
154     SYSTEM_INFO sysinfo;
155     GetSystemInfo( &sysinfo );
156
157     return (int)sysinfo.dwNumberOfProcessors;
158 #elif defined __linux__
159     return (int)sysconf( _SC_NPROCESSORS_ONLN );
160 #elif defined __APPLE__
161     int numCPU=0;
162     int mib[4];
163     size_t len = sizeof(numCPU);
164
165     /* set the mib for hw.ncpu */
166     mib[0] = CTL_HW;
167     mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
168
169     /* get the number of CPUs from the system */
170     sysctl(mib, 2, &numCPU, &len, NULL, 0);
171
172     if( numCPU < 1 )
173     {
174         mib[1] = HW_NCPU;
175         sysctl( mib, 2, &numCPU, &len, NULL, 0 );
176
177         if( numCPU < 1 )
178             numCPU = 1;
179     }
180
181     return (int)numCPU;
182 #else
183     return 1;
184 #endif
185 }
186
187
188 char * FOURCC2str( int fourcc )
189 {
190     char * mystr=(char*)malloc(5);
191     mystr[0]=(char)((fourcc    )&255);
192     mystr[1]=(char)((fourcc>> 8)&255);
193     mystr[2]=(char)((fourcc>>16)&255);
194     mystr[3]=(char)((fourcc>>24)&255);
195     mystr[4]=0;
196     return mystr;
197 }
198
199
200 // required to look up the correct codec ID depending on the FOURCC code,
201 // this is just a snipped from the file riff.c from ffmpeg/libavformat
202 typedef struct AVCodecTag {
203     int id;
204     unsigned int tag;
205 } AVCodecTag;
206
207 const AVCodecTag codec_bmp_tags[] = {
208     { CODEC_ID_H264, MKTAG('H', '2', '6', '4') },
209     { CODEC_ID_H264, MKTAG('h', '2', '6', '4') },
210     { CODEC_ID_H264, MKTAG('X', '2', '6', '4') },
211     { CODEC_ID_H264, MKTAG('x', '2', '6', '4') },
212     { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
213     { CODEC_ID_H264, MKTAG('V', 'S', 'S', 'H') },
214
215     { CODEC_ID_H263, MKTAG('H', '2', '6', '3') },
216     { CODEC_ID_H263P, MKTAG('H', '2', '6', '3') },
217     { CODEC_ID_H263I, MKTAG('I', '2', '6', '3') }, /* intel h263 */
218     { CODEC_ID_H261, MKTAG('H', '2', '6', '1') },
219
220     /* added based on MPlayer */
221     { CODEC_ID_H263P, MKTAG('U', '2', '6', '3') },
222     { CODEC_ID_H263P, MKTAG('v', 'i', 'v', '1') },
223
224     { CODEC_ID_MPEG4, MKTAG('F', 'M', 'P', '4') },
225     { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') },
226     { CODEC_ID_MPEG4, MKTAG('D', 'X', '5', '0') },
227     { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
228     { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
229     { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') },
230     { CODEC_ID_MPEG4, MKTAG(0x04, 0, 0, 0) }, /* some broken avi use this */
231
232     /* added based on MPlayer */
233     { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', '1') },
234     { CODEC_ID_MPEG4, MKTAG('B', 'L', 'Z', '0') },
235     { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
236     { CODEC_ID_MPEG4, MKTAG('U', 'M', 'P', '4') },
237     { CODEC_ID_MPEG4, MKTAG('W', 'V', '1', 'F') },
238     { CODEC_ID_MPEG4, MKTAG('S', 'E', 'D', 'G') },
239
240     { CODEC_ID_MPEG4, MKTAG('R', 'M', 'P', '4') },
241
242     { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') }, /* default signature when using MSMPEG4 */
243     { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
244
245     /* added based on MPlayer */
246     { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') },
247     { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '5') },
248     { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '6') },
249     { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '4') },
250     { CODEC_ID_MSMPEG4V3, MKTAG('A', 'P', '4', '1') },
251     { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '1') },
252     { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '0') },
253
254     { CODEC_ID_MSMPEG4V2, MKTAG('M', 'P', '4', '2') },
255
256     /* added based on MPlayer */
257     { CODEC_ID_MSMPEG4V2, MKTAG('D', 'I', 'V', '2') },
258
259     { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', 'G', '4') },
260
261     { CODEC_ID_WMV1, MKTAG('W', 'M', 'V', '1') },
262
263     /* added based on MPlayer */
264     { CODEC_ID_WMV2, MKTAG('W', 'M', 'V', '2') },
265     { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'd') },
266     { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'd') },
267     { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'l') },
268     { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '2', '5') },
269     { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') },
270     { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') },
271     { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', '2') },
272     { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'P', 'E', 'G') },
273     { CODEC_ID_MPEG1VIDEO, MKTAG('P', 'I', 'M', '1') },
274     { CODEC_ID_MPEG1VIDEO, MKTAG('V', 'C', 'R', '2') },
275     { CODEC_ID_MPEG1VIDEO, 0x10000001 },
276     { CODEC_ID_MPEG2VIDEO, 0x10000002 },
277     { CODEC_ID_MPEG2VIDEO, MKTAG('D', 'V', 'R', ' ') },
278     { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'M', 'E', 'S') },
279     { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') },
280     { CODEC_ID_MJPEG, MKTAG('L', 'J', 'P', 'G') },
281     { CODEC_ID_LJPEG, MKTAG('L', 'J', 'P', 'G') },
282     { CODEC_ID_MJPEG, MKTAG('J', 'P', 'G', 'L') }, /* Pegasus lossless JPEG */
283     { CODEC_ID_MJPEG, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
284     { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') },
285     { CODEC_ID_MJPEG, MKTAG('I', 'J', 'P', 'G') },
286     { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') },
287     { CODEC_ID_HUFFYUV, MKTAG('H', 'F', 'Y', 'U') },
288     { CODEC_ID_FFVHUFF, MKTAG('F', 'F', 'V', 'H') },
289     { CODEC_ID_CYUV, MKTAG('C', 'Y', 'U', 'V') },
290     { CODEC_ID_RAWVIDEO, 0 },
291     { CODEC_ID_RAWVIDEO, MKTAG('I', '4', '2', '0') },
292     { CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'Y', '2') },
293     { CODEC_ID_RAWVIDEO, MKTAG('Y', '4', '2', '2') },
294     { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '2') },
295     { CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'V', 'Y') },
296     { CODEC_ID_RAWVIDEO, MKTAG('I', 'Y', 'U', 'V') },
297     { CODEC_ID_RAWVIDEO, MKTAG('Y', '8', '0', '0') },
298     { CODEC_ID_RAWVIDEO, MKTAG('H', 'D', 'Y', 'C') },
299     { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') },
300     { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') },
301     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
302     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') },
303     { CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') },
304     { CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') },
305     { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') },
306     { CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
307     { CODEC_ID_XAN_WC4, MKTAG('X', 'x', 'a', 'n') },
308     { CODEC_ID_MSRLE, MKTAG('m', 'r', 'l', 'e') },
309     { CODEC_ID_MSRLE, MKTAG(0x1, 0x0, 0x0, 0x0) },
310     { CODEC_ID_MSVIDEO1, MKTAG('M', 'S', 'V', 'C') },
311     { CODEC_ID_MSVIDEO1, MKTAG('m', 's', 'v', 'c') },
312     { CODEC_ID_MSVIDEO1, MKTAG('C', 'R', 'A', 'M') },
313     { CODEC_ID_MSVIDEO1, MKTAG('c', 'r', 'a', 'm') },
314     { CODEC_ID_MSVIDEO1, MKTAG('W', 'H', 'A', 'M') },
315     { CODEC_ID_MSVIDEO1, MKTAG('w', 'h', 'a', 'm') },
316     { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') },
317     { CODEC_ID_TRUEMOTION1, MKTAG('D', 'U', 'C', 'K') },
318     { CODEC_ID_MSZH, MKTAG('M', 'S', 'Z', 'H') },
319     { CODEC_ID_ZLIB, MKTAG('Z', 'L', 'I', 'B') },
320     { CODEC_ID_SNOW, MKTAG('S', 'N', 'O', 'W') },
321     { CODEC_ID_4XM, MKTAG('4', 'X', 'M', 'V') },
322     { CODEC_ID_FLV1, MKTAG('F', 'L', 'V', '1') },
323     { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') },
324     { CODEC_ID_TSCC, MKTAG('t', 's', 'c', 'c') },
325     { CODEC_ID_ULTI, MKTAG('U', 'L', 'T', 'I') },
326     { CODEC_ID_VIXL, MKTAG('V', 'I', 'X', 'L') },
327     { CODEC_ID_QPEG, MKTAG('Q', 'P', 'E', 'G') },
328     { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
329     { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
330     { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
331     { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
332     { CODEC_ID_THEORA, MKTAG('t', 'h', 'e', 'o') },
333 #if LIBAVCODEC_VERSION_INT>0x000409
334     { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
335     { CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },
336     { CODEC_ID_INDEO2, MKTAG('R', 'T', '2', '1') },
337     { CODEC_ID_FRAPS, MKTAG('F', 'P', 'S', '1') },
338     { CODEC_ID_TRUEMOTION2, MKTAG('T', 'M', '2', '0') },
339 #endif
340 #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
341     { CODEC_ID_FLASHSV, MKTAG('F', 'S', 'V', '1') },
342     { CODEC_ID_JPEGLS,MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - encoder */
343     { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
344     { CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },
345     { CODEC_ID_CSCD, MKTAG('C', 'S', 'C', 'D') },
346     { CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') },
347     { CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') },
348 #endif
349 #if LIBAVCODEC_VERSION_INT>((51<<16)+(11<<8)+0)
350     { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
351     { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') },
352     { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') },
353     { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
354     { CODEC_ID_VP6F, MKTAG('V', 'P', '6', 'F') },
355     { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
356     { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
357 #endif
358 #if LIBAVCODEC_VERSION_INT>=((51<<16)+(49<<8)+0)
359 // this tag seems not to exist in older versions of FFMPEG
360     { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
361 #endif
362     { CODEC_ID_NONE, 0 },
363 };
364
365
366 struct Image_FFMPEG
367 {
368     unsigned char* data;
369     int step;
370     int width;
371     int height;
372     int cn;
373 };
374
375
376 inline void _opencv_ffmpeg_free(void** ptr)
377 {
378     if(*ptr) free(*ptr);
379     *ptr = 0;
380 }
381
382
383 struct CvCapture_FFMPEG
384 {
385     bool open( const char* filename );
386     void close();
387
388     double getProperty(int);
389     bool setProperty(int, double);
390     bool grabFrame();
391     bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
392
393     void init();
394     bool reopen();
395
396     void    seek(int64_t frame_number);
397     void    seek(double sec);
398     bool        slowSeek( int framenumber );
399
400     int64_t get_total_frames();
401     double  get_duration_sec();
402     double  get_fps();
403     int     get_bitrate();
404
405     double  r2d(AVRational r);
406     int64_t dts_to_frame_number(int64_t dts);
407     double  dts_to_sec(int64_t dts);
408
409     AVFormatContext * ic;
410     AVCodecContext  * avcodec_context;
411     AVCodec         * avcodec;
412     int               video_stream;
413     AVStream        * video_st;
414     AVFrame         * picture;        
415     AVFrame           rgb_picture;    
416     int64_t           picture_pts;
417
418     AVPacket          packet;
419     Image_FFMPEG      frame;
420         #if defined(HAVE_FFMPEG_SWSCALE)
421                 struct SwsContext *img_convert_ctx;
422         #endif
423
424     int64_t frame_number;
425
426     double eps_zero;
427 /*
428    'filename' contains the filename of the videosource,
429    'filename==NULL' indicates that ffmpeg's seek support works
430    for the particular file.
431    'filename!=NULL' indicates that the slow fallback function is used for seeking,
432    and so the filename is needed to reopen the file on backward seeking.
433 */
434     char              * filename;
435 };
436
437 void CvCapture_FFMPEG::init()
438 {
439     ic = 0;
440     video_stream = -1;
441     video_st = 0;
442     picture = 0;
443     picture_pts = 0;
444     memset( &rgb_picture, 0, sizeof(rgb_picture) );
445     memset( &frame, 0, sizeof(frame) );
446     filename = 0;
447     packet.data = NULL;
448         #if defined(HAVE_FFMPEG_SWSCALE)
449                 img_convert_ctx = 0;
450         #endif
451
452     avcodec_context = 0;
453     avcodec = 0;
454     frame_number = 0;
455     eps_zero = 0.000025;
456 }
457
458
459 void CvCapture_FFMPEG::close()
460 {
461     if( picture )
462     av_free(picture);
463
464     if( video_st )
465     {
466         #if LIBAVFORMAT_BUILD > 4628
467                 avcodec_close( video_st->codec );
468
469         #else
470                 avcodec_close( &(video_st->codec) );
471
472         #endif
473                 video_st = NULL;
474     }
475
476     if ( avcodec_context )
477     {
478         #if LIBAVFORMAT_BUILD > 4628
479                 avcodec_close( avcodec_context );
480
481         #else
482                 avcodec_close( &avcodec_context );
483
484         #endif
485                 avcodec_context = NULL;
486     }
487
488     if( ic )
489     {
490      #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
491                 av_close_input_file(ic);
492          #else
493                 avformat_close_input(&ic);
494      #endif
495
496      ic = NULL;
497     }
498
499     if( rgb_picture.data[0] )
500     {
501         free( rgb_picture.data[0] );
502         rgb_picture.data[0] = 0;
503     }
504
505     // free last packet if exist
506     if (packet.data) {
507         av_free_packet (&packet);
508     }
509
510     init();
511 }
512
513
514 /*
515     Used to reopen a video if the slower fallback function for seeking is used.
516 */
517 bool CvCapture_FFMPEG::reopen()
518 {
519     if ( filename==NULL ) return false;
520
521         #if LIBAVFORMAT_BUILD > 4628
522                 avcodec_close( video_st->codec );
523                 avcodec_close( avcodec_context );
524         #else
525                 avcodec_close( &video_st->codec );
526                 avcodec_close( &avcodec_context );
527         #endif
528     #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
529         av_close_input_file(ic);
530     #else
531         avformat_close_input(&ic);
532     #endif
533
534     // reopen video
535     avformat_open_input(&ic, filename, NULL, NULL);
536     av_find_stream_info(ic);
537         #if LIBAVFORMAT_BUILD > 4628
538                 AVCodecContext *enc = ic->streams[video_stream]->codec;
539         #else
540                 AVCodecContext *enc = &ic->streams[video_stream]->codec;
541         #endif
542
543         #ifdef FF_API_THREAD_INIT
544                 avcodec_thread_init(enc, std::min(get_number_of_cpus(), 16));
545         #endif
546
547         AVCodec *codec = avcodec_find_decoder(enc->codec_id);
548         #if FF_API_AVCODEC_OPEN
549                 avcodec_open(enc, codec);
550         #else
551                 avcodec_open_2(enc, codec, NULL);
552         #endif
553         video_st = ic->streams[video_stream];
554
555         // reset framenumber to zero
556         frame_number = 0;
557     picture_pts=0;
558
559     return true;
560 }
561
562 #ifndef AVSEEK_FLAG_FRAME
563     #define AVSEEK_FLAG_FRAME 0
564 #endif
565 #ifndef AVSEEK_FLAG_ANY
566     #define AVSEEK_FLAG_ANY 1
567 #endif
568
569 bool CvCapture_FFMPEG::open( const char* _filename )
570 {
571     unsigned i;
572     bool valid = false;
573
574     close();
575         
576         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
577                 avformat_network_init();
578         #endif
579
580     /* register all codecs, demux and protocols */
581     av_register_all();
582
583     #ifndef _DEBUG
584         // av_log_level = AV_LOG_QUIET;
585     #endif
586
587     int err = avformat_open_input(&ic, _filename, NULL, NULL);
588     if (err < 0) {
589         CV_WARN("Error opening file");
590         goto exit_func;
591     }
592     err = av_find_stream_info(ic);
593     if (err < 0) {
594         CV_WARN("Could not find codec parameters");
595         goto exit_func;
596     }
597     for(i = 0; i < ic->nb_streams; i++)
598     {
599         #if LIBAVFORMAT_BUILD > 4628
600                 AVCodecContext *enc = ic->streams[i]->codec;
601         #else
602                 AVCodecContext *enc = &ic->streams[i]->codec;
603         #endif
604
605         #ifdef FF_API_THREAD_INIT
606                 avcodec_thread_init(enc, get_number_of_cpus());
607         #else
608                 enc->thread_count = get_number_of_cpus();
609         #endif
610
611         #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
612             #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
613         #endif
614
615         if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) {
616             AVCodec *codec = avcodec_find_decoder(enc->codec_id);
617             if (!codec ||
618                 #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
619                             avcodec_open2(enc, codec, NULL)
620                 #else
621                             avcodec_open(enc, codec)
622                 #endif
623                         < 0) goto exit_func;
624
625             video_stream = i;
626             video_st = ic->streams[i];
627             picture = avcodec_alloc_frame();
628
629             rgb_picture.data[0] = (uint8_t*)malloc(
630                                     avpicture_get_size( PIX_FMT_BGR24,
631                                     enc->width, enc->height ));
632             avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
633                     PIX_FMT_BGR24, enc->width, enc->height );
634
635             frame.width = enc->width;
636             frame.height = enc->height;
637             frame.cn = 3;
638             frame.step = rgb_picture.linesize[0];
639             frame.data = rgb_picture.data[0];
640             break;
641         }
642     }
643
644     if(video_stream >= 0) valid = true;
645
646     // perform check if source is seekable via ffmpeg's seek function av_seek_frame(...)
647     err = av_seek_frame(ic, video_stream, 10, 0);
648     if (err < 0)
649     {
650         filename=(char*)malloc(strlen(_filename)+1);
651         strcpy(filename, _filename);
652         // reopen videofile to 'seek' back to first frame
653         reopen();
654     }
655     else
656     {
657         // seek seems to work, so we don't need the filename,
658         // but we still need to seek back to filestart
659         filename=NULL;
660         int64_t ts    = video_st->first_dts;
661         int     flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD;
662         av_seek_frame(ic, video_stream, ts, flags);
663     }
664 exit_func:
665
666     if( !valid )
667         close();
668
669     return valid;
670 }
671
672
673 bool CvCapture_FFMPEG::grabFrame()
674 {
675     bool valid = false;
676     static bool bFirstTime = true;
677     int got_picture;
678
679     int count_errs = 0;
680     const int max_number_of_attempts = 64;
681
682     if (bFirstTime)
683     {
684         bFirstTime = false;
685         packet.data = NULL;
686     }
687
688     if( !ic || !video_st )  return false;
689
690     if (packet.data != NULL)
691     {
692         av_free_packet (&packet);
693     }
694
695     // get the next frame
696     while (!valid)
697     {
698         int ret = av_read_frame(ic, &packet);
699
700         if (ret == AVERROR(EAGAIN)) continue;
701
702         /* else if (ret < 0) break; */
703
704         if( packet.stream_index != video_stream )
705         {
706                 av_free_packet (&packet);
707                 count_errs++;
708                 if (count_errs > max_number_of_attempts) break; else
709                 continue;
710         }
711
712         // Decode video frame
713         avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
714
715             // Did we get a video frame?
716             if(got_picture)
717             {
718                           frame_number++;
719                           picture_pts = packet.pts;
720                           valid = true;
721                       }
722                       else
723                       {
724                           count_errs++;
725                           if (count_errs > max_number_of_attempts)
726                                   break;
727                       }
728
729     }
730
731     // return if we have a new picture or not
732     return valid;
733 }
734
735
736 bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
737 {
738     if( !video_st || !picture->data[0] )
739         return false;
740
741     rgb_picture = *avcodec_alloc_frame();
742
743     avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, video_st->codec->width, video_st->codec->height);
744
745     #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(6<<8)+0)
746
747                     frame.width  = picture->width;
748                     frame.height = picture->height;
749
750     #else
751                     frame.width = video_st->codec->width;
752                     frame.height = video_st->codec->height;
753     #endif
754
755    img_convert_ctx = sws_getContext(
756                                                          video_st->codec->width, video_st->codec->height,
757                                                                    video_st->codec->pix_fmt,
758                                                                    video_st->codec->width, video_st->codec->height,
759                                                                    PIX_FMT_BGR24,
760                                                                    SWS_BICUBIC,
761                                                                    NULL, NULL, NULL
762                                                                   );
763
764                           img_convert_ctx = sws_getCachedContext(
765                                                                    img_convert_ctx,
766                                                                    video_st->codec->width, video_st->codec->height,
767                                                                    video_st->codec->pix_fmt,
768                                                                    video_st->codec->width, video_st->codec->height,
769                                                                    PIX_FMT_BGR24,
770                                                                    SWS_BICUBIC,
771                                                                    NULL, NULL, NULL
772                                                                   );
773
774               if (img_convert_ctx == NULL)
775                   CV_Error(0, "Cannot initialize the conversion context!");
776
777               sws_scale(
778                           img_convert_ctx,
779                           picture->data,
780                           picture->linesize,
781                           0, video_st->codec->height,
782                           rgb_picture.data,
783                           rgb_picture.linesize
784                        );
785
786               sws_freeContext(img_convert_ctx);
787
788
789
790      frame_number++;
791
792     *data = frame.data;
793     *step = frame.step;
794     *width = frame.width;
795     *height = frame.height;
796     *cn = frame.cn;
797
798     return true;
799 }
800
801 #if defined(__APPLE__)
802 #define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
803 #else
804 #define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE)
805 #endif
806
807 double CvCapture_FFMPEG::getProperty( int property_id )
808 {
809     // if( !capture || !video_st || !picture->data[0] ) return 0;
810     if( !video_st ) return 0;
811
812     // double frameScale = av_q2d (video_st->time_base) * av_q2d (video_st->r_frame_rate);
813     int64_t timestamp;
814     timestamp = picture_pts;
815
816     switch( property_id )
817     {
818     case CV_FFMPEG_CAP_PROP_POS_MSEC:
819         return 1000.0*static_cast<int>(frame_number)/static_cast<int>(get_fps());
820         break;
821     case CV_FFMPEG_CAP_PROP_POS_FRAMES:
822         return (double)static_cast<int>(frame_number);
823         break;
824     case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
825         return r2d(ic->streams[video_stream]->time_base);
826         break;
827     case CV_FFMPEG_CAP_PROP_FRAME_COUNT:
828         return (double)static_cast<int>(get_total_frames());
829         break;
830     case CV_FFMPEG_CAP_PROP_FRAME_WIDTH:
831         return (double)frame.width;
832     break;
833     case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT:
834         return (double)frame.height;
835     break;
836     case CV_FFMPEG_CAP_PROP_FPS:
837 #if LIBAVCODEC_BUILD > 4753
838         return av_q2d (video_st->r_frame_rate);
839 #else
840         return (double)video_st->codec.frame_rate
841             / (double)video_st->codec.frame_rate_base;
842 #endif
843     break;
844     case CV_FFMPEG_CAP_PROP_FOURCC:
845 #if LIBAVFORMAT_BUILD > 4628
846         return (double)video_st->codec->codec_tag;
847 #else
848         return (double)video_st->codec.codec_tag;
849 #endif
850     break;
851     }
852
853     return 0;
854 }
855
856 double CvCapture_FFMPEG::r2d(AVRational r)
857 {
858     if (r.num == 0 || r.den == 0)
859     {
860         return 0.0;
861     }
862     else
863     {
864         return static_cast<double>(r.num) / static_cast<double>(r.den);
865     }
866 }
867
868 double CvCapture_FFMPEG::get_duration_sec()
869 {
870     double sec = static_cast<double>(ic->duration) / static_cast<double>(AV_TIME_BASE);
871
872     if (sec < eps_zero)
873     {
874         sec = static_cast<double>(ic->streams[video_stream]->duration) * r2d(ic->streams[video_stream]->time_base);
875     }
876
877     if (sec < eps_zero)
878     {
879         sec = static_cast<double>(static_cast<int64_t>(ic->streams[video_stream]->duration)) * r2d(ic->streams[video_stream]->time_base);
880     }
881
882     return sec;
883 }
884
885 int CvCapture_FFMPEG::get_bitrate()
886 {
887     return ic->bit_rate;
888 }
889
890 double CvCapture_FFMPEG::get_fps()
891 {
892     double fps = r2d(ic->streams[video_stream]->r_frame_rate);
893
894     if (fps < eps_zero)
895     {
896         fps = r2d(ic->streams[video_stream]->avg_frame_rate);
897     }
898
899     if (fps < eps_zero)
900     {
901         fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base);
902     }
903
904     return fps;
905 }
906
907 int64_t CvCapture_FFMPEG::get_total_frames()
908 {
909     int64_t nbf = ic->streams[video_stream]->nb_frames;
910
911     if (nbf == 0)
912     {
913         nbf = static_cast<int64_t>(get_duration_sec() * get_fps());
914     }
915     return nbf;
916 }
917
918 int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts)
919 {
920     double sec = dts_to_sec(dts);
921     return static_cast<int64_t>(get_fps() * sec);
922 }
923
924 double CvCapture_FFMPEG::dts_to_sec(int64_t dts)
925 {
926     return static_cast<double>(dts - ic->streams[video_stream]->start_time) * r2d(ic->streams[video_stream]->time_base);
927 }
928
929 void CvCapture_FFMPEG::seek(int64_t frame_number)
930 {
931     frame_number = std::min(frame_number, get_total_frames());
932     int64_t dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
933
934     if (abs(dts - 2 - frame_number) > 16)
935     {
936         double sec = static_cast<double>(frame_number) / static_cast<double>(get_fps());
937         int64_t time_stamp = ic->streams[video_stream]->start_time;
938         double  time_base  = r2d(ic->streams[video_stream]->time_base);
939         time_stamp += static_cast<int64_t>(sec / time_base);
940         av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD);
941     }
942
943     while(dts - 2 < frame_number)
944     {
945         /* cv::Mat imag = read(); */
946         if (!grabFrame()) break;
947
948         dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
949     }
950 }
951
952 void CvCapture_FFMPEG::seek(double sec)
953 {
954     seek(static_cast<int64_t>(sec * get_fps()));
955 }
956
957 // this is a VERY slow fallback function, ONLY used if ffmpeg's av_seek_frame delivers no correct result!
958 bool CvCapture_FFMPEG::slowSeek( int framenumber )
959 {
960     if ( framenumber>picture_pts )
961     {
962         while ( picture_pts<framenumber )
963             if ( !grabFrame() ) return false;
964     }
965     else if ( framenumber<picture_pts )
966     {
967         reopen();
968         while ( picture_pts<framenumber )
969             if ( !grabFrame() ) return false;
970     }
971     return true;
972 }
973
974 bool CvCapture_FFMPEG::setProperty( int property_id, double value )
975 {
976     if( !video_st ) return false;
977
978     switch( property_id )
979     {
980     case CV_FFMPEG_CAP_PROP_POS_MSEC:
981     case CV_FFMPEG_CAP_PROP_POS_FRAMES:
982     case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
983         {
984             switch( property_id )
985             {
986             case CV_FFMPEG_CAP_PROP_POS_FRAMES:
987                 seek((int64_t)value);
988                 break;
989
990             case CV_FFMPEG_CAP_PROP_POS_MSEC:
991                 seek(value/1000.0);
992                 break;
993
994             case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
995                 seek((int64_t)(value*ic->duration));
996                 break;
997             }
998
999             picture_pts=(int64_t)value;
1000         }
1001         break;
1002     default:
1003         return false;
1004     }
1005
1006     return true;
1007 }
1008
1009
1010 ///////////////// FFMPEG CvVideoWriter implementation //////////////////////////
1011 struct CvVideoWriter_FFMPEG
1012 {
1013     bool open( const char* filename, int fourcc,
1014         double fps, int width, int height, bool isColor );
1015     void close();
1016     bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin );
1017
1018     void init();
1019
1020     AVOutputFormat      * fmt;
1021     AVFormatContext * oc;
1022     uint8_t         * outbuf;
1023     uint32_t          outbuf_size;
1024     FILE            * outfile;
1025     AVFrame         * picture;
1026     AVFrame         * input_picture;
1027     uint8_t         * picbuf;
1028     AVStream        * video_st;
1029     int               input_pix_fmt;
1030     Image_FFMPEG      temp_image;
1031 #if defined(HAVE_FFMPEG_SWSCALE)
1032     struct SwsContext *img_convert_ctx;
1033 #endif
1034 };
1035
1036 static const char * icvFFMPEGErrStr(int err)
1037 {
1038 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1039     switch(err) {
1040         case AVERROR_BSF_NOT_FOUND:
1041             return "Bitstream filter not found";
1042         case AVERROR_DECODER_NOT_FOUND:
1043             return "Decoder not found";
1044         case AVERROR_DEMUXER_NOT_FOUND:
1045             return "Demuxer not found";
1046         case AVERROR_ENCODER_NOT_FOUND:
1047             return "Encoder not found";
1048         case AVERROR_EOF:
1049             return "End of file";
1050         case AVERROR_EXIT:
1051             return "Immediate exit was requested; the called function should not be restarted";
1052         case AVERROR_FILTER_NOT_FOUND:
1053             return "Filter not found";
1054         case AVERROR_INVALIDDATA:
1055             return "Invalid data found when processing input";
1056         case AVERROR_MUXER_NOT_FOUND:
1057             return "Muxer not found";
1058         case AVERROR_OPTION_NOT_FOUND:
1059             return "Option not found";
1060         case AVERROR_PATCHWELCOME:
1061             return "Not yet implemented in FFmpeg, patches welcome";
1062         case AVERROR_PROTOCOL_NOT_FOUND:
1063             return "Protocol not found";
1064         case AVERROR_STREAM_NOT_FOUND:
1065             return "Stream not found";
1066         default:
1067             break;
1068     }
1069 #else
1070     switch(err) {
1071     case AVERROR_NUMEXPECTED:
1072         return "Incorrect filename syntax";
1073     case AVERROR_INVALIDDATA:
1074         return "Invalid data in header";
1075     case AVERROR_NOFMT:
1076         return "Unknown format";
1077     case AVERROR_IO:
1078         return "I/O error occurred";
1079     case AVERROR_NOMEM:
1080         return "Memory allocation error";
1081     default:
1082         break;
1083     }
1084 #endif
1085
1086     return "Unspecified error";
1087 }
1088
1089 /* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/
1090 extern "C" {
1091     enum CodecID codec_get_bmp_id(unsigned int tag);
1092 }
1093
1094 void CvVideoWriter_FFMPEG::init()
1095 {
1096     fmt = 0;
1097     oc = 0;
1098     outbuf = 0;
1099     outbuf_size = 0;
1100     outfile = 0;
1101     picture = 0;
1102     input_picture = 0;
1103     picbuf = 0;
1104     video_st = 0;
1105     input_pix_fmt = 0;
1106     memset(&temp_image, 0, sizeof(temp_image));
1107         #if defined(HAVE_FFMPEG_SWSCALE)
1108                 img_convert_ctx = 0;
1109         #endif
1110 }
1111
1112 /**
1113  * the following function is a modified version of code
1114  * found in ffmpeg-0.4.9-pre1/output_example.c
1115  */
1116 static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc)
1117 {
1118     AVFrame * picture;
1119     uint8_t * picture_buf;
1120     int size;
1121
1122     picture = avcodec_alloc_frame();
1123     if (!picture)
1124         return NULL;
1125     size = avpicture_get_size( (PixelFormat) pix_fmt, width, height);
1126     if(alloc){
1127         picture_buf = (uint8_t *) malloc(size);
1128         if (!picture_buf)
1129         {
1130             av_free(picture);
1131             return NULL;
1132         }
1133         avpicture_fill((AVPicture *)picture, picture_buf,
1134                 (PixelFormat) pix_fmt, width, height);
1135     }
1136     else {
1137     }
1138     return picture;
1139 }
1140
1141 /* add a video output stream to the container */
1142 static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
1143                                              CodecID codec_id,
1144                                              int w, int h, int bitrate,
1145                                              double fps, int pixel_format)
1146 {
1147     AVCodecContext *c;
1148     AVStream *st;
1149     int frame_rate, frame_rate_base;
1150     AVCodec *codec;
1151
1152
1153     st = av_new_stream(oc, 0);
1154     if (!st) {
1155         CV_WARN("Could not allocate stream");
1156         return NULL;
1157     }
1158
1159         #if LIBAVFORMAT_BUILD > 4628
1160                 c = st->codec;
1161         #else
1162                 c = &(st->codec);
1163         #endif
1164
1165         #if LIBAVFORMAT_BUILD > 4621
1166                 c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
1167         #else
1168                 c->codec_id = oc->oformat->video_codec;
1169         #endif
1170
1171     if(codec_id != CODEC_ID_NONE){
1172         c->codec_id = codec_id;
1173     }
1174
1175     //if(codec_tag) c->codec_tag=codec_tag;
1176     codec = avcodec_find_encoder(c->codec_id);
1177
1178     c->codec_type = AVMEDIA_TYPE_VIDEO;
1179
1180     /* put sample parameters */
1181     c->bit_rate = bitrate;
1182
1183     /* resolution must be a multiple of two */
1184     c->width = w;
1185     c->height = h;
1186
1187     /* time base: this is the fundamental unit of time (in seconds) in terms
1188        of which frame timestamps are represented. for fixed-fps content,
1189        timebase should be 1/framerate and timestamp increments should be
1190        identically 1. */
1191     frame_rate=(int)(fps+0.5);
1192     frame_rate_base=1;
1193     while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){
1194         frame_rate_base*=10;
1195         frame_rate=(int)(fps*frame_rate_base + 0.5);
1196     }
1197         #if LIBAVFORMAT_BUILD > 4752
1198                 c->time_base.den = frame_rate;
1199                 c->time_base.num = frame_rate_base;
1200                 /* adjust time base for supported framerates */
1201                 if(codec && codec->supported_framerates){
1202                         const AVRational *p= codec->supported_framerates;
1203                         AVRational req = {frame_rate, frame_rate_base};
1204                         const AVRational *best=NULL;
1205                         AVRational best_error= {INT_MAX, 1};
1206                         for(; p->den!=0; p++){
1207                                 AVRational error= av_sub_q(req, *p);
1208                                 if(error.num <0) error.num *= -1;
1209                                 if(av_cmp_q(error, best_error) < 0){
1210                                         best_error= error;
1211                                         best= p;
1212                                 }
1213                         }
1214                         c->time_base.den= best->num;
1215                         c->time_base.num= best->den;
1216                 }
1217         #else
1218                 c->frame_rate = frame_rate;
1219                 c->frame_rate_base = frame_rate_base;
1220         #endif
1221
1222     c->gop_size = 12; /* emit one intra frame every twelve frames at most */
1223     c->pix_fmt = (PixelFormat) pixel_format;
1224
1225     if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
1226         c->max_b_frames = 2;
1227     }
1228     if (c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MSMPEG4V3){
1229         /* needed to avoid using macroblocks in which some coeffs overflow
1230            this doesnt happen with normal video, it just happens here as the
1231            motion of the chroma plane doesnt match the luma plane */
1232         /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */
1233         c->mb_decision=2;
1234     }
1235         #if LIBAVCODEC_VERSION_INT>0x000409
1236                 // some formats want stream headers to be seperate
1237                 if(oc->oformat->flags & AVFMT_GLOBALHEADER)
1238                 {
1239                         c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1240                 }
1241         #endif
1242
1243     return st;
1244 }
1245
1246 int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture )
1247 {
1248         #if LIBAVFORMAT_BUILD > 4628
1249                 AVCodecContext * c = video_st->codec;
1250         #else
1251                 AVCodecContext * c = &(video_st->codec);
1252         #endif
1253     int out_size;
1254     int ret;
1255
1256     if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1257         /* raw video case. The API will change slightly in the near
1258            futur for that */
1259         AVPacket pkt;
1260         av_init_packet(&pkt);
1261
1262         #ifndef PKT_FLAG_KEY
1263             #define PKT_FLAG_KEY AV_PKT_FLAG_KEY
1264         #endif
1265
1266         pkt.flags |= PKT_FLAG_KEY;
1267         pkt.stream_index= video_st->index;
1268         pkt.data= (uint8_t *)picture;
1269         pkt.size= sizeof(AVPicture);
1270
1271         ret = av_write_frame(oc, &pkt);
1272     } else {
1273         /* encode the image */
1274         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
1275         /* if zero size, it means the image was buffered */
1276         if (out_size > 0) {
1277             AVPacket pkt;
1278             av_init_packet(&pkt);
1279
1280         #if LIBAVFORMAT_BUILD > 4752
1281                                 pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
1282         #else
1283                                 pkt.pts = c->coded_frame->pts;
1284         #endif
1285             if(c->coded_frame->key_frame)
1286                 pkt.flags |= PKT_FLAG_KEY;
1287             pkt.stream_index= video_st->index;
1288             pkt.data= outbuf;
1289             pkt.size= out_size;
1290
1291             /* write the compressed frame in the media file */
1292             ret = av_write_frame(oc, &pkt);
1293         } else {
1294             ret = 0;
1295         }
1296     }
1297     if (ret != 0) return -1;
1298
1299     return 0;
1300 }
1301
1302 /// write a frame with FFMPEG
1303 bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin )
1304 {
1305     bool ret = false;
1306
1307     // typecast from opaque data type to implemented struct
1308         #if LIBAVFORMAT_BUILD > 4628
1309                 AVCodecContext *c = video_st->codec;
1310         #else
1311                 AVCodecContext *c = &(video_st->codec);
1312         #endif
1313
1314         #if LIBAVFORMAT_BUILD < 5231
1315                 // It is not needed in the latest versions of the ffmpeg
1316                 if( c->codec_id == CODEC_ID_RAWVIDEO && origin != 1 )
1317                 {
1318                         if( !temp_image.data )
1319                         {
1320                                 temp_image.step = (width*cn + 3) & -4;
1321                                 temp_image.width = width;
1322                                 temp_image.height = height;
1323                                 temp_image.cn = cn;
1324                                 temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
1325                         }
1326                         for( int y = 0; y < height; y++ )
1327                                 memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn);
1328                         data = temp_image.data;
1329                         step = temp_image.step;
1330                 }
1331         #else
1332                 if( width*cn != step )
1333                 {
1334                         if( !temp_image.data )
1335                         {
1336                                 temp_image.step = width*cn;
1337                                 temp_image.width = width;
1338                                 temp_image.height = height;
1339                                 temp_image.cn = cn;
1340                                 temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
1341                         }
1342                         if (origin == 1)
1343                                 for( int y = 0; y < height; y++ )
1344                                         memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step);
1345                         else
1346                                 for( int y = 0; y < height; y++ )
1347                                         memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step);
1348                         data = temp_image.data;
1349                         step = temp_image.step;
1350                 }
1351         #endif
1352
1353     // check parameters
1354     if (input_pix_fmt == PIX_FMT_BGR24) {
1355         if (cn != 3) {
1356             return false;
1357         }
1358     }
1359     else if (input_pix_fmt == PIX_FMT_GRAY8) {
1360         if (cn != 1) {
1361             return false;
1362         }
1363     }
1364     else {
1365         assert(false);
1366     }
1367
1368     if ( c->pix_fmt != input_pix_fmt ) {
1369         assert( input_picture );
1370         // let input_picture point to the raw data buffer of 'image'
1371         avpicture_fill((AVPicture *)input_picture, (uint8_t *) data,
1372                 (PixelFormat)input_pix_fmt, width, height);
1373
1374 #if !defined(HAVE_FFMPEG_SWSCALE)
1375         // convert to the color format needed by the codec
1376         if( img_convert((AVPicture *)picture, c->pix_fmt,
1377                     (AVPicture *)input_picture, (PixelFormat)input_pix_fmt,
1378                     width, height) < 0){
1379             return false;
1380         }
1381 #else
1382         img_convert_ctx = sws_getContext(width,
1383                      height,
1384                      (PixelFormat)input_pix_fmt,
1385                      c->width,
1386                      c->height,
1387                      c->pix_fmt,
1388                      SWS_BICUBIC,
1389                      NULL, NULL, NULL);
1390
1391             if ( sws_scale(img_convert_ctx, input_picture->data,
1392                      input_picture->linesize, 0,
1393                      height,
1394                      picture->data, picture->linesize) < 0 )
1395             {
1396                return false;
1397             }
1398         sws_freeContext(img_convert_ctx);
1399 #endif
1400     }
1401     else{
1402         avpicture_fill((AVPicture *)picture, (uint8_t *) data,
1403                 (PixelFormat)input_pix_fmt, width, height);
1404     }
1405
1406     ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0;
1407
1408     return ret;
1409 }
1410
1411 /// close video output stream and free associated memory
1412 void CvVideoWriter_FFMPEG::close()
1413 {
1414     unsigned i;
1415
1416     // nothing to do if already released
1417     if ( !picture )
1418         return;
1419
1420     /* no more frame to compress. The codec has a latency of a few
1421        frames if using B frames, so we get the last frames by
1422        passing the same picture again */
1423     // TODO -- do we need to account for latency here?
1424
1425     /* write the trailer, if any */
1426     av_write_trailer(oc);
1427
1428     // free pictures
1429         #if LIBAVFORMAT_BUILD > 4628
1430                 if( video_st->codec->pix_fmt != input_pix_fmt){
1431         #else
1432                 if( video_st->codec.pix_fmt != input_pix_fmt){
1433         #endif
1434         if(picture->data[0])
1435            free(picture->data[0]);
1436         picture->data[0] = 0;
1437     }
1438     av_free(picture);
1439
1440     if (input_picture) {
1441         av_free(input_picture);
1442     }
1443
1444     /* close codec */
1445         #if LIBAVFORMAT_BUILD > 4628
1446                 avcodec_close(video_st->codec);
1447         #else
1448                 avcodec_close(&(video_st->codec));
1449         #endif
1450
1451     av_free(outbuf);
1452
1453     /* free the streams */
1454     for(i = 0; i < oc->nb_streams; i++) {
1455         av_freep(&oc->streams[i]->codec);
1456         av_freep(&oc->streams[i]);
1457     }
1458
1459     if (!(fmt->flags & AVFMT_NOFILE)) {
1460         /* close the output file */
1461
1462         #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
1463         #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1464                         url_fclose(oc->pb);
1465         #else
1466                         url_fclose(&oc->pb);
1467         #endif
1468         #else
1469                         avio_close(oc->pb);
1470         #endif
1471
1472     }
1473
1474     /* free the stream */
1475     av_free(oc);
1476
1477     if( temp_image.data )
1478     {
1479         free(temp_image.data);
1480         temp_image.data = 0;
1481     }
1482
1483     init();
1484 }
1485
1486 /// Create a video writer object that uses FFMPEG
1487 bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
1488         double fps, int width, int height, bool is_color )
1489 {
1490     CodecID codec_id = CODEC_ID_NONE;
1491     int err, codec_pix_fmt, bitrate_scale=64;
1492
1493     close();
1494
1495     // check arguments
1496     assert (filename);
1497     assert (fps > 0);
1498     assert (width > 0  &&  height > 0);
1499
1500     // tell FFMPEG to register codecs
1501     av_register_all ();
1502
1503     /* auto detect the output format from the name and fourcc code. */
1504
1505         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1506                 fmt = av_guess_format(NULL, filename, NULL);
1507         #else
1508                 fmt = guess_format(NULL, filename, NULL);
1509         #endif
1510
1511     if (!fmt)
1512         return false;
1513
1514     /* determine optimal pixel format */
1515     if (is_color) {
1516         input_pix_fmt = PIX_FMT_BGR24;
1517     }
1518     else {
1519         input_pix_fmt = PIX_FMT_GRAY8;
1520     }
1521
1522     /* Lookup codec_id for given fourcc */
1523         #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
1524                 if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE )
1525                         return false;
1526         #else
1527                 const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
1528                 if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE )
1529                         return false;
1530         #endif
1531
1532     // alloc memory for context
1533         #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1534                 oc = avformat_alloc_context();
1535         #else
1536                 oc = av_alloc_format_context();
1537         #endif
1538     assert (oc);
1539
1540     /* set file name */
1541     oc->oformat = fmt;
1542     snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
1543
1544     /* set some options */
1545     oc->max_delay = (int)(0.7*AV_TIME_BASE);  /* This reduces buffer underrun warnings with MPEG */
1546
1547     // set a few optimal pixel formats for lossless codecs of interest..
1548     switch (codec_id) {
1549         #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
1550                 case CODEC_ID_JPEGLS:
1551                         // BGR24 or GRAY8 depending on is_color...
1552                         codec_pix_fmt = input_pix_fmt;
1553                         break;
1554         #endif
1555     case CODEC_ID_HUFFYUV:
1556         codec_pix_fmt = PIX_FMT_YUV422P;
1557         break;
1558     case CODEC_ID_MJPEG:
1559     case CODEC_ID_LJPEG:
1560       codec_pix_fmt = PIX_FMT_YUVJ420P;
1561       bitrate_scale = 128;
1562       break;
1563     case CODEC_ID_RAWVIDEO:
1564       codec_pix_fmt = input_pix_fmt;
1565       break;
1566     default:
1567         // good for lossy formats, MPEG, etc.
1568         codec_pix_fmt = PIX_FMT_YUV420P;
1569         break;
1570     }
1571
1572     // TODO -- safe to ignore output audio stream?
1573     video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
1574             width, height, width*height*bitrate_scale,
1575             fps, codec_pix_fmt);
1576
1577
1578     /* set the output parameters (must be done even if no
1579        parameters). */
1580         #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1581                 if (av_set_parameters(oc, NULL) < 0)
1582         #else
1583                 if (avformat_write_header(oc, NULL) < 0)
1584         #endif
1585         {
1586         return false;
1587     }
1588
1589         #if FF_API_DUMP_FORMAT
1590                 dump_format(oc, 0, filename, 1);
1591         #else
1592                 av_dump_format(oc, 0, filename, 1);
1593         #endif
1594
1595     /* now that all the parameters are set, we can open the audio and
1596        video codecs and allocate the necessary encode buffers */
1597     if (!video_st){
1598         return false;
1599     }
1600
1601     AVCodec *codec;
1602     AVCodecContext *c;
1603
1604         #if LIBAVFORMAT_BUILD > 4628
1605                 c = (video_st->codec);
1606         #else
1607                 c = &(video_st->codec);
1608         #endif
1609
1610     c->codec_tag = fourcc;
1611     /* find the video encoder */
1612     codec = avcodec_find_encoder(c->codec_id);
1613     if (!codec) {
1614         return false;
1615     }
1616
1617     c->bit_rate_tolerance = c->bit_rate;
1618
1619     /* open the codec */
1620     if ( (err=avcodec_open(c, codec)) < 0) {
1621         char errtext[256];
1622         sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err));
1623         return false;
1624     }
1625
1626     outbuf = NULL;
1627
1628     if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
1629         /* allocate output buffer */
1630         /* assume we will never get codec output with more than 4 bytes per pixel... */
1631         outbuf_size = width*height*4;
1632         outbuf = (uint8_t *) av_malloc(outbuf_size);
1633     }
1634
1635     bool need_color_convert;
1636     need_color_convert = (c->pix_fmt != input_pix_fmt);
1637
1638     /* allocate the encoded raw picture */
1639     picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert);
1640     if (!picture) {
1641         return false;
1642     }
1643
1644     /* if the output format is not our input format, then a temporary
1645        picture of the input format is needed too. It is then converted
1646        to the required output format */
1647     input_picture = NULL;
1648     if ( need_color_convert ) {
1649         input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false);
1650         if (!input_picture) {
1651             return false;
1652         }
1653     }
1654
1655     /* open the output file, if needed */
1656     if (!(fmt->flags & AVFMT_NOFILE)) {
1657         #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
1658                         if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
1659         #else
1660                                 if (avio_open(&oc->pb, filename, 1) < 0)
1661         #endif
1662         {
1663             return false;
1664         }
1665     }
1666
1667     /* write the stream header, if any */
1668     avformat_write_header(oc, NULL);
1669
1670     return true;
1671 }
1672
1673
1674
1675 CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
1676 {
1677     CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture));
1678     capture->init();
1679     if( capture->open( filename ))
1680         return capture;
1681     capture->close();
1682     free(capture);
1683     return 0;
1684 }
1685
1686
1687 void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture)
1688 {
1689     if( capture && *capture )
1690     {
1691         (*capture)->close();
1692         free(*capture);
1693         *capture = 0;
1694     }
1695 }
1696
1697 int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value)
1698 {
1699     return capture->setProperty(prop_id, value);
1700 }
1701
1702 double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id)
1703 {
1704     return capture->getProperty(prop_id);
1705 }
1706
1707 int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture)
1708 {
1709     return capture->grabFrame();
1710 }
1711
1712 int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn)
1713 {
1714     return capture->retrieveFrame(0, data, step, width, height, cn);
1715 }
1716
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
1732 void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
1733 {
1734     if( writer && *writer )
1735     {
1736         (*writer)->close();
1737         free(*writer);
1738         *writer = 0;
1739     }
1740 }
1741
1742
1743 int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer,
1744                          const unsigned char* data, int step,
1745                          int width, int height, int cn, int origin)
1746 {
1747     return writer->writeFrame(data, step, width, height, cn, origin);
1748 }
1749