1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
44 #if defined _MSC_VER && _MSC_VER >= 1200
45 #pragma warning( disable: 4244 4510 4512 4610 )
49 #if !defined(WIN32) || defined(__MINGW32__)
50 // some versions of FFMPEG assume a C99 compiler, and don't define INT64_C
53 #define __STDC_CONSTANT_MACROS
54 // force re-inclusion of stdint.h to get INT64_C macro
62 #include <ffmpeg_/avformat.h>
63 #include <ffmpeg_/avcodec.h>
64 #include <ffmpeg_/imgconvert.h>
67 // if the header path is not specified explicitly, let's deduce it
68 #if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H
70 #if defined(HAVE_GENTOO_FFMPEG)
71 #define HAVE_LIBAVCODEC_AVCODEC_H 1
72 #define HAVE_LIBAVFORMAT_AVFORMAT_H 1
73 #if defined(HAVE_FFMPEG_SWSCALE)
74 #define HAVE_LIBSWSCALE_SWSCALE_H 1
76 #elif defined HAVE_FFMPEG
77 #define HAVE_FFMPEG_AVCODEC_H 1
78 #define HAVE_FFMPEG_AVFORMAT_H 1
79 #if defined(HAVE_FFMPEG_SWSCALE)
80 #define HAVE_FFMPEG_SWSCALE_H 1
86 #if defined(HAVE_FFMPEG_AVCODEC_H)
87 #include <ffmpeg/avcodec.h>
89 #if defined(HAVE_FFMPEG_AVFORMAT_H)
90 #include <ffmpeg/avformat.h>
92 #if defined(HAVE_FFMPEG_SWSCALE_H)
93 #include <ffmpeg/swscale.h>
96 #if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
97 #include <libavformat/avformat.h>
99 #if defined(HAVE_LIBAVCODEC_AVCODEC_H)
100 #include <libavcodec/avcodec.h>
102 #if defined(HAVE_LIBSWSCALE_SWSCALE_H)
103 #include <libswscale/swscale.h>
110 #if defined _MSC_VER && _MSC_VER >= 1200
111 #pragma warning( default: 4244 4510 4512 4610 )
115 #define CV_WARN(message)
117 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
122 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
125 /* PIX_FMT_RGBA32 macro changed in newer ffmpeg versions */
126 #ifndef PIX_FMT_RGBA32
127 #define PIX_FMT_RGBA32 PIX_FMT_RGB32
132 char * FOURCC2str( int fourcc )
134 char * mystr=(char*)malloc(5);
135 mystr[0]=(char)((fourcc )&255);
136 mystr[1]=(char)((fourcc>> 8)&255);
137 mystr[2]=(char)((fourcc>>16)&255);
138 mystr[3]=(char)((fourcc>>24)&255);
144 // required to look up the correct codec ID depending on the FOURCC code,
145 // this is just a snipped from the file riff.c from ffmpeg/libavformat
146 typedef struct AVCodecTag {
151 const AVCodecTag codec_bmp_tags[] = {
152 { CODEC_ID_H264, MKTAG('H', '2', '6', '4') },
153 { CODEC_ID_H264, MKTAG('h', '2', '6', '4') },
154 { CODEC_ID_H264, MKTAG('X', '2', '6', '4') },
155 { CODEC_ID_H264, MKTAG('x', '2', '6', '4') },
156 { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
157 { CODEC_ID_H264, MKTAG('V', 'S', 'S', 'H') },
159 { CODEC_ID_H263, MKTAG('H', '2', '6', '3') },
160 { CODEC_ID_H263P, MKTAG('H', '2', '6', '3') },
161 { CODEC_ID_H263I, MKTAG('I', '2', '6', '3') }, /* intel h263 */
162 { CODEC_ID_H261, MKTAG('H', '2', '6', '1') },
164 /* added based on MPlayer */
165 { CODEC_ID_H263P, MKTAG('U', '2', '6', '3') },
166 { CODEC_ID_H263P, MKTAG('v', 'i', 'v', '1') },
168 { CODEC_ID_MPEG4, MKTAG('F', 'M', 'P', '4') },
169 { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') },
170 { CODEC_ID_MPEG4, MKTAG('D', 'X', '5', '0') },
171 { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
172 { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
173 { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') },
174 { CODEC_ID_MPEG4, MKTAG(0x04, 0, 0, 0) }, /* some broken avi use this */
176 /* added based on MPlayer */
177 { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', '1') },
178 { CODEC_ID_MPEG4, MKTAG('B', 'L', 'Z', '0') },
179 { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
180 { CODEC_ID_MPEG4, MKTAG('U', 'M', 'P', '4') },
181 { CODEC_ID_MPEG4, MKTAG('W', 'V', '1', 'F') },
182 { CODEC_ID_MPEG4, MKTAG('S', 'E', 'D', 'G') },
184 { CODEC_ID_MPEG4, MKTAG('R', 'M', 'P', '4') },
186 { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') }, /* default signature when using MSMPEG4 */
187 { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
189 /* added based on MPlayer */
190 { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') },
191 { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '5') },
192 { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '6') },
193 { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '4') },
194 { CODEC_ID_MSMPEG4V3, MKTAG('A', 'P', '4', '1') },
195 { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '1') },
196 { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '0') },
198 { CODEC_ID_MSMPEG4V2, MKTAG('M', 'P', '4', '2') },
200 /* added based on MPlayer */
201 { CODEC_ID_MSMPEG4V2, MKTAG('D', 'I', 'V', '2') },
203 { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', 'G', '4') },
205 { CODEC_ID_WMV1, MKTAG('W', 'M', 'V', '1') },
207 /* added based on MPlayer */
208 { CODEC_ID_WMV2, MKTAG('W', 'M', 'V', '2') },
209 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'd') },
210 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'd') },
211 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'l') },
212 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '2', '5') },
213 { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') },
214 { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') },
215 { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', '2') },
216 { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'P', 'E', 'G') },
217 { CODEC_ID_MPEG1VIDEO, MKTAG('P', 'I', 'M', '1') },
218 { CODEC_ID_MPEG1VIDEO, MKTAG('V', 'C', 'R', '2') },
219 { CODEC_ID_MPEG1VIDEO, 0x10000001 },
220 { CODEC_ID_MPEG2VIDEO, 0x10000002 },
221 { CODEC_ID_MPEG2VIDEO, MKTAG('D', 'V', 'R', ' ') },
222 { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'M', 'E', 'S') },
223 { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') },
224 { CODEC_ID_MJPEG, MKTAG('L', 'J', 'P', 'G') },
225 { CODEC_ID_LJPEG, MKTAG('L', 'J', 'P', 'G') },
226 { CODEC_ID_MJPEG, MKTAG('J', 'P', 'G', 'L') }, /* Pegasus lossless JPEG */
227 { CODEC_ID_MJPEG, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
228 { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') },
229 { CODEC_ID_MJPEG, MKTAG('I', 'J', 'P', 'G') },
230 { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') },
231 { CODEC_ID_HUFFYUV, MKTAG('H', 'F', 'Y', 'U') },
232 { CODEC_ID_FFVHUFF, MKTAG('F', 'F', 'V', 'H') },
233 { CODEC_ID_CYUV, MKTAG('C', 'Y', 'U', 'V') },
234 { CODEC_ID_RAWVIDEO, 0 },
235 { CODEC_ID_RAWVIDEO, MKTAG('I', '4', '2', '0') },
236 { CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'Y', '2') },
237 { CODEC_ID_RAWVIDEO, MKTAG('Y', '4', '2', '2') },
238 { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '2') },
239 { CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'V', 'Y') },
240 { CODEC_ID_RAWVIDEO, MKTAG('I', 'Y', 'U', 'V') },
241 { CODEC_ID_RAWVIDEO, MKTAG('Y', '8', '0', '0') },
242 { CODEC_ID_RAWVIDEO, MKTAG('H', 'D', 'Y', 'C') },
243 { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') },
244 { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') },
245 { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
246 { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') },
247 { CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') },
248 { CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') },
249 { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') },
250 { CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
251 { CODEC_ID_XAN_WC4, MKTAG('X', 'x', 'a', 'n') },
252 { CODEC_ID_MSRLE, MKTAG('m', 'r', 'l', 'e') },
253 { CODEC_ID_MSRLE, MKTAG(0x1, 0x0, 0x0, 0x0) },
254 { CODEC_ID_MSVIDEO1, MKTAG('M', 'S', 'V', 'C') },
255 { CODEC_ID_MSVIDEO1, MKTAG('m', 's', 'v', 'c') },
256 { CODEC_ID_MSVIDEO1, MKTAG('C', 'R', 'A', 'M') },
257 { CODEC_ID_MSVIDEO1, MKTAG('c', 'r', 'a', 'm') },
258 { CODEC_ID_MSVIDEO1, MKTAG('W', 'H', 'A', 'M') },
259 { CODEC_ID_MSVIDEO1, MKTAG('w', 'h', 'a', 'm') },
260 { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') },
261 { CODEC_ID_TRUEMOTION1, MKTAG('D', 'U', 'C', 'K') },
262 { CODEC_ID_MSZH, MKTAG('M', 'S', 'Z', 'H') },
263 { CODEC_ID_ZLIB, MKTAG('Z', 'L', 'I', 'B') },
264 { CODEC_ID_SNOW, MKTAG('S', 'N', 'O', 'W') },
265 { CODEC_ID_4XM, MKTAG('4', 'X', 'M', 'V') },
266 { CODEC_ID_FLV1, MKTAG('F', 'L', 'V', '1') },
267 { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') },
268 { CODEC_ID_TSCC, MKTAG('t', 's', 'c', 'c') },
269 { CODEC_ID_ULTI, MKTAG('U', 'L', 'T', 'I') },
270 { CODEC_ID_VIXL, MKTAG('V', 'I', 'X', 'L') },
271 { CODEC_ID_QPEG, MKTAG('Q', 'P', 'E', 'G') },
272 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
273 { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
274 { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
275 { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
276 { CODEC_ID_THEORA, MKTAG('t', 'h', 'e', 'o') },
277 #if LIBAVCODEC_VERSION_INT>0x000409
278 { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
279 { CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },
280 { CODEC_ID_INDEO2, MKTAG('R', 'T', '2', '1') },
281 { CODEC_ID_FRAPS, MKTAG('F', 'P', 'S', '1') },
282 { CODEC_ID_TRUEMOTION2, MKTAG('T', 'M', '2', '0') },
284 #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
285 { CODEC_ID_FLASHSV, MKTAG('F', 'S', 'V', '1') },
286 { CODEC_ID_JPEGLS,MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - encoder */
287 { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
288 { CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },
289 { CODEC_ID_CSCD, MKTAG('C', 'S', 'C', 'D') },
290 { CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') },
291 { CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') },
293 #if LIBAVCODEC_VERSION_INT>((51<<16)+(11<<8)+0)
294 { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
295 { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') },
296 { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') },
297 { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
298 { CODEC_ID_VP6F, MKTAG('V', 'P', '6', 'F') },
299 { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
300 { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
302 #if LIBAVCODEC_VERSION_INT>=((51<<16)+(49<<8)+0)
303 // this tag seems not to exist in older versions of FFMPEG
304 { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
306 { CODEC_ID_NONE, 0 },
310 class CvCapture_FFMPEG : public CvCapture
313 CvCapture_FFMPEG() { init(); }
314 virtual ~CvCapture_FFMPEG() { close(); }
316 virtual bool open( const char* filename );
317 virtual void close();
319 virtual double getProperty(int);
320 virtual bool setProperty(int, double);
321 virtual bool grabFrame();
322 virtual IplImage* retrieveFrame(int);
327 bool slowSeek( int framenumber );
329 AVFormatContext * ic;
337 #if defined(HAVE_FFMPEG_SWSCALE)
338 struct SwsContext *img_convert_ctx;
341 'filename' contains the filename of the videosource,
342 'filename==NULL' indicates that ffmpeg's seek support works
343 for the particular file.
344 'filename!=NULL' indicates that the slow fallback function is used for seeking,
345 and so the filename is needed to reopen the file on backward seeking.
351 void CvCapture_FFMPEG::init()
358 memset( &rgb_picture, 0, sizeof(rgb_picture) );
359 memset( &frame, 0, sizeof(frame) );
362 #if defined(HAVE_FFMPEG_SWSCALE)
368 void CvCapture_FFMPEG::close()
375 #if LIBAVFORMAT_BUILD > 4628
376 avcodec_close( video_st->codec );
378 avcodec_close( &video_st->codec );
385 av_close_input_file(ic);
389 if( rgb_picture.data[0] )
390 cvFree( &rgb_picture.data[0] );
392 // free last packet if exist
394 av_free_packet (&packet);
403 Used to reopen a video if the slower fallback function for seeking is used.
405 bool CvCapture_FFMPEG::reopen()
407 if ( filename==NULL ) return false;
409 #if LIBAVFORMAT_BUILD > 4628
410 avcodec_close( video_st->codec );
412 avcodec_close( &video_st->codec );
414 av_close_input_file(ic);
417 av_open_input_file(&ic, filename, NULL, 0, NULL);
418 av_find_stream_info(ic);
419 #if LIBAVFORMAT_BUILD > 4628
420 AVCodecContext *enc = ic->streams[video_stream]->codec;
422 AVCodecContext *enc = &ic->streams[video_stream]->codec;
424 AVCodec *codec = avcodec_find_decoder(enc->codec_id);
425 avcodec_open(enc, codec);
426 video_st = ic->streams[video_stream];
428 // reset framenumber to zero
436 bool CvCapture_FFMPEG::open( const char* _filename )
443 /* register all codecs, demux and protocols */
447 // av_log_level = AV_LOG_QUIET;
450 int err = av_open_input_file(&ic, _filename, NULL, 0, NULL);
452 CV_WARN("Error opening file");
455 err = av_find_stream_info(ic);
457 CV_WARN("Could not find codec parameters");
460 for(i = 0; i < ic->nb_streams; i++) {
461 #if LIBAVFORMAT_BUILD > 4628
462 AVCodecContext *enc = ic->streams[i]->codec;
464 AVCodecContext *enc = &ic->streams[i]->codec;
467 if( CODEC_TYPE_VIDEO == enc->codec_type && video_stream < 0) {
468 AVCodec *codec = avcodec_find_decoder(enc->codec_id);
470 avcodec_open(enc, codec) < 0)
473 video_st = ic->streams[i];
474 picture = avcodec_alloc_frame();
476 rgb_picture.data[0] = (uint8_t*)cvAlloc(
477 avpicture_get_size( PIX_FMT_BGR24,
478 enc->width, enc->height ));
479 avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
480 PIX_FMT_BGR24, enc->width, enc->height );
482 cvInitImageHeader( &frame, cvSize( enc->width,
483 enc->height ), 8, 3, 0, 4 );
484 cvSetData( &frame, rgb_picture.data[0],
485 rgb_picture.linesize[0] );
490 if(video_stream >= 0) valid = true;
492 // perform check if source is seekable via ffmpeg's seek function av_seek_frame(...)
493 err = av_seek_frame(ic, video_stream, 10, 0);
496 filename=(char*)malloc(strlen(_filename)+1);
497 strcpy(filename, _filename);
498 // reopen videofile to 'seek' back to first frame
503 // seek seems to work, so we don't need the filename,
504 // but we still need to seek back to filestart
506 av_seek_frame(ic, video_stream, 0, 0);
517 bool CvCapture_FFMPEG::grabFrame()
520 static bool bFirstTime = true;
523 // First time we're called, set packet.data to NULL to indicate it
524 // doesn't have to be freed
530 if( !ic || !video_st )
533 // free last packet if exist
534 if (packet.data != NULL) {
535 av_free_packet (&packet);
538 // get the next frame
539 while (!valid && (av_read_frame(ic, &packet) >= 0)) {
540 if( packet.stream_index != video_stream ) {
541 av_free_packet (&packet);
545 #if LIBAVFORMAT_BUILD > 4628
546 avcodec_decode_video(video_st->codec,
547 picture, &got_picture,
548 packet.data, packet.size);
550 avcodec_decode_video(&video_st->codec,
551 picture, &got_picture,
552 packet.data, packet.size);
556 // we have a new picture, so memorize it
557 picture_pts = packet.pts;
562 // return if we have a new picture or not
567 IplImage* CvCapture_FFMPEG::retrieveFrame(int)
569 if( !video_st || !picture->data[0] )
572 #if !defined(HAVE_FFMPEG_SWSCALE)
573 #if LIBAVFORMAT_BUILD > 4628
574 img_convert( (AVPicture*)&rgb_picture, PIX_FMT_BGR24,
576 video_st->codec->pix_fmt,
577 video_st->codec->width,
578 video_st->codec->height );
580 img_convert( (AVPicture*)&rgb_picture, PIX_FMT_BGR24,
582 video_st->codec.pix_fmt,
583 video_st->codec.width,
584 video_st->codec.height );
587 img_convert_ctx = sws_getContext(video_st->codec->width,
588 video_st->codec->height,
589 video_st->codec->pix_fmt,
590 video_st->codec->width,
591 video_st->codec->height,
596 sws_scale(img_convert_ctx, picture->data,
597 picture->linesize, 0,
598 video_st->codec->height,
599 rgb_picture.data, rgb_picture.linesize);
600 sws_freeContext(img_convert_ctx);
605 #if defined(__APPLE__)
606 #define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
608 #define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE)
611 double CvCapture_FFMPEG::getProperty( int property_id )
613 // if( !capture || !video_st || !picture->data[0] ) return 0;
614 if( !video_st ) return 0;
618 timestamp = picture_pts;
620 switch( property_id )
622 case CV_CAP_PROP_POS_MSEC:
623 if(video_st->parser && video_st->parser->dts != AV_NOPTS_VALUE_)
624 return (((double)video_st->parser->dts-1) *1000.0f) * av_q2d (video_st->time_base);
625 if(video_st->cur_dts != AV_NOPTS_VALUE_)
626 return (((double)video_st->cur_dts-1) *1000.0f * av_q2d (video_st->time_base));
627 // return (((double)video_st->cur_dts-1) *1000) / av_q2d (video_st->r_frame_rate);
629 case CV_CAP_PROP_POS_FRAMES:
630 if(video_st->parser && video_st->parser->dts != AV_NOPTS_VALUE_)
631 return (double)video_st->parser->dts-1;
632 if(video_st->cur_dts != AV_NOPTS_VALUE_)
633 return (double)video_st->cur_dts-1;
635 case CV_CAP_PROP_POS_AVI_RATIO:
636 if(video_st->parser && video_st->parser->dts != AV_NOPTS_VALUE_)
637 return (double)(video_st->parser->dts-1)/(double)video_st->duration;
638 if(video_st->cur_dts != AV_NOPTS_VALUE_ && video_st->duration != AV_NOPTS_VALUE_)
639 return (double)(video_st->cur_dts-1)/(double)video_st->duration;
641 case CV_CAP_PROP_FRAME_COUNT:
642 if(video_st->duration != AV_NOPTS_VALUE_)
643 return (double)video_st->duration;
645 case CV_CAP_PROP_FRAME_WIDTH:
646 return (double)frame.width;
648 case CV_CAP_PROP_FRAME_HEIGHT:
649 return (double)frame.height;
651 case CV_CAP_PROP_FPS:
652 #if LIBAVCODEC_BUILD > 4753
653 return av_q2d (video_st->r_frame_rate);
655 return (double)video_st->codec.frame_rate
656 / (double)video_st->codec.frame_rate_base;
659 case CV_CAP_PROP_FOURCC:
660 #if LIBAVFORMAT_BUILD > 4628
661 return (double)video_st->codec->codec_tag;
663 return (double)video_st->codec.codec_tag;
672 // this is a VERY slow fallback function, ONLY used if ffmpeg's av_seek_frame delivers no correct result!
673 bool CvCapture_FFMPEG::slowSeek( int framenumber )
675 if ( framenumber>picture_pts )
677 while ( picture_pts<framenumber )
678 if ( !grabFrame() ) return false;
680 else if ( framenumber<picture_pts )
683 while ( picture_pts<framenumber )
684 if ( !grabFrame() ) return false;
690 bool CvCapture_FFMPEG::setProperty( int property_id, double value )
692 if( !video_st ) return false;
694 switch( property_id )
696 case CV_CAP_PROP_POS_MSEC:
697 case CV_CAP_PROP_POS_FRAMES:
698 case CV_CAP_PROP_POS_AVI_RATIO:
700 int64_t timestamp = 0;
701 AVRational time_base;
702 switch( property_id )
704 case CV_CAP_PROP_POS_FRAMES:
705 timestamp=(int64_t)value;
706 if(ic->start_time != AV_NOPTS_VALUE_)
707 timestamp += ic->start_time;
710 case CV_CAP_PROP_POS_MSEC:
711 time_base=ic->streams[video_stream]->time_base;
712 timestamp=(int64_t)(value*(float(time_base.den)/float(time_base.num))/1000);
713 if(ic->start_time != AV_NOPTS_VALUE_)
714 timestamp += ic->start_time;
717 case CV_CAP_PROP_POS_AVI_RATIO:
718 timestamp=(int64_t)(value*ic->duration);
719 if(ic->start_time != AV_NOPTS_VALUE_ && ic->duration != AV_NOPTS_VALUE_)
720 timestamp += ic->start_time;
726 // ffmpeg's seek doesn't work...
727 if (!slowSeek((int)timestamp))
729 fprintf(stderr, "HIGHGUI ERROR: AVI: could not (slow) seek to position %0.3f\n",
730 (double)timestamp / AV_TIME_BASE);
736 int ret = av_seek_frame(ic, video_stream, timestamp, 0);
739 fprintf(stderr, "HIGHGUI ERROR: AVI: could not seek to position %0.3f\n",
740 (double)timestamp / AV_TIME_BASE);
744 picture_pts=(int64_t)value;
757 CvCapture* cvCreateFileCapture_FFMPEG( const char* filename )
759 CvCapture_FFMPEG* capture = new CvCapture_FFMPEG;
760 if( capture->open( filename ))
767 ///////////////// FFMPEG CvVideoWriter implementation //////////////////////////
768 class CvVideoWriter_FFMPEG : public CvVideoWriter
771 CvVideoWriter_FFMPEG() { init(); }
772 virtual ~CvVideoWriter_FFMPEG() { close(); }
774 virtual bool open( const char* filename, int fourcc,
775 double fps, CvSize frameSize, bool isColor );
776 virtual void close();
777 virtual bool writeFrame( const IplImage* image );
785 uint32_t outbuf_size;
788 AVFrame * input_picture;
792 IplImage * temp_image;
793 #if defined(HAVE_FFMPEG_SWSCALE)
794 struct SwsContext *img_convert_ctx;
798 static const char * icvFFMPEGErrStr(int err)
801 case AVERROR_NUMEXPECTED:
802 return "Incorrect filename syntax";
803 case AVERROR_INVALIDDATA:
804 return "Invalid data in header";
806 return "Unknown format";
808 return "I/O error occurred";
810 return "Memory allocation error";
814 return "Unspecified error";
817 /* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/
819 enum CodecID codec_get_bmp_id(unsigned int tag);
822 void CvVideoWriter_FFMPEG::init()
835 #if defined(HAVE_FFMPEG_SWSCALE)
841 * the following function is a modified version of code
842 * found in ffmpeg-0.4.9-pre1/output_example.c
844 static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc)
847 uint8_t * picture_buf;
850 picture = avcodec_alloc_frame();
853 size = avpicture_get_size( (PixelFormat) pix_fmt, width, height);
855 picture_buf = (uint8_t *) cvAlloc(size);
861 avpicture_fill((AVPicture *)picture, picture_buf,
862 (PixelFormat) pix_fmt, width, height);
869 /* add a video output stream to the container */
870 static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
872 int w, int h, int bitrate,
873 double fps, int pixel_format)
877 int frame_rate, frame_rate_base;
881 st = av_new_stream(oc, 0);
883 CV_WARN("Could not allocate stream");
887 #if LIBAVFORMAT_BUILD > 4628
893 #if LIBAVFORMAT_BUILD > 4621
894 c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
896 c->codec_id = oc->oformat->video_codec;
899 if(codec_id != CODEC_ID_NONE){
900 c->codec_id = codec_id;
903 //if(codec_tag) c->codec_tag=codec_tag;
904 codec = avcodec_find_encoder(c->codec_id);
906 c->codec_type = CODEC_TYPE_VIDEO;
908 /* put sample parameters */
909 c->bit_rate = bitrate;
911 /* resolution must be a multiple of two */
915 /* time base: this is the fundamental unit of time (in seconds) in terms
916 of which frame timestamps are represented. for fixed-fps content,
917 timebase should be 1/framerate and timestamp increments should be
919 frame_rate=cvRound(fps);
921 while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){
923 frame_rate=cvRound(fps*frame_rate_base);
925 #if LIBAVFORMAT_BUILD > 4752
926 c->time_base.den = frame_rate;
927 c->time_base.num = frame_rate_base;
928 /* adjust time base for supported framerates */
929 if(codec && codec->supported_framerates){
930 const AVRational *p= codec->supported_framerates;
931 AVRational req = {frame_rate, frame_rate_base};
932 const AVRational *best=NULL;
933 AVRational best_error= {INT_MAX, 1};
934 for(; p->den!=0; p++){
935 AVRational error= av_sub_q(req, *p);
936 if(error.num <0) error.num *= -1;
937 if(av_cmp_q(error, best_error) < 0){
942 c->time_base.den= best->num;
943 c->time_base.num= best->den;
946 c->frame_rate = frame_rate;
947 c->frame_rate_base = frame_rate_base;
950 c->gop_size = 12; /* emit one intra frame every twelve frames at most */
951 c->pix_fmt = (PixelFormat) pixel_format;
953 if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
956 if (c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MSMPEG4V3){
957 /* needed to avoid using macroblocks in which some coeffs overflow
958 this doesnt happen with normal video, it just happens here as the
959 motion of the chroma plane doesnt match the luma plane */
960 /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */
963 #if LIBAVCODEC_VERSION_INT>0x000409
964 // some formats want stream headers to be seperate
965 if(oc->oformat->flags & AVFMT_GLOBALHEADER)
967 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
974 int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture ){
975 CV_FUNCNAME("icv_av_write_frame_FFMPEG");
977 #if LIBAVFORMAT_BUILD > 4628
978 AVCodecContext * c = video_st->codec;
980 AVCodecContext * c = &(video_st->codec);
987 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
988 /* raw video case. The API will change slightly in the near
991 av_init_packet(&pkt);
993 pkt.flags |= PKT_FLAG_KEY;
994 pkt.stream_index= video_st->index;
995 pkt.data= (uint8_t *)picture;
996 pkt.size= sizeof(AVPicture);
998 ret = av_write_frame(oc, &pkt);
1000 /* encode the image */
1001 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
1002 /* if zero size, it means the image was buffered */
1005 av_init_packet(&pkt);
1007 #if LIBAVFORMAT_BUILD > 4752
1008 pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
1010 pkt.pts = c->coded_frame->pts;
1012 if(c->coded_frame->key_frame)
1013 pkt.flags |= PKT_FLAG_KEY;
1014 pkt.stream_index= video_st->index;
1018 /* write the compressed frame in the media file */
1019 ret = av_write_frame(oc, &pkt);
1025 CV_ERROR(CV_StsError, "Error while writing video frame");
1032 /// write a frame with FFMPEG
1033 bool CvVideoWriter_FFMPEG::writeFrame( const IplImage * image )
1037 CV_FUNCNAME("CvVideoWriter_FFMPEG::writerFrame");
1041 // typecast from opaque data type to implemented struct
1042 #if LIBAVFORMAT_BUILD > 4628
1043 AVCodecContext *c = video_st->codec;
1045 AVCodecContext *c = &(video_st->codec);
1048 #if LIBAVFORMAT_BUILD < 5231
1049 // It is not needed in the latest versions of the ffmpeg
1050 if( c->codec_id == CODEC_ID_RAWVIDEO && image->origin != IPL_ORIGIN_BL )
1053 temp_image = cvCreateImage( cvGetSize(image),
1054 image->depth, image->nChannels );
1055 cvFlip( image, temp_image, 0 );
1061 if (input_pix_fmt == PIX_FMT_BGR24) {
1062 if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U) {
1063 CV_ERROR(CV_StsUnsupportedFormat, "cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 3.");
1066 else if (input_pix_fmt == PIX_FMT_GRAY8) {
1067 if (image->nChannels != 1 || image->depth != IPL_DEPTH_8U) {
1068 CV_ERROR(CV_StsUnsupportedFormat, "cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1.");
1075 // check if buffer sizes match, i.e. image has expected format (size, channels, bitdepth, alignment)
1076 #if LIBAVCODEC_VERSION_INT >= ((52<<16)+(37<<8)+0)
1077 assert (image->imageSize == avpicture_get_size( (PixelFormat)input_pix_fmt, image->width, image->height ));
1079 assert (image->imageSize == avpicture_get_size( input_pix_fmt, image->width, image->height ));
1082 if ( c->pix_fmt != input_pix_fmt ) {
1083 assert( input_picture );
1084 // let input_picture point to the raw data buffer of 'image'
1085 avpicture_fill((AVPicture *)input_picture, (uint8_t *) image->imageData,
1086 (PixelFormat)input_pix_fmt, image->width, image->height);
1088 #if !defined(HAVE_FFMPEG_SWSCALE)
1089 // convert to the color format needed by the codec
1090 if( img_convert((AVPicture *)picture, c->pix_fmt,
1091 (AVPicture *)input_picture, (PixelFormat)input_pix_fmt,
1092 image->width, image->height) < 0){
1093 CV_ERROR(CV_StsUnsupportedFormat, "FFMPEG::img_convert pixel format conversion from BGR24 not handled");
1096 img_convert_ctx = sws_getContext(image->width,
1105 if ( sws_scale(img_convert_ctx, input_picture->data,
1106 input_picture->linesize, 0,
1108 picture->data, picture->linesize) < 0 )
1110 CV_ERROR(CV_StsUnsupportedFormat, "FFMPEG::img_convert pixel format conversion from BGR24 not handled");
1112 sws_freeContext(img_convert_ctx);
1116 avpicture_fill((AVPicture *)picture, (uint8_t *) image->imageData,
1117 (PixelFormat)input_pix_fmt, image->width, image->height);
1120 ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0;
1126 /// close video output stream and free associated memory
1127 void CvVideoWriter_FFMPEG::close()
1131 // nothing to do if already released
1135 /* no more frame to compress. The codec has a latency of a few
1136 frames if using B frames, so we get the last frames by
1137 passing the same picture again */
1138 // TODO -- do we need to account for latency here?
1140 /* write the trailer, if any */
1141 av_write_trailer(oc);
1144 #if LIBAVFORMAT_BUILD > 4628
1145 if( video_st->codec->pix_fmt != input_pix_fmt){
1147 if( video_st->codec.pix_fmt != input_pix_fmt){
1149 cvFree(&(picture->data[0]));
1153 if (input_picture) {
1154 av_free(input_picture);
1158 #if LIBAVFORMAT_BUILD > 4628
1159 avcodec_close(video_st->codec);
1161 avcodec_close(&(video_st->codec));
1166 /* free the streams */
1167 for(i = 0; i < oc->nb_streams; i++) {
1168 av_freep(&oc->streams[i]->codec);
1169 av_freep(&oc->streams[i]);
1172 if (!(fmt->flags & AVFMT_NOFILE)) {
1173 /* close the output file */
1176 #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1179 url_fclose(&oc->pb);
1184 /* free the stream */
1187 cvReleaseImage( &temp_image );
1192 /// Create a video writer object that uses FFMPEG
1193 bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
1194 double fps, CvSize frameSize, bool is_color )
1196 CodecID codec_id = CODEC_ID_NONE;
1197 int err, codec_pix_fmt, bitrate_scale=64;
1204 assert (frameSize.width > 0 && frameSize.height > 0);
1206 // tell FFMPEG to register codecs
1209 /* auto detect the output format from the name and fourcc code. */
1210 fmt = guess_format(NULL, filename, NULL);
1214 /* determine optimal pixel format */
1216 input_pix_fmt = PIX_FMT_BGR24;
1219 input_pix_fmt = PIX_FMT_GRAY8;
1222 /* Lookup codec_id for given fourcc */
1223 #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
1224 if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE )
1227 const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
1228 if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE )
1232 // alloc memory for context
1233 oc = av_alloc_format_context();
1238 snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
1240 /* set some options */
1241 oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */
1243 // set a few optimal pixel formats for lossless codecs of interest..
1245 #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
1246 case CODEC_ID_JPEGLS:
1247 // BGR24 or GRAY8 depending on is_color...
1248 codec_pix_fmt = input_pix_fmt;
1251 case CODEC_ID_HUFFYUV:
1252 codec_pix_fmt = PIX_FMT_YUV422P;
1254 case CODEC_ID_MJPEG:
1255 case CODEC_ID_LJPEG:
1256 codec_pix_fmt = PIX_FMT_YUVJ420P;
1257 bitrate_scale = 128;
1259 case CODEC_ID_RAWVIDEO:
1261 // good for lossy formats, MPEG, etc.
1262 codec_pix_fmt = PIX_FMT_YUV420P;
1266 // TODO -- safe to ignore output audio stream?
1267 video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
1268 frameSize.width, frameSize.height, frameSize.width*frameSize.height*bitrate_scale,
1269 fps, codec_pix_fmt);
1272 /* set the output parameters (must be done even if no
1274 if (av_set_parameters(oc, NULL) < 0) {
1275 CV_Error(CV_StsBadArg, "Invalid output format parameters");
1278 dump_format(oc, 0, filename, 1);
1280 /* now that all the parameters are set, we can open the audio and
1281 video codecs and allocate the necessary encode buffers */
1283 CV_Error(CV_StsBadArg, "Couldn't open video stream");
1289 #if LIBAVFORMAT_BUILD > 4628
1290 c = (video_st->codec);
1292 c = &(video_st->codec);
1295 c->codec_tag = fourcc;
1296 /* find the video encoder */
1297 codec = avcodec_find_encoder(c->codec_id);
1299 CV_Error(CV_StsBadArg, "codec not found");
1302 /* open the codec */
1303 if ( (err=avcodec_open(c, codec)) < 0) {
1305 sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err));
1306 CV_Error(CV_StsBadArg, errtext);
1311 if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
1312 /* allocate output buffer */
1313 /* assume we will never get codec output with more than 4 bytes per pixel... */
1314 outbuf_size = frameSize.width*frameSize.height*4;
1315 outbuf = (uint8_t *) av_malloc(outbuf_size);
1318 bool need_color_convert;
1319 need_color_convert = (c->pix_fmt != input_pix_fmt);
1321 /* allocate the encoded raw picture */
1322 picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert);
1324 CV_Error(CV_StsNoMem, "Could not allocate picture");
1327 /* if the output format is not our input format, then a temporary
1328 picture of the input format is needed too. It is then converted
1329 to the required output format */
1330 input_picture = NULL;
1331 if ( need_color_convert ) {
1332 input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false);
1333 if (!input_picture) {
1334 CV_Error(CV_StsNoMem, "Could not allocate picture");
1338 /* open the output file, if needed */
1339 if (!(fmt->flags & AVFMT_NOFILE)) {
1340 if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
1341 CV_Error(CV_StsBadArg, "Couldn't open output file for writing");
1345 /* write the stream header, if any */
1346 av_write_header( oc );
1351 CvVideoWriter* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
1352 CvSize frameSize, int isColor )
1354 CvVideoWriter_FFMPEG* writer = new CvVideoWriter_FFMPEG;
1355 if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))