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->cur_dts != AV_NOPTS_VALUE_)
624 return (((double)video_st->cur_dts-1) *1000) / av_q2d (video_st->r_frame_rate);
626 case CV_CAP_PROP_POS_FRAMES:
627 if(video_st->cur_dts != AV_NOPTS_VALUE_)
628 return (double)video_st->cur_dts-1;
630 case CV_CAP_PROP_POS_AVI_RATIO:
631 if(video_st->cur_dts != AV_NOPTS_VALUE_ && video_st->duration != AV_NOPTS_VALUE_)
632 return (double)(video_st->cur_dts-1)/(double)video_st->duration;
634 case CV_CAP_PROP_FRAME_COUNT:
635 if(video_st->duration != AV_NOPTS_VALUE_)
636 return (double)video_st->duration;
638 case CV_CAP_PROP_FRAME_WIDTH:
639 return (double)frame.width;
640 case CV_CAP_PROP_FRAME_HEIGHT:
641 return (double)frame.height;
642 case CV_CAP_PROP_FPS:
643 #if LIBAVCODEC_BUILD > 4753
644 return av_q2d (video_st->r_frame_rate);
646 return (double)video_st->codec.frame_rate
647 / (double)video_st->codec.frame_rate_base;
649 case CV_CAP_PROP_FOURCC:
650 #if LIBAVFORMAT_BUILD > 4628
651 return (double)video_st->codec->codec_tag;
653 return (double)video_st->codec.codec_tag;
661 // this is a VERY slow fallback function, ONLY used if ffmpeg's av_seek_frame delivers no correct result!
662 bool CvCapture_FFMPEG::slowSeek( int framenumber )
664 if ( framenumber>picture_pts )
666 while ( picture_pts<framenumber )
667 if ( !grabFrame() ) return false;
669 else if ( framenumber<picture_pts )
672 while ( picture_pts<framenumber )
673 if ( !grabFrame() ) return false;
679 bool CvCapture_FFMPEG::setProperty( int property_id, double value )
681 if( !video_st ) return false;
683 switch( property_id )
685 case CV_CAP_PROP_POS_MSEC:
686 case CV_CAP_PROP_POS_FRAMES:
687 case CV_CAP_PROP_POS_AVI_RATIO:
689 int64_t timestamp = 0;
690 AVRational time_base;
691 switch( property_id )
693 case CV_CAP_PROP_POS_FRAMES:
694 timestamp=(int64_t)value;
695 if(ic->start_time != AV_NOPTS_VALUE_)
696 timestamp += ic->start_time;
699 case CV_CAP_PROP_POS_MSEC:
700 time_base=ic->streams[video_stream]->time_base;
701 timestamp=(int64_t)(value*(float(time_base.den)/float(time_base.num))/1000);
702 if(ic->start_time != AV_NOPTS_VALUE_)
703 timestamp += ic->start_time;
706 case CV_CAP_PROP_POS_AVI_RATIO:
707 timestamp=(int64_t)(value*ic->duration);
708 if(ic->start_time != AV_NOPTS_VALUE_ && ic->duration != AV_NOPTS_VALUE_)
709 timestamp += ic->start_time;
715 // ffmpeg's seek doesn't work...
716 if (!slowSeek((int)timestamp))
718 fprintf(stderr, "HIGHGUI ERROR: AVI: could not (slow) seek to position %0.3f\n",
719 (double)timestamp / AV_TIME_BASE);
725 int ret = av_seek_frame(ic, video_stream, timestamp, 0);
728 fprintf(stderr, "HIGHGUI ERROR: AVI: could not seek to position %0.3f\n",
729 (double)timestamp / AV_TIME_BASE);
733 picture_pts=(int64_t)value;
746 CvCapture* cvCreateFileCapture_FFMPEG( const char* filename )
748 CvCapture_FFMPEG* capture = new CvCapture_FFMPEG;
749 if( capture->open( filename ))
756 ///////////////// FFMPEG CvVideoWriter implementation //////////////////////////
757 class CvVideoWriter_FFMPEG : public CvVideoWriter
760 CvVideoWriter_FFMPEG() { init(); }
761 virtual ~CvVideoWriter_FFMPEG() { close(); }
763 virtual bool open( const char* filename, int fourcc,
764 double fps, CvSize frameSize, bool isColor );
765 virtual void close();
766 virtual bool writeFrame( const IplImage* image );
774 uint32_t outbuf_size;
777 AVFrame * input_picture;
781 IplImage * temp_image;
782 #if defined(HAVE_FFMPEG_SWSCALE)
783 struct SwsContext *img_convert_ctx;
787 static const char * icvFFMPEGErrStr(int err)
790 case AVERROR_NUMEXPECTED:
791 return "Incorrect filename syntax";
792 case AVERROR_INVALIDDATA:
793 return "Invalid data in header";
795 return "Unknown format";
797 return "I/O error occurred";
799 return "Memory allocation error";
803 return "Unspecified error";
806 /* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/
808 enum CodecID codec_get_bmp_id(unsigned int tag);
811 void CvVideoWriter_FFMPEG::init()
824 #if defined(HAVE_FFMPEG_SWSCALE)
830 * the following function is a modified version of code
831 * found in ffmpeg-0.4.9-pre1/output_example.c
833 static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc)
836 uint8_t * picture_buf;
839 picture = avcodec_alloc_frame();
842 size = avpicture_get_size( (PixelFormat) pix_fmt, width, height);
844 picture_buf = (uint8_t *) cvAlloc(size);
850 avpicture_fill((AVPicture *)picture, picture_buf,
851 (PixelFormat) pix_fmt, width, height);
858 /* add a video output stream to the container */
859 static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
861 int w, int h, int bitrate,
862 double fps, int pixel_format)
866 int frame_rate, frame_rate_base;
870 st = av_new_stream(oc, 0);
872 CV_WARN("Could not allocate stream");
876 #if LIBAVFORMAT_BUILD > 4628
882 #if LIBAVFORMAT_BUILD > 4621
883 c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
885 c->codec_id = oc->oformat->video_codec;
888 if(codec_id != CODEC_ID_NONE){
889 c->codec_id = codec_id;
892 //if(codec_tag) c->codec_tag=codec_tag;
893 codec = avcodec_find_encoder(c->codec_id);
895 c->codec_type = CODEC_TYPE_VIDEO;
897 /* put sample parameters */
898 c->bit_rate = bitrate;
900 /* resolution must be a multiple of two */
904 /* time base: this is the fundamental unit of time (in seconds) in terms
905 of which frame timestamps are represented. for fixed-fps content,
906 timebase should be 1/framerate and timestamp increments should be
908 frame_rate=cvRound(fps);
910 while (fabs((double)frame_rate/frame_rate_base) - fps > 0.001){
912 frame_rate=cvRound(fps*frame_rate_base);
914 #if LIBAVFORMAT_BUILD > 4752
915 c->time_base.den = frame_rate;
916 c->time_base.num = frame_rate_base;
917 /* adjust time base for supported framerates */
918 if(codec && codec->supported_framerates){
919 const AVRational *p= codec->supported_framerates;
920 AVRational req = {frame_rate, frame_rate_base};
921 const AVRational *best=NULL;
922 AVRational best_error= {INT_MAX, 1};
923 for(; p->den!=0; p++){
924 AVRational error= av_sub_q(req, *p);
925 if(error.num <0) error.num *= -1;
926 if(av_cmp_q(error, best_error) < 0){
931 c->time_base.den= best->num;
932 c->time_base.num= best->den;
935 c->frame_rate = frame_rate;
936 c->frame_rate_base = frame_rate_base;
939 c->gop_size = 12; /* emit one intra frame every twelve frames at most */
940 c->pix_fmt = (PixelFormat) pixel_format;
942 if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
945 if (c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MSMPEG4V3){
946 /* needed to avoid using macroblocks in which some coeffs overflow
947 this doesnt happen with normal video, it just happens here as the
948 motion of the chroma plane doesnt match the luma plane */
949 /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */
952 #if LIBAVCODEC_VERSION_INT>0x000409
953 // some formats want stream headers to be seperate
954 if(oc->oformat->flags & AVFMT_GLOBALHEADER)
956 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
963 int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture ){
964 CV_FUNCNAME("icv_av_write_frame_FFMPEG");
966 #if LIBAVFORMAT_BUILD > 4628
967 AVCodecContext * c = video_st->codec;
969 AVCodecContext * c = &(video_st->codec);
976 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
977 /* raw video case. The API will change slightly in the near
980 av_init_packet(&pkt);
982 pkt.flags |= PKT_FLAG_KEY;
983 pkt.stream_index= video_st->index;
984 pkt.data= (uint8_t *)picture;
985 pkt.size= sizeof(AVPicture);
987 ret = av_write_frame(oc, &pkt);
989 /* encode the image */
990 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
991 /* if zero size, it means the image was buffered */
994 av_init_packet(&pkt);
996 #if LIBAVFORMAT_BUILD > 4752
997 pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
999 pkt.pts = c->coded_frame->pts;
1001 if(c->coded_frame->key_frame)
1002 pkt.flags |= PKT_FLAG_KEY;
1003 pkt.stream_index= video_st->index;
1007 /* write the compressed frame in the media file */
1008 ret = av_write_frame(oc, &pkt);
1014 CV_ERROR(CV_StsError, "Error while writing video frame");
1021 /// write a frame with FFMPEG
1022 bool CvVideoWriter_FFMPEG::writeFrame( const IplImage * image )
1026 CV_FUNCNAME("CvVideoWriter_FFMPEG::writerFrame");
1030 // typecast from opaque data type to implemented struct
1031 #if LIBAVFORMAT_BUILD > 4628
1032 AVCodecContext *c = video_st->codec;
1034 AVCodecContext *c = &(video_st->codec);
1037 #if LIBAVFORMAT_BUILD < 5231
1038 // It is not needed in the latest versions of the ffmpeg
1039 if( c->codec_id == CODEC_ID_RAWVIDEO && image->origin != IPL_ORIGIN_BL )
1042 temp_image = cvCreateImage( cvGetSize(image),
1043 image->depth, image->nChannels );
1044 cvFlip( image, temp_image, 0 );
1050 if (input_pix_fmt == PIX_FMT_BGR24) {
1051 if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U) {
1052 CV_ERROR(CV_StsUnsupportedFormat, "cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 3.");
1055 else if (input_pix_fmt == PIX_FMT_GRAY8) {
1056 if (image->nChannels != 1 || image->depth != IPL_DEPTH_8U) {
1057 CV_ERROR(CV_StsUnsupportedFormat, "cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1.");
1064 // check if buffer sizes match, i.e. image has expected format (size, channels, bitdepth, alignment)
1065 assert (image->imageSize == avpicture_get_size( input_pix_fmt, image->width, image->height ));
1067 if ( c->pix_fmt != input_pix_fmt ) {
1068 assert( input_picture );
1069 // let input_picture point to the raw data buffer of 'image'
1070 avpicture_fill((AVPicture *)input_picture, (uint8_t *) image->imageData,
1071 (PixelFormat)input_pix_fmt, image->width, image->height);
1073 #if !defined(HAVE_FFMPEG_SWSCALE)
1074 // convert to the color format needed by the codec
1075 if( img_convert((AVPicture *)picture, c->pix_fmt,
1076 (AVPicture *)input_picture, (PixelFormat)input_pix_fmt,
1077 image->width, image->height) < 0){
1078 CV_ERROR(CV_StsUnsupportedFormat, "FFMPEG::img_convert pixel format conversion from BGR24 not handled");
1081 img_convert_ctx = sws_getContext(image->width,
1090 if ( sws_scale(img_convert_ctx, input_picture->data,
1091 input_picture->linesize, 0,
1093 picture->data, picture->linesize) < 0 )
1095 CV_ERROR(CV_StsUnsupportedFormat, "FFMPEG::img_convert pixel format conversion from BGR24 not handled");
1097 sws_freeContext(img_convert_ctx);
1101 avpicture_fill((AVPicture *)picture, (uint8_t *) image->imageData,
1102 (PixelFormat)input_pix_fmt, image->width, image->height);
1105 ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0;
1111 /// close video output stream and free associated memory
1112 void CvVideoWriter_FFMPEG::close()
1116 // nothing to do if already released
1120 /* no more frame to compress. The codec has a latency of a few
1121 frames if using B frames, so we get the last frames by
1122 passing the same picture again */
1123 // TODO -- do we need to account for latency here?
1125 /* write the trailer, if any */
1126 av_write_trailer(oc);
1129 #if LIBAVFORMAT_BUILD > 4628
1130 if( video_st->codec->pix_fmt != input_pix_fmt){
1132 if( video_st->codec.pix_fmt != input_pix_fmt){
1134 cvFree(&(picture->data[0]));
1138 if (input_picture) {
1139 av_free(input_picture);
1143 #if LIBAVFORMAT_BUILD > 4628
1144 avcodec_close(video_st->codec);
1146 avcodec_close(&(video_st->codec));
1151 /* free the streams */
1152 for(i = 0; i < oc->nb_streams; i++) {
1153 av_freep(&oc->streams[i]->codec);
1154 av_freep(&oc->streams[i]);
1157 if (!(fmt->flags & AVFMT_NOFILE)) {
1158 /* close the output file */
1161 #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1164 url_fclose(&oc->pb);
1169 /* free the stream */
1172 cvReleaseImage( &temp_image );
1177 /// Create a video writer object that uses FFMPEG
1178 bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
1179 double fps, CvSize frameSize, bool is_color )
1181 CV_FUNCNAME("CvVideoWriter_FFMPEG::open");
1183 CodecID codec_id = CODEC_ID_NONE;
1184 int err, codec_pix_fmt, bitrate_scale=64;
1193 assert (frameSize.width > 0 && frameSize.height > 0);
1195 // tell FFMPEG to register codecs
1198 /* auto detect the output format from the name and fourcc code. */
1199 fmt = guess_format(NULL, filename, NULL);
1201 CV_ERROR( CV_StsUnsupportedFormat, "FFMPEG does not recognize the given file extension");
1204 /* determine optimal pixel format */
1206 input_pix_fmt = PIX_FMT_BGR24;
1209 input_pix_fmt = PIX_FMT_GRAY8;
1212 // alloc memory for context
1213 oc = av_alloc_format_context();
1218 snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
1220 /* set some options */
1221 oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */
1223 /* Lookup codec_id for given fourcc */
1224 #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
1225 if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE ){
1226 CV_ERROR( CV_StsUnsupportedFormat,
1227 "FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto selection." );
1231 const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
1232 if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ){
1233 CV_ERROR( CV_StsUnsupportedFormat,
1234 "FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto selection." );
1239 // set a few optimal pixel formats for lossless codecs of interest..
1241 #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
1242 case CODEC_ID_JPEGLS:
1243 // BGR24 or GRAY8 depending on is_color...
1244 codec_pix_fmt = input_pix_fmt;
1247 case CODEC_ID_HUFFYUV:
1248 codec_pix_fmt = PIX_FMT_YUV422P;
1250 case CODEC_ID_MJPEG:
1251 case CODEC_ID_LJPEG:
1252 codec_pix_fmt = PIX_FMT_YUVJ420P;
1253 bitrate_scale = 128;
1255 case CODEC_ID_RAWVIDEO:
1257 // good for lossy formats, MPEG, etc.
1258 codec_pix_fmt = PIX_FMT_YUV420P;
1262 // TODO -- safe to ignore output audio stream?
1263 video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
1264 frameSize.width, frameSize.height, frameSize.width*frameSize.height*bitrate_scale,
1265 fps, codec_pix_fmt);
1268 /* set the output parameters (must be done even if no
1270 if (av_set_parameters(oc, NULL) < 0) {
1271 CV_ERROR(CV_StsBadArg, "Invalid output format parameters");
1274 dump_format(oc, 0, filename, 1);
1276 /* now that all the parameters are set, we can open the audio and
1277 video codecs and allocate the necessary encode buffers */
1279 CV_ERROR(CV_StsBadArg, "Couldn't open video stream");
1285 #if LIBAVFORMAT_BUILD > 4628
1286 c = (video_st->codec);
1288 c = &(video_st->codec);
1291 c->codec_tag = fourcc;
1292 /* find the video encoder */
1293 codec = avcodec_find_encoder(c->codec_id);
1295 CV_ERROR(CV_StsBadArg, "codec not found");
1298 /* open the codec */
1299 if ( (err=avcodec_open(c, codec)) < 0) {
1301 sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err));
1302 CV_ERROR(CV_StsBadArg, errtext);
1307 if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
1308 /* allocate output buffer */
1309 /* assume we will never get codec output with more than 4 bytes per pixel... */
1310 outbuf_size = frameSize.width*frameSize.height*4;
1311 outbuf = (uint8_t *) av_malloc(outbuf_size);
1314 bool need_color_convert;
1315 need_color_convert = (c->pix_fmt != input_pix_fmt);
1317 /* allocate the encoded raw picture */
1318 picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert);
1320 CV_ERROR(CV_StsNoMem, "Could not allocate picture");
1323 /* if the output format is not our input format, then a temporary
1324 picture of the input format is needed too. It is then converted
1325 to the required output format */
1326 input_picture = NULL;
1327 if ( need_color_convert ) {
1328 input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false);
1329 if (!input_picture) {
1330 CV_ERROR(CV_StsNoMem, "Could not allocate picture");
1334 /* open the output file, if needed */
1335 if (!(fmt->flags & AVFMT_NOFILE)) {
1336 if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
1337 CV_ERROR(CV_StsBadArg, "Couldn't open output file for writing");
1341 /* write the stream header, if any */
1342 av_write_header( oc );
1350 CvVideoWriter* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
1351 CvSize frameSize, int isColor )
1353 CvVideoWriter_FFMPEG* writer = new CvVideoWriter_FFMPEG;
1354 if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))