From d87a56a6391d0b8dd51e9aa72f1ad3205ede3c59 Mon Sep 17 00:00:00 2001 From: Andrey Morozov Date: Fri, 29 Jul 2011 14:17:42 +0000 Subject: [PATCH] added support new ffmpeg (0.8.X) --- 3rdparty/ffmpeg/make.bat | 1 + .../include/opencv2/highgui/highgui_c.h | 194 +++++++++--------- modules/highgui/src/cap_ffmpeg_api.hpp | 3 +- modules/highgui/src/cap_ffmpeg_impl.hpp | 100 +++++++-- 4 files changed, 185 insertions(+), 113 deletions(-) diff --git a/3rdparty/ffmpeg/make.bat b/3rdparty/ffmpeg/make.bat index 6c965c57c..f4f959268 100644 --- a/3rdparty/ffmpeg/make.bat +++ b/3rdparty/ffmpeg/make.bat @@ -1,2 +1,3 @@ +rem gcc -Wall -shared -o opencv_ffmpeg.dll -O3 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat -lavcodec -lavdevice -lswscale -lavutil -lwsock32 -lpthreadGÑE2 gcc -Wall -shared -o opencv_ffmpeg.dll -O2 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat -lavcodec -lavdevice -lswscale -lavutil -lwsock32 set path=c:\apps\mingw64\bin;%path% & gcc -Wall -shared -o opencv_ffmpeg_64.dll -O2 -x c++ -I../include -I../include/ffmpeg_ -I../../modules/highgui/src ffopencv.c -L../lib -lavformat64 -lavcodec64 -lavdevice64 -lswscale64 -lavutil64 -lavcore64 -lwsock32 \ No newline at end of file diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index 55728826d..dbdb34db1 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -54,16 +54,16 @@ extern "C" { //YV //-----------New for Qt /* For font */ -enum { CV_FONT_LIGHT = 25,//QFont::Light, - CV_FONT_NORMAL = 50,//QFont::Normal, - CV_FONT_DEMIBOLD = 63,//QFont::DemiBold, - CV_FONT_BOLD = 75,//QFont::Bold, - CV_FONT_BLACK = 87 //QFont::Black +enum { CV_FONT_LIGHT = 25,//QFont::Light, + CV_FONT_NORMAL = 50,//QFont::Normal, + CV_FONT_DEMIBOLD = 63,//QFont::DemiBold, + CV_FONT_BOLD = 75,//QFont::Bold, + CV_FONT_BLACK = 87 //QFont::Black }; -enum { CV_STYLE_NORMAL = 0,//QFont::StyleNormal, - CV_STYLE_ITALIC = 1,//QFont::StyleItalic, - CV_STYLE_OBLIQUE = 2 //QFont::StyleOblique +enum { CV_STYLE_NORMAL = 0,//QFont::StyleNormal, + CV_STYLE_ITALIC = 1,//QFont::StyleItalic, + CV_STYLE_OBLIQUE = 2 //QFont::StyleOblique }; /* ---------*/ @@ -98,23 +98,23 @@ CVAPI(int) cvStartWindowThread(); // --------- YV --------- enum { - //These 3 flags are used by cvSet/GetWindowProperty - CV_WND_PROP_FULLSCREEN = 0,//to change/get window's fullscreen property - CV_WND_PROP_AUTOSIZE = 1,//to change/get window's autosize property - CV_WND_PROP_ASPECTRATIO= 2,//to change/get window's aspectratio property - // - //These 2 flags are used by cvNamedWindow and cvSet/GetWindowProperty - CV_WINDOW_NORMAL = 0x00000000,//the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size - CV_WINDOW_AUTOSIZE = 0x00000001,//the user cannot resize the window, the size is constrainted by the image displayed - // - //Those flags are only for Qt - CV_GUI_EXPANDED = 0x00000000,//status bar and tool bar - CV_GUI_NORMAL = 0x00000010,//old fashious way - // - //These 3 flags are used by cvNamedWindow and cvSet/GetWindowProperty - CV_WINDOW_FULLSCREEN = 1,//change the window to fullscreen - CV_WINDOW_FREERATIO = 0x00000100,//the image expends as much as it can (no ratio constraint) - CV_WINDOW_KEEPRATIO = 0x00000000//the ration image is respected. + //These 3 flags are used by cvSet/GetWindowProperty + CV_WND_PROP_FULLSCREEN = 0,//to change/get window's fullscreen property + CV_WND_PROP_AUTOSIZE = 1,//to change/get window's autosize property + CV_WND_PROP_ASPECTRATIO= 2,//to change/get window's aspectratio property + // + //These 2 flags are used by cvNamedWindow and cvSet/GetWindowProperty + CV_WINDOW_NORMAL = 0x00000000,//the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size + CV_WINDOW_AUTOSIZE = 0x00000001,//the user cannot resize the window, the size is constrainted by the image displayed + // + //Those flags are only for Qt + CV_GUI_EXPANDED = 0x00000000,//status bar and tool bar + CV_GUI_NORMAL = 0x00000010,//old fashious way + // + //These 3 flags are used by cvNamedWindow and cvSet/GetWindowProperty + CV_WINDOW_FULLSCREEN = 1,//change the window to fullscreen + CV_WINDOW_FREERATIO = 0x00000100,//the image expends as much as it can (no ratio constraint) + CV_WINDOW_KEEPRATIO = 0x00000000//the ration image is respected. }; /* create window */ @@ -162,26 +162,26 @@ CVAPI(void) cvSetTrackbarPos( const char* trackbar_name, const char* window_name enum { - CV_EVENT_MOUSEMOVE =0, - CV_EVENT_LBUTTONDOWN =1, - CV_EVENT_RBUTTONDOWN =2, - CV_EVENT_MBUTTONDOWN =3, - CV_EVENT_LBUTTONUP =4, - CV_EVENT_RBUTTONUP =5, - CV_EVENT_MBUTTONUP =6, - CV_EVENT_LBUTTONDBLCLK =7, - CV_EVENT_RBUTTONDBLCLK =8, - CV_EVENT_MBUTTONDBLCLK =9 + CV_EVENT_MOUSEMOVE =0, + CV_EVENT_LBUTTONDOWN =1, + CV_EVENT_RBUTTONDOWN =2, + CV_EVENT_MBUTTONDOWN =3, + CV_EVENT_LBUTTONUP =4, + CV_EVENT_RBUTTONUP =5, + CV_EVENT_MBUTTONUP =6, + CV_EVENT_LBUTTONDBLCLK =7, + CV_EVENT_RBUTTONDBLCLK =8, + CV_EVENT_MBUTTONDBLCLK =9 }; enum { - CV_EVENT_FLAG_LBUTTON =1, - CV_EVENT_FLAG_RBUTTON =2, - CV_EVENT_FLAG_MBUTTON =4, - CV_EVENT_FLAG_CTRLKEY =8, - CV_EVENT_FLAG_SHIFTKEY =16, - CV_EVENT_FLAG_ALTKEY =32 + CV_EVENT_FLAG_LBUTTON =1, + CV_EVENT_FLAG_RBUTTON =2, + CV_EVENT_FLAG_MBUTTON =4, + CV_EVENT_FLAG_CTRLKEY =8, + CV_EVENT_FLAG_SHIFTKEY =16, + CV_EVENT_FLAG_ALTKEY =32 }; typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param); @@ -193,15 +193,15 @@ CVAPI(void) cvSetMouseCallback( const char* window_name, CvMouseCallback on_mous enum { /* 8bit, color or not */ - CV_LOAD_IMAGE_UNCHANGED =-1, + CV_LOAD_IMAGE_UNCHANGED =-1, /* 8bit, gray */ - CV_LOAD_IMAGE_GRAYSCALE =0, + CV_LOAD_IMAGE_GRAYSCALE =0, /* ?, color */ - CV_LOAD_IMAGE_COLOR =1, + CV_LOAD_IMAGE_COLOR =1, /* any depth, ? */ - CV_LOAD_IMAGE_ANYDEPTH =2, + CV_LOAD_IMAGE_ANYDEPTH =2, /* ?, any color */ - CV_LOAD_IMAGE_ANYCOLOR =4 + CV_LOAD_IMAGE_ANYCOLOR =4 }; /* load image from file @@ -215,9 +215,9 @@ CVAPI(CvMat*) cvLoadImageM( const char* filename, int iscolor CV_DEFAULT(CV_LOAD enum { - CV_IMWRITE_JPEG_QUALITY =1, - CV_IMWRITE_PNG_COMPRESSION =16, - CV_IMWRITE_PXM_BINARY =32 + CV_IMWRITE_JPEG_QUALITY =1, + CV_IMWRITE_PNG_COMPRESSION =16, + CV_IMWRITE_PXM_BINARY =32 }; /* save image to file */ @@ -234,8 +234,8 @@ CVAPI(CvMat*) cvEncodeImage( const char* ext, const CvArr* image, enum { - CV_CVTIMG_FLIP =1, - CV_CVTIMG_SWAP_RB =2 + CV_CVTIMG_FLIP =1, + CV_CVTIMG_SWAP_RB =2 }; /* utility function: convert one image to another with optional vertical flip */ @@ -256,38 +256,38 @@ CVAPI(CvCapture*) cvCreateFileCapture( const char* filename ); enum { - CV_CAP_ANY =0, // autodetect + CV_CAP_ANY =0, // autodetect - CV_CAP_MIL =100, // MIL proprietary drivers + CV_CAP_MIL =100, // MIL proprietary drivers - CV_CAP_VFW =200, // platform native - CV_CAP_V4L =200, - CV_CAP_V4L2 =200, + CV_CAP_VFW =200, // platform native + CV_CAP_V4L =200, + CV_CAP_V4L2 =200, - CV_CAP_FIREWARE =300, // IEEE 1394 drivers - CV_CAP_FIREWIRE =300, - CV_CAP_IEEE1394 =300, - CV_CAP_DC1394 =300, - CV_CAP_CMU1394 =300, + CV_CAP_FIREWARE =300, // IEEE 1394 drivers + CV_CAP_FIREWIRE =300, + CV_CAP_IEEE1394 =300, + CV_CAP_DC1394 =300, + CV_CAP_CMU1394 =300, - CV_CAP_STEREO =400, // TYZX proprietary drivers - CV_CAP_TYZX =400, - CV_TYZX_LEFT =400, - CV_TYZX_RIGHT =401, - CV_TYZX_COLOR =402, - CV_TYZX_Z =403, + CV_CAP_STEREO =400, // TYZX proprietary drivers + CV_CAP_TYZX =400, + CV_TYZX_LEFT =400, + CV_TYZX_RIGHT =401, + CV_TYZX_COLOR =402, + CV_TYZX_Z =403, - CV_CAP_QT =500, // QuickTime + CV_CAP_QT =500, // QuickTime - CV_CAP_UNICAP =600, // Unicap drivers + CV_CAP_UNICAP =600, // Unicap drivers - CV_CAP_DSHOW =700, // DirectShow (via videoInput) + CV_CAP_DSHOW =700, // DirectShow (via videoInput) - CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK + CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK - CV_CAP_OPENNI =900, // OpenNI (for Kinect) + CV_CAP_OPENNI =900, // OpenNI (for Kinect) - CV_CAP_ANDROID =1000 // Android + CV_CAP_ANDROID =1000 // Android }; /* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */ @@ -318,26 +318,26 @@ enum CV_CAP_PROP_DC1394_MODE_MANUAL = -3, //set automatically when a value of the feature is set by the user CV_CAP_PROP_DC1394_MODE_AUTO = -2, CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO = -1, - CV_CAP_PROP_POS_MSEC =0, - CV_CAP_PROP_POS_FRAMES =1, - CV_CAP_PROP_POS_AVI_RATIO =2, - CV_CAP_PROP_FRAME_WIDTH =3, - CV_CAP_PROP_FRAME_HEIGHT =4, - CV_CAP_PROP_FPS =5, - CV_CAP_PROP_FOURCC =6, - CV_CAP_PROP_FRAME_COUNT =7, - CV_CAP_PROP_FORMAT =8, - CV_CAP_PROP_MODE =9, - CV_CAP_PROP_BRIGHTNESS =10, - CV_CAP_PROP_CONTRAST =11, - CV_CAP_PROP_SATURATION =12, - CV_CAP_PROP_HUE =13, - CV_CAP_PROP_GAIN =14, - CV_CAP_PROP_EXPOSURE =15, - CV_CAP_PROP_CONVERT_RGB =16, + CV_CAP_PROP_POS_MSEC =0, + CV_CAP_PROP_POS_FRAMES =1, + CV_CAP_PROP_POS_AVI_RATIO =2, + CV_CAP_PROP_FRAME_WIDTH =3, + CV_CAP_PROP_FRAME_HEIGHT =4, + CV_CAP_PROP_FPS =5, + CV_CAP_PROP_FOURCC =6, + CV_CAP_PROP_FRAME_COUNT =7, + CV_CAP_PROP_FORMAT =8, + CV_CAP_PROP_MODE =9, + CV_CAP_PROP_BRIGHTNESS =10, + CV_CAP_PROP_CONTRAST =11, + CV_CAP_PROP_SATURATION =12, + CV_CAP_PROP_HUE =13, + CV_CAP_PROP_GAIN =14, + CV_CAP_PROP_EXPOSURE =15, + CV_CAP_PROP_CONVERT_RGB =16, CV_CAP_PROP_WHITE_BALANCE_BLUE_U =17, - CV_CAP_PROP_RECTIFICATION =18, - CV_CAP_PROP_MONOCROME =19, + CV_CAP_PROP_RECTIFICATION =18, + CV_CAP_PROP_MONOCROME =19, CV_CAP_PROP_SHARPNESS =20, CV_CAP_PROP_AUTO_EXPOSURE =21, // exposure control done by camera, // user can adjust refernce level @@ -351,7 +351,7 @@ enum CV_CAP_PROP_AUTOGRAB =1024, // property for highgui class CvCapture_Android only CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING=1025, // readonly, tricky property, returns cpnst char* indeed CV_CAP_PROP_PREVIEW_FORMAT=1026, // readonly, tricky property, returns cpnst char* indeed - // OpenNI map generators + // OpenNI map generators CV_CAP_OPENNI_DEPTH_GENERATOR = 0, CV_CAP_OPENNI_IMAGE_GENERATOR = 1 << 31, CV_CAP_OPENNI_GENERATORS_MASK = 1 << 31, @@ -371,8 +371,10 @@ enum CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION_ON = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_REGISTRATION_ON, // Properties of cameras available through GStreamer interface - CV_CAP_GSTREAMER_QUEUE_LENGTH = 200, // default is 1 - CV_CAP_PROP_PVAPI_MULTICASTIP = 300 // ip for anable multicast master mode. 0 for disable multicast + CV_CAP_GSTREAMER_QUEUE_LENGTH = 200, // default is 1 + CV_CAP_PROP_PVAPI_MULTICASTIP = 300, // ip for anable multicast master mode. 0 for disable multicast + + CV_CAP_PROP_THREADS = 400 }; enum @@ -419,7 +421,7 @@ typedef struct CvVideoWriter CvVideoWriter; CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4) { - return (c1 & 255) + ((c2 & 255) << 8) + ((c3 &255) << 16) + ((c4 & 255) << 24); + return (c1 & 255) + ((c2 & 255) << 8) + ((c3 &255) << 16) + ((c4 & 255) << 24); } #define CV_FOURCC_PROMPT -1 /* Open Codec Selection Dialog (Windows only) */ diff --git a/modules/highgui/src/cap_ffmpeg_api.hpp b/modules/highgui/src/cap_ffmpeg_api.hpp index 57d5f1939..109049c2d 100644 --- a/modules/highgui/src/cap_ffmpeg_api.hpp +++ b/modules/highgui/src/cap_ffmpeg_api.hpp @@ -21,7 +21,8 @@ enum CV_FFMPEG_CAP_PROP_FRAME_HEIGHT=4, CV_FFMPEG_CAP_PROP_FPS=5, CV_FFMPEG_CAP_PROP_FOURCC=6, - CV_FFMPEG_CAP_PROP_FRAME_COUNT=7 + CV_FFMPEG_CAP_PROP_FRAME_COUNT=7, + CV_FFMPEG_CAP_PROP_THREADS=8 }; diff --git a/modules/highgui/src/cap_ffmpeg_impl.hpp b/modules/highgui/src/cap_ffmpeg_impl.hpp index 5fd9926c0..147a52553 100644 --- a/modules/highgui/src/cap_ffmpeg_impl.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl.hpp @@ -135,7 +135,7 @@ extern "C" { #define PIX_FMT_RGBA32 PIX_FMT_RGB32 #endif - +#define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c ) char * FOURCC2str( int fourcc ) { @@ -365,6 +365,7 @@ struct CvCapture_FFMPEG and so the filename is needed to reopen the file on backward seeking. */ char * filename; + int count_threads; }; @@ -379,6 +380,7 @@ void CvCapture_FFMPEG::init() memset( &frame, 0, sizeof(frame) ); filename = 0; packet.data = NULL; + count_threads = 1; #if defined(HAVE_FFMPEG_SWSCALE) img_convert_ctx = 0; #endif @@ -489,8 +491,14 @@ bool CvCapture_FFMPEG::open( const char* _filename ) AVCodecContext *enc = &ic->streams[i]->codec; #endif - if( CODEC_TYPE_VIDEO == enc->codec_type && video_stream < 0) { - AVCodec *codec = avcodec_find_decoder(enc->codec_id); + avcodec_thread_init(enc, count_threads); + + //#ifndef AVMEDIA_TYPE_VIDEO + // #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO + //#endif + + if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) { + AVCodec *codec = avcodec_find_decoder(enc->codec_id); if (!codec || avcodec_open(enc, codec) < 0) goto exit_func; @@ -576,14 +584,18 @@ bool CvCapture_FFMPEG::grabFrame() continue; } -#if LIBAVFORMAT_BUILD > 4628 - avcodec_decode_video(video_st->codec, - picture, &got_picture, - packet.data, packet.size); +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 4, 0) + avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); #else - avcodec_decode_video(&video_st->codec, - picture, &got_picture, - packet.data, packet.size); + #if LIBAVFORMAT_BUILD > 4628 + avcodec_decode_video(video_st->codec, + picture, &got_picture, + packet.data, packet.size); + #else + avcodec_decode_video(&video_st->codec, + picture, &got_picture, + packet.data, packet.size); + #endif #endif if (got_picture) { @@ -702,12 +714,14 @@ double CvCapture_FFMPEG::getProperty( int property_id ) return (double)video_st->codec.codec_tag; #endif break; + case CV_FFMPEG_CAP_PROP_THREADS: + return count_threads; + break; } + return 0; } - - // this is a VERY slow fallback function, ONLY used if ffmpeg's av_seek_frame delivers no correct result! bool CvCapture_FFMPEG::slowSeek( int framenumber ) { @@ -787,6 +801,12 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value ) picture_pts=(int64_t)value; } break; + + case CV_FFMPEG_CAP_PROP_THREADS: + { + count_threads = (int)value; + } + break; default: return false; @@ -824,6 +844,38 @@ struct CvVideoWriter_FFMPEG static const char * icvFFMPEGErrStr(int err) { +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 4, 0) + switch(err) { + case AVERROR_BSF_NOT_FOUND: + return "Bitstream filter not found"; + case AVERROR_DECODER_NOT_FOUND: + return "Decoder not found"; + case AVERROR_DEMUXER_NOT_FOUND: + return "Demuxer not found"; + case AVERROR_ENCODER_NOT_FOUND: + return "Encoder not found"; + case AVERROR_EOF: + return "End of file"; + case AVERROR_EXIT: + return "Immediate exit was requested; the called function should not be restarted"; + case AVERROR_FILTER_NOT_FOUND: + return "Filter not found"; + case AVERROR_INVALIDDATA: + return "Invalid data found when processing input"; + case AVERROR_MUXER_NOT_FOUND: + return "Muxer not found"; + case AVERROR_OPTION_NOT_FOUND: + return "Option not found"; + case AVERROR_PATCHWELCOME: + return "Not yet implemented in FFmpeg, patches welcome"; + case AVERROR_PROTOCOL_NOT_FOUND: + return "Protocol not found"; + case AVERROR_STREAM_NOT_FOUND: + return "Stream not found"; + default: + break; + } +#else switch(err) { case AVERROR_NUMEXPECTED: return "Incorrect filename syntax"; @@ -838,7 +890,9 @@ static const char * icvFFMPEGErrStr(int err) default: break; } - return "Unspecified error"; +#endif + + return "Unspecified error"; } /* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/ @@ -918,7 +972,7 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, #endif #if LIBAVFORMAT_BUILD > 4621 - c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO); + c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); #else c->codec_id = oc->oformat->video_codec; #endif @@ -930,7 +984,7 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, //if(codec_tag) c->codec_tag=codec_tag; codec = avcodec_find_encoder(c->codec_id); - c->codec_type = CODEC_TYPE_VIDEO; + c->codec_type = AVMEDIA_TYPE_VIDEO; /* put sample parameters */ c->bit_rate = bitrate; @@ -1015,7 +1069,11 @@ int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_ AVPacket pkt; av_init_packet(&pkt); - pkt.flags |= PKT_FLAG_KEY; + #ifndef PKT_FLAG_KEY + #define PKT_FLAG_KEY AV_PKT_FLAG_KEY + #endif + + pkt.flags |= PKT_FLAG_KEY; pkt.stream_index= video_st->index; pkt.data= (uint8_t *)picture; pkt.size= sizeof(AVPicture); @@ -1237,7 +1295,13 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, av_register_all (); /* auto detect the output format from the name and fourcc code. */ + +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 4, 0) + fmt = av_guess_format(NULL, filename, NULL); +#else fmt = guess_format(NULL, filename, NULL); +#endif + if (!fmt) return false; @@ -1260,7 +1324,11 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, #endif // alloc memory for context +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 4, 0) + oc = avformat_alloc_context(); +#else oc = av_alloc_format_context(); +#endif assert (oc); /* set file name */