Refactored new ffmpeg wrapper
authorAlexander Reshetnikov <no@email>
Tue, 20 Mar 2012 09:17:28 +0000 (09:17 +0000)
committerAlexander Reshetnikov <no@email>
Tue, 20 Mar 2012 09:17:28 +0000 (09:17 +0000)
modules/highgui/src/cap_ffmpeg_impl_v2.hpp
modules/highgui/src/cap_ffmpeg_v2.cpp

index 886f55e..c82c94f 100755 (executable)
 //
 //M*/
 
+#include "cap_ffmpeg_api.hpp"
+#include <assert.h>
+#include <algorithm>
+
+#if defined _MSC_VER && _MSC_VER >= 1200
+#pragma warning( disable: 4244 4510 4512 4610 )
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#undef  UINT64_C
-#define UINT64_C(val) val ## LL
-#include <libavformat/avformat.h>
-#include <libavcodec/avcodec.h>
-#include <libswscale/swscale.h>
+#if !defined(WIN32) || defined(__MINGW32__)
+// some versions of FFMPEG assume a C99 compiler, and don't define INT64_C
+#if !defined INT64_C || !defined UINT64_C
+#define INT64_C
+#define UINT64_C
+#define __STDC_CONSTANT_MACROS
+// force re-inclusion of stdint.h to get INT64_C macro
+#undef _STDINT_H
+#include <stdint.h>
+#endif
+#include <errno.h>
+#endif
+
+#ifdef WIN32
+  #define HAVE_FFMPEG_SWSCALE 1
+  #include <libavformat/avformat.h>
+  #include <libavcodec/avcodec.h>
+  #include <libswscale/swscale.h>
+#else
+
+// if the header path is not specified explicitly, let's deduce it
+#if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H
+
+#if defined(HAVE_GENTOO_FFMPEG)
+  #define HAVE_LIBAVCODEC_AVCODEC_H 1
+  #define HAVE_LIBAVFORMAT_AVFORMAT_H 1
+  #if defined(HAVE_FFMPEG_SWSCALE)
+    #define HAVE_LIBSWSCALE_SWSCALE_H 1
+  #endif
+#elif defined HAVE_FFMPEG
+  #define HAVE_FFMPEG_AVCODEC_H 1
+  #define HAVE_FFMPEG_AVFORMAT_H 1
+  #if defined(HAVE_FFMPEG_SWSCALE)
+    #define HAVE_FFMPEG_SWSCALE_H 1
+  #endif
+#endif
+
+#endif
+
+#if defined(HAVE_FFMPEG_AVCODEC_H)
+  #include <ffmpeg/avcodec.h>
+#endif
+#if defined(HAVE_FFMPEG_AVFORMAT_H)
+  #include <ffmpeg/avformat.h>
+#endif
+#if defined(HAVE_FFMPEG_SWSCALE_H)
+  #include <ffmpeg/swscale.h>
+#endif
+
+#if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
+  #include <libavformat/avformat.h>
+#endif
+#if defined(HAVE_LIBAVCODEC_AVCODEC_H)
+  #include <libavcodec/avcodec.h>
+#endif
+#if defined(HAVE_LIBSWSCALE_SWSCALE_H)
+  #include <libswscale/swscale.h>
+#endif
+
+#endif
 
 #ifdef __cplusplus
 }
 #endif
 
-#include "cap_ffmpeg_api.hpp"
-#include <assert.h>
-#include <algorithm>
-
 #if defined _MSC_VER && _MSC_VER >= 1200
 #pragma warning( default: 4244 4510 4512 4610 )
 #endif
@@ -67,6 +126,7 @@ extern "C" {
 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
 #endif
 
+
 #ifndef MKTAG
 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
 #endif
@@ -301,6 +361,7 @@ const AVCodecTag codec_bmp_tags[] = {
     { CODEC_ID_NONE, 0 },
 };
 
+
 struct Image_FFMPEG
 {
     unsigned char* data;
@@ -310,419 +371,488 @@ struct Image_FFMPEG
     int cn;
 };
 
-struct CvCapture_FFMPEG_2
+
+inline void _opencv_ffmpeg_free(void** ptr)
 {
-        CvCapture_FFMPEG_2(const char* filename);
-        CvCapture_FFMPEG_2(const CvCapture_FFMPEG_2& mf);
-        CvCapture_FFMPEG_2& operator=(const CvCapture_FFMPEG_2& mf);
-
-        ~CvCapture_FFMPEG_2();
-
-        bool open( const char* filename );
-        void close();
-        bool setProperty(int, double);
-        double getProperty(int);
-        bool grabFrame();
-        bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
-        void init();
-        bool reopen();
-
-        cv::Mat read();
-
-        void seek(int64_t frame_number);
-        void seek(double sec);
-
-        int64_t get_total_frames();
-        int64_t get_frame_number();
-
- private:
-        AVFormatContext * ic;
-        AVCodecContext  * avcodec_context;
-        AVCodec         * avcodec;
-        AVFrame         * picture;
-        AVFrame         * rgb_picture;
-        AVStream        * video_st;
-        AVPacket          packet;
-        Image_FFMPEG      frame;
-
-        #if defined(HAVE_FFMPEG_SWSCALE)
-        struct SwsContext *img_convert_ctx;
-        #endif
+    if(*ptr) free(*ptr);
+    *ptr = 0;
+}
+
 
-        char* filename;
+struct CvCapture_FFMPEG
+{
+    bool open( const char* filename );
+    void close();
 
-        int video_stream;
-        int64_t picture_pts;
+    double getProperty(int);
+    bool setProperty(int, double);
+    bool grabFrame();
+    bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
+
+    void init();
+    bool reopen();
 
-        size_t width, height;
-        int64_t frame_number;
+    void    seek(int64_t frame_number);
+    void    seek(double sec);
+    bool       slowSeek( int framenumber );
 
-        double eps_zero;
+    int64_t get_total_frames();
+    double  get_duration_sec();
+    double  get_fps();
+    int     get_bitrate();
 
-        double  get_duration_sec();
-        double  get_fps();
-        int     get_bitrate();
+    double  r2d(AVRational r);
+    int64_t dts_to_frame_number(int64_t dts);
+    double  dts_to_sec(int64_t dts);
 
-        double r2d(AVRational r);
-        int64_t dts_to_frame_number(int64_t dts);
-        double  dts_to_sec(int64_t dts);
+    AVFormatContext * ic;
+    AVCodecContext  * avcodec_context;
+    AVCodec         * avcodec;
+    int               video_stream;
+    AVStream        * video_st;
+    AVFrame         * picture;        
+    AVFrame           rgb_picture;    
+    int64_t           picture_pts;
+
+    AVPacket          packet;
+    Image_FFMPEG      frame;
+       #if defined(HAVE_FFMPEG_SWSCALE)
+               struct SwsContext *img_convert_ctx;
+       #endif
+
+    int64_t frame_number;
+
+    double eps_zero;
+/*
+   'filename' contains the filename of the videosource,
+   'filename==NULL' indicates that ffmpeg's seek support works
+   for the particular file.
+   'filename!=NULL' indicates that the slow fallback function is used for seeking,
+   and so the filename is needed to reopen the file on backward seeking.
+*/
+    char              * filename;
 };
 
-CvCapture_FFMPEG_2::CvCapture_FFMPEG_2(const char* filename) :
-ic(0), avcodec_context(0), avcodec(0),
-picture(0), rgb_picture(0), video_stream(-1),
-width(0), height(0), frame_number(0), eps_zero(0.000025)
+void CvCapture_FFMPEG::init()
 {
- av_register_all();
+    ic = 0;
+    video_stream = -1;
+    video_st = 0;
+    picture = 0;
+    picture_pts = 0;
+    memset( &rgb_picture, 0, sizeof(rgb_picture) );
+    memset( &frame, 0, sizeof(frame) );
+    filename = 0;
+    packet.data = NULL;
+       #if defined(HAVE_FFMPEG_SWSCALE)
+               img_convert_ctx = 0;
+       #endif
+
+    avcodec_context = 0;
+    avcodec = 0;
+    frame_number = 0;
+    eps_zero = 0.000025;
+}
 
- #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
-    avformat_network_init();
- #endif
 
- // Open video file
- avformat_open_input(&ic, filename, NULL, NULL);
+void CvCapture_FFMPEG::close()
+{
+    if( picture )
+    av_free(picture);
 
- // Find the first video stream
- for(int i = 0; i < static_cast<int>(ic->nb_streams); i++)
- {
-        struct AVCodecContext * cc = ic->streams[i]->codec;
-        // set number of threads
-        cc->thread_count = 2;
+    if( video_st )
+    {
+        #if LIBAVFORMAT_BUILD > 4628
+                avcodec_close( video_st->codec );
 
-        if(cc->codec_type == AVMEDIA_TYPE_VIDEO && video_stream == -1)
-        {
-            AVCodec * codec = avcodec_find_decoder(cc->codec_id);
+        #else
+                avcodec_close( &(video_st->codec) );
 
-            if (codec == NULL)
-                CV_Error(0, "Unsupported codec !!!");
+        #endif
+                video_st = NULL;
+    }
 
-            avcodec_open2(cc, codec, NULL);
-            video_stream = i;
-            break;
-        }
+    if ( avcodec_context )
+    {
+        #if LIBAVFORMAT_BUILD > 4628
+                avcodec_close( avcodec_context );
+
+        #else
+                avcodec_close( &avcodec_context );
+
+        #endif
+                avcodec_context = NULL;
     }
 
-    if(video_stream == -1)
-        CV_Error(0, "Didn't find a video stream");
+    if( ic )
+    {
+     #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
+               av_close_input_file(ic);
+        #else
+               avformat_close_input(&ic);
+     #endif
 
-    // Get a pointer to the codec context for the video stream
-    avcodec_context = ic->streams[video_stream]->codec;
+     ic = NULL;
+    }
 
-    // Allocate video frame
-    picture = avcodec_alloc_frame();
-}
+    if( rgb_picture.data[0] )
+    {
+        free( rgb_picture.data[0] );
+        rgb_picture.data[0] = 0;
+    }
 
-CvCapture_FFMPEG_2::CvCapture_FFMPEG_2(const CvCapture_FFMPEG_2& vr) :
-    ic(vr.ic),
-    avcodec_context (vr.avcodec_context),
-    avcodec(0),
-    picture(0),
-    rgb_picture(0),
-    video_stream(-1),
-    width(0), height(0),
-    frame_number(0),
-    eps_zero(0.000001) {}
-
-CvCapture_FFMPEG_2& CvCapture_FFMPEG_2::operator=(const CvCapture_FFMPEG_2& mf)
-{
-    ic = mf.ic;
-    avcodec_context  = mf.avcodec_context;
-    return *this;
+    // free last packet if exist
+    if (packet.data) {
+        av_free_packet (&packet);
+    }
+
+    init();
 }
 
-bool CvCapture_FFMPEG_2::open(const char* filename)
+
+/*
+    Used to reopen a video if the slower fallback function for seeking is used.
+*/
+bool CvCapture_FFMPEG::reopen()
 {
-    CvCapture_FFMPEG_2 cap(filename);
-    *this = cap;
+    if ( filename==NULL ) return false;
+
+       #if LIBAVFORMAT_BUILD > 4628
+               avcodec_close( video_st->codec );
+               avcodec_close( avcodec_context );
+       #else
+               avcodec_close( &video_st->codec );
+               avcodec_close( &avcodec_context );
+       #endif
+    #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
+        av_close_input_file(ic);
+    #else
+        avformat_close_input(&ic);
+    #endif
+
+    // reopen video
+    avformat_open_input(&ic, filename, NULL, NULL);
+    av_find_stream_info(ic);
+       #if LIBAVFORMAT_BUILD > 4628
+               AVCodecContext *enc = ic->streams[video_stream]->codec;
+       #else
+               AVCodecContext *enc = &ic->streams[video_stream]->codec;
+       #endif
+
+       #ifdef FF_API_THREAD_INIT
+               avcodec_thread_init(enc, std::min(get_number_of_cpus(), 16));
+       #endif
+
+       AVCodec *codec = avcodec_find_decoder(enc->codec_id);
+       #if FF_API_AVCODEC_OPEN
+               avcodec_open(enc, codec);
+       #else
+               avcodec_open_2(enc, codec, NULL);
+       #endif
+       video_st = ic->streams[video_stream];
+
+       // reset framenumber to zero
+       frame_number = 0;
+    picture_pts=0;
+
+    return true;
 }
 
-void CvCapture_FFMPEG_2::close()
+#ifndef AVSEEK_FLAG_FRAME
+    #define AVSEEK_FLAG_FRAME 0
+#endif
+#ifndef AVSEEK_FLAG_ANY
+    #define AVSEEK_FLAG_ANY 1
+#endif
+
+bool CvCapture_FFMPEG::open( const char* _filename )
 {
-    if( picture )
-    av_free(picture);
+    unsigned i;
+    bool valid = false;
 
-    if( video_st )
+    close();
+       
+       #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
+               avformat_network_init();
+       #endif
+
+    /* register all codecs, demux and protocols */
+    av_register_all();
+
+    #ifndef _DEBUG
+        // av_log_level = AV_LOG_QUIET;
+    #endif
+
+    int err = avformat_open_input(&ic, _filename, NULL, NULL);
+    if (err < 0) {
+        CV_WARN("Error opening file");
+        goto exit_func;
+    }
+    err = av_find_stream_info(ic);
+    if (err < 0) {
+        CV_WARN("Could not find codec parameters");
+        goto exit_func;
+    }
+    for(i = 0; i < ic->nb_streams; i++)
     {
-#if LIBAVFORMAT_BUILD > 4628
-        avcodec_close( video_st->codec );
-#else
-        avcodec_close( &video_st->codec );
-#endif
-        video_st = NULL;
+        #if LIBAVFORMAT_BUILD > 4628
+                AVCodecContext *enc = ic->streams[i]->codec;
+        #else
+                AVCodecContext *enc = &ic->streams[i]->codec;
+        #endif
+
+        #ifdef FF_API_THREAD_INIT
+                avcodec_thread_init(enc, get_number_of_cpus());
+        #else
+                enc->thread_count = get_number_of_cpus();
+        #endif
+
+        #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
+            #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 ||
+                #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
+                            avcodec_open2(enc, codec, NULL)
+                #else
+                            avcodec_open(enc, codec)
+                #endif
+                        < 0) goto exit_func;
+
+            video_stream = i;
+            video_st = ic->streams[i];
+            picture = avcodec_alloc_frame();
+
+            rgb_picture.data[0] = (uint8_t*)malloc(
+                                    avpicture_get_size( PIX_FMT_BGR24,
+                                    enc->width, enc->height ));
+            avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
+                    PIX_FMT_BGR24, enc->width, enc->height );
+
+            frame.width = enc->width;
+            frame.height = enc->height;
+            frame.cn = 3;
+            frame.step = rgb_picture.linesize[0];
+            frame.data = rgb_picture.data[0];
+            break;
+        }
     }
 
-    if( ic )
+    if(video_stream >= 0) valid = true;
+
+    // perform check if source is seekable via ffmpeg's seek function av_seek_frame(...)
+    err = av_seek_frame(ic, video_stream, 10, 0);
+    if (err < 0)
     {
-        av_close_input_file(ic);
-        ic = NULL;
+        filename=(char*)malloc(strlen(_filename)+1);
+        strcpy(filename, _filename);
+        // reopen videofile to 'seek' back to first frame
+        reopen();
     }
-
-    if( rgb_picture->data[0] )
+    else
     {
-        free( rgb_picture->data[0] );
-        rgb_picture->data[0] = 0;
+        // seek seems to work, so we don't need the filename,
+        // but we still need to seek back to filestart
+        filename=NULL;
+        int64_t ts    = video_st->first_dts;
+        int     flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD;
+        av_seek_frame(ic, video_stream, ts, flags);
     }
+exit_func:
 
-    // free last packet if exist
-    if (packet.data) {
-        av_free_packet (&packet);
-    }
+    if( !valid )
+        close();
 
-    init();
+    return valid;
 }
 
-bool CvCapture_FFMPEG_2::grabFrame()
+
+bool CvCapture_FFMPEG::grabFrame()
 {
     bool valid = false;
     static bool bFirstTime = true;
     int got_picture;
 
-    // First time we're called, set packet.data to NULL to indicate it
-    // doesn't have to be freed
-    if (bFirstTime) {
+    int count_errs = 0;
+    const int max_number_of_attempts = 64;
+
+    if (bFirstTime)
+    {
         bFirstTime = false;
         packet.data = NULL;
     }
 
-    if( !ic || !video_st )
-        return false;
+    if( !ic || !video_st )  return false;
 
-    // free last packet if exist
-    if (packet.data != NULL) {
+    if (packet.data != NULL)
+    {
         av_free_packet (&packet);
     }
 
     // get the next frame
-    while (!valid) {
+    while (!valid)
+    {
         int ret = av_read_frame(ic, &packet);
-        if (ret == AVERROR(EAGAIN))
-            continue;
-        if (ret < 0)
-            break;
 
-        if( packet.stream_index != video_stream ) {
+        if (ret == AVERROR(EAGAIN)) continue;
+
+        /* else if (ret < 0) break; */
+
+        if( packet.stream_index != video_stream )
+        {
                 av_free_packet (&packet);
+                count_errs++;
+                if (count_errs > max_number_of_attempts) break; else
                 continue;
-            }
+        }
 
+        // Decode video frame
         avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
 
-        if (got_picture) {
-            // we have a new picture, so memorize it
-            picture_pts = packet.pts;
-            valid = 1;
-        }
+            // Did we get a video frame?
+            if(got_picture)
+            {
+                          frame_number++;
+                          picture_pts = packet.pts;
+                          valid = true;
+                      }
+                      else
+                      {
+                          count_errs++;
+                          if (count_errs > max_number_of_attempts)
+                                  break;
+                      }
+
     }
 
     // return if we have a new picture or not
     return valid;
 }
 
-bool CvCapture_FFMPEG_2::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
+
+bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
 {
     if( !video_st || !picture->data[0] )
         return false;
 
-#if !defined(HAVE_FFMPEG_SWSCALE)
-#if LIBAVFORMAT_BUILD > 4628
-    img_convert( (AVPicture*)&rgb_picture, PIX_FMT_BGR24,
-                 (AVPicture*)picture,
-                 video_st->codec->pix_fmt,
-                 video_st->codec->width,
-                 video_st->codec->height );
-#else
-    img_convert( (AVPicture*)&rgb_picture, PIX_FMT_BGR24,
-                 (AVPicture*)picture,
-                 video_st->codec.pix_fmt,
-                 video_st->codec.width,
-                 video_st->codec.height );
-#endif
-#else
-    img_convert_ctx = sws_getContext(video_st->codec->width,
-                  video_st->codec->height,
-                  video_st->codec->pix_fmt,
-                  video_st->codec->width,
-                  video_st->codec->height,
-                  PIX_FMT_BGR24,
-                  SWS_BICUBIC,
-                  NULL, NULL, NULL);
-
-         sws_scale(img_convert_ctx, picture->data,
-             picture->linesize, 0,
-             video_st->codec->height,
-             rgb_picture->data, rgb_picture->linesize);
-    sws_freeContext(img_convert_ctx);
-#endif
-    *data = frame.data;
-    *step = frame.step;
-    *width = frame.width;
-    *height = frame.height;
-    *cn = frame.cn;
+    rgb_picture = *avcodec_alloc_frame();
 
-    return true;
-}
+    avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, video_st->codec->width, video_st->codec->height);
 
-void CvCapture_FFMPEG_2::init()
-{
-    ic = 0;
-    video_stream = -1;
-    video_st = 0;
-    picture = 0;
-    picture_pts = 0;
-    memset( &rgb_picture, 0, sizeof(rgb_picture) );
-    memset( &frame, 0, sizeof(frame) );
-    filename = 0;
-    packet.data = NULL;
-#if defined(HAVE_FFMPEG_SWSCALE)
-    img_convert_ctx = 0;
-#endif
-}
+    #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(6<<8)+0)
 
-bool CvCapture_FFMPEG_2::reopen()
-{
-    if ( filename==NULL ) return false;
+                    frame.width  = picture->width;
+                    frame.height = picture->height;
 
-#if LIBAVFORMAT_BUILD > 4628
-    avcodec_close( video_st->codec );
-#else
-    avcodec_close( &video_st->codec );
-#endif
-    av_close_input_file(ic);
+    #else
+                    frame.width = video_st->codec->width;
+                    frame.height = video_st->codec->height;
+    #endif
 
-// reopen video
-#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0)
-    av_open_input_file(&ic, filename, NULL, 0, NULL);
-#else
-    avformat_open_input(&ic, filename, NULL, NULL);
-#endif
+   img_convert_ctx = sws_getContext(
+                                                         video_st->codec->width, video_st->codec->height,
+                                                                   video_st->codec->pix_fmt,
+                                                                   video_st->codec->width, video_st->codec->height,
+                                                                   PIX_FMT_BGR24,
+                                                                   SWS_BICUBIC,
+                                                                   NULL, NULL, NULL
+                                                                  );
 
-    av_find_stream_info(ic);
+                          img_convert_ctx = sws_getCachedContext(
+                                                                   img_convert_ctx,
+                                                                   video_st->codec->width, video_st->codec->height,
+                                                                   video_st->codec->pix_fmt,
+                                                                   video_st->codec->width, video_st->codec->height,
+                                                                   PIX_FMT_BGR24,
+                                                                   SWS_BICUBIC,
+                                                                   NULL, NULL, NULL
+                                                                  );
 
-#if LIBAVFORMAT_BUILD > 4628
-    AVCodecContext *enc = ic->streams[video_stream]->codec;
-#else
-    AVCodecContext *enc = &ic->streams[video_stream]->codec;
-#endif
+              if (img_convert_ctx == NULL)
+                  CV_Error(0, "Cannot initialize the conversion context!");
 
-#if FF_API_THREAD_INIT
-    avcodec_thread_init(enc, std::min(get_number_of_cpus(), 16));
-#endif
+              sws_scale(
+                          img_convert_ctx,
+                          picture->data,
+                          picture->linesize,
+                          0, video_st->codec->height,
+                          rgb_picture.data,
+                          rgb_picture.linesize
+                       );
 
-    AVCodec *codec = avcodec_find_decoder(enc->codec_id);
-    avcodec_open(enc, codec);
-    video_st = ic->streams[video_stream];
+              sws_freeContext(img_convert_ctx);
 
-    // reset framenumber to zero
-    picture_pts=0;
+
+
+     frame_number++;
+
+    *data = frame.data;
+    *step = frame.step;
+    *width = frame.width;
+    *height = frame.height;
+    *cn = frame.cn;
 
     return true;
 }
 
-int64_t CvCapture_FFMPEG_2::get_frame_number()
-{
-    return frame_number;
-}
+#if defined(__APPLE__)
+#define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
+#else
+#define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE)
+#endif
 
-cv::Mat CvCapture_FFMPEG_2::read()
+double CvCapture_FFMPEG::getProperty( int property_id )
 {
-    int frame_finished = 0;
-    AVPacket packet;
+    // if( !capture || !video_st || !picture->data[0] ) return 0;
+    if( !video_st ) return 0;
 
-    int count_errs = 0;
-    const int max_number_of_attempts = 32;
+    // double frameScale = av_q2d (video_st->time_base) * av_q2d (video_st->r_frame_rate);
+    int64_t timestamp;
+    timestamp = picture_pts;
 
-    while(true)
+    switch( property_id )
     {
-        av_read_frame(ic, &packet);
-
-        if(packet.stream_index == video_stream)
-        {
-            // Decode video frame
-            avcodec_decode_video2(avcodec_context, picture, &frame_finished, &packet);
-
-            // Did we get a video frame?
-            if(frame_finished)
-            {
-                rgb_picture = avcodec_alloc_frame();
-
-                cv::Mat img(static_cast<int>(avcodec_context->height), static_cast<int>(avcodec_context->width), CV_8UC3);
-
-                uint8_t * buffer = reinterpret_cast<uint8_t *>(img.ptr(0));
-
-                avpicture_fill(reinterpret_cast<AVPicture*>(rgb_picture), buffer, PIX_FMT_RGB24, avcodec_context->width, avcodec_context->height);
-
-                #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(4<<8)+0)
-
-                                width  = picture->width;
-                                height = picture->height;
-                #else
-                                width = avcodec_context->width;
-                                height = avcodec_context->height;
-                #endif
-
-                struct SwsContext * img_convert_ctx = sws_getContext(
-                                                                     width, height,
-                                                                     avcodec_context->pix_fmt,
-                                                                     width, height,
-                                                                     PIX_FMT_BGR24,
-                                                                     SWS_BICUBIC,
-                                                                     NULL, NULL, NULL
-                                                                    );
-
-                            img_convert_ctx = sws_getCachedContext(
-                                                                     img_convert_ctx,
-                                                                     width, height,
-                                                                     avcodec_context->pix_fmt,
-                                                                     width, height,
-                                                                     PIX_FMT_BGR24,
-                                                                     SWS_BICUBIC,
-                                                                     NULL, NULL, NULL
-                                                                    );
-
-                if (img_convert_ctx == NULL)
-                    CV_Error(0, "Cannot initialize the conversion context!");
-
-                sws_scale(
-                            img_convert_ctx,
-                            picture->data,
-                            picture->linesize,
-                            0, height,
-                            rgb_picture->data,
-                            rgb_picture->linesize
-                         );
-
-                sws_freeContext(img_convert_ctx);
-
-                av_free(rgb_picture);
-
-                frame_number++;
-
-                //std::cout << "cur dts: " << ic->streams[video_stream]->cur_dts << std::endl;
-
-                return img;
-            }
-            else
-            {
-                count_errs ++;
-                if (count_errs > max_number_of_attempts)
-                        break;
-            }
-        }
-        else
-        {
-            count_errs ++;
-            if (count_errs > max_number_of_attempts)
-                    break;
-        }
+    case CV_FFMPEG_CAP_PROP_POS_MSEC:
+        return 1000.0*static_cast<int>(frame_number)/static_cast<int>(get_fps());
+        break;
+    case CV_FFMPEG_CAP_PROP_POS_FRAMES:
+        return (double)static_cast<int>(frame_number);
+        break;
+    case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
+        return r2d(ic->streams[video_stream]->time_base);
+        break;
+    case CV_FFMPEG_CAP_PROP_FRAME_COUNT:
+        return (double)static_cast<int>(get_total_frames());
+        break;
+    case CV_FFMPEG_CAP_PROP_FRAME_WIDTH:
+        return (double)frame.width;
+    break;
+    case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT:
+        return (double)frame.height;
+    break;
+    case CV_FFMPEG_CAP_PROP_FPS:
+#if LIBAVCODEC_BUILD > 4753
+        return av_q2d (video_st->r_frame_rate);
+#else
+        return (double)video_st->codec.frame_rate
+            / (double)video_st->codec.frame_rate_base;
+#endif
+    break;
+    case CV_FFMPEG_CAP_PROP_FOURCC:
+#if LIBAVFORMAT_BUILD > 4628
+        return (double)video_st->codec->codec_tag;
+#else
+        return (double)video_st->codec.codec_tag;
+#endif
+    break;
     }
 
-    // Free the packet that was allocated by av_read_frame
-    av_free_packet(&packet);
-
-    return cv::Mat();
+    return 0;
 }
 
-double CvCapture_FFMPEG_2::r2d(AVRational r)
+double CvCapture_FFMPEG::r2d(AVRational r)
 {
     if (r.num == 0 || r.den == 0)
     {
@@ -734,7 +864,7 @@ double CvCapture_FFMPEG_2::r2d(AVRational r)
     }
 }
 
-double CvCapture_FFMPEG_2::get_duration_sec()
+double CvCapture_FFMPEG::get_duration_sec()
 {
     double sec = static_cast<double>(ic->duration) / static_cast<double>(AV_TIME_BASE);
 
@@ -747,15 +877,16 @@ double CvCapture_FFMPEG_2::get_duration_sec()
     {
         sec = static_cast<double>(static_cast<int64_t>(ic->streams[video_stream]->duration)) * r2d(ic->streams[video_stream]->time_base);
     }
+
     return sec;
 }
 
-int CvCapture_FFMPEG_2::get_bitrate()
+int CvCapture_FFMPEG::get_bitrate()
 {
     return ic->bit_rate;
 }
 
-double CvCapture_FFMPEG_2::get_fps()
+double CvCapture_FFMPEG::get_fps()
 {
     double fps = r2d(ic->streams[video_stream]->r_frame_rate);
 
@@ -764,7 +895,6 @@ double CvCapture_FFMPEG_2::get_fps()
         fps = r2d(ic->streams[video_stream]->avg_frame_rate);
     }
 
-    // may be this is wrong
     if (fps < eps_zero)
     {
         fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base);
@@ -773,7 +903,7 @@ double CvCapture_FFMPEG_2::get_fps()
     return fps;
 }
 
-int64_t CvCapture_FFMPEG_2::get_total_frames()
+int64_t CvCapture_FFMPEG::get_total_frames()
 {
     int64_t nbf = ic->streams[video_stream]->nb_frames;
 
@@ -784,30 +914,21 @@ int64_t CvCapture_FFMPEG_2::get_total_frames()
     return nbf;
 }
 
-//#include <iostream>
-
-double round(double d)
-{
-    return std::floor(d + 0.5);
-}
-
-int64_t CvCapture_FFMPEG_2::dts_to_frame_number(int64_t dts)
+int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts)
 {
     double sec = dts_to_sec(dts);
     return static_cast<int64_t>(get_fps() * sec);
 }
 
-double  CvCapture_FFMPEG_2::dts_to_sec(int64_t dts)
+double CvCapture_FFMPEG::dts_to_sec(int64_t dts)
 {
     return static_cast<double>(dts - ic->streams[video_stream]->start_time) * r2d(ic->streams[video_stream]->time_base);
 }
 
-void CvCapture_FFMPEG_2::seek(int64_t frame_number)
+void CvCapture_FFMPEG::seek(int64_t frame_number)
 {
-    double sec = static_cast<double>(frame_number) / static_cast<double>(get_fps());
-    this->frame_number = std::min<int>(frame_number, get_total_frames());
-    seek(sec);
-    /* int64_t dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
+    frame_number = std::min(frame_number, get_total_frames());
+    int64_t dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
 
     if (abs(dts - 2 - frame_number) > 16)
     {
@@ -820,38 +941,38 @@ void CvCapture_FFMPEG_2::seek(int64_t frame_number)
 
     while(dts - 2 < frame_number)
     {
-        cv::Mat i = read();
-        if (i.empty())
-            break;
+        /* cv::Mat imag = read(); */
+        if (!grabFrame()) break;
 
         dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
-
-        //std::cout << "cur dts: " << ic->streams[video_stream]->cur_dts << " f: " << dts << std::endl;
-    } */
+    }
 }
 
-void CvCapture_FFMPEG_2::seek(double sec)
+void CvCapture_FFMPEG::seek(double sec)
 {
-   // seek(static_cast<int64_t>(sec * get_fps()));
-
-   int64_t time_stamp = ic->streams[video_stream]->start_time;
-   double  time_base  = av_q2d(ic->streams[video_stream]->time_base);
-   time_stamp += static_cast<int64_t>(sec / time_base);
-   av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD);
+    seek(static_cast<int64_t>(sec * get_fps()));
 }
 
-CvCapture_FFMPEG_2::~CvCapture_FFMPEG_2()
+// 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 )
 {
-    #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
-        av_close_input_file(ic);
-    #else
-        avformat_close_input(&ic);
-    #endif
+    if ( framenumber>picture_pts )
+    {
+        while ( picture_pts<framenumber )
+            if ( !grabFrame() ) return false;
+    }
+    else if ( framenumber<picture_pts )
+    {
+        reopen();
+        while ( picture_pts<framenumber )
+            if ( !grabFrame() ) return false;
+    }
+    return true;
 }
 
-bool CvCapture_FFMPEG_2::setProperty( int property_id, double value )
+bool CvCapture_FFMPEG::setProperty( int property_id, double value )
 {
-    if (!video_stream) return false;
+    if( !video_st ) return false;
 
     switch( property_id )
     {
@@ -859,46 +980,22 @@ bool CvCapture_FFMPEG_2::setProperty( int property_id, double value )
     case CV_FFMPEG_CAP_PROP_POS_FRAMES:
     case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
         {
-
             switch( property_id )
             {
             case CV_FFMPEG_CAP_PROP_POS_FRAMES:
-                seek(value/1000.0); break;
+                seek((int64_t)value);
                 break;
 
             case CV_FFMPEG_CAP_PROP_POS_MSEC:
-                seek(value);
+                seek(value/1000.0);
                 break;
 
             case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
-                seek(value*this->get_bitrate());
+                seek((int64_t)(value*ic->duration));
                 break;
             }
 
-            /* if ( filename )
-            {
-                // ffmpeg's seek doesn't work...
-                if (!slowSeek((int)timestamp))
-                {
-                    fprintf(stderr, "HIGHGUI ERROR: AVI: could not (slow) seek to position %0.3f\n",
-                        (double)timestamp / AV_TIME_BASE);
-                    return false;
-                }
-            }
-            else
-            {
-                int flags = AVSEEK_FLAG_ANY;
-                if (timestamp < ic->streams[video_stream]->cur_dts)
-                  flags |= AVSEEK_FLAG_BACKWARD;
-                int ret = av_seek_frame(ic, video_stream, timestamp, flags);
-                if (ret < 0)
-                {
-                    fprintf(stderr, "HIGHGUI ERROR: AVI: could not seek to position %0.3f\n",
-                            (double)timestamp / AV_TIME_BASE);
-                    return false;
-                }
-            }
-            picture_pts=(int64_t)value;*/
+            picture_pts=(int64_t)value;
         }
         break;
     default:
@@ -906,69 +1003,8 @@ bool CvCapture_FFMPEG_2::setProperty( int property_id, double value )
     }
 
     return true;
-
 }
 
-#if defined(__APPLE__)
-#define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
-#else
-#define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE)
-#endif
-
-double CvCapture_FFMPEG_2::getProperty( int property_id )
-{
-    // if( !capture || !video_st || !picture->data[0] ) return 0;
-    if( !video_stream ) return 0;
-
-    double frameScale = av_q2d (video_st->time_base) * av_q2d (video_st->r_frame_rate);
-    int64_t timestamp;
-    timestamp = picture_pts;
-
-    switch( property_id )
-    {
-    case CV_FFMPEG_CAP_PROP_POS_MSEC:
-        return 1000.0*static_cast<double>(dts_to_sec(frame_number));
-        break;
-
-    case CV_FFMPEG_CAP_PROP_POS_FRAMES:
-        return (double)static_cast<int>(get_frame_number());
-        break;
-
-    case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
-        return static_cast<double>(dts_to_frame_number(frame_number))/static_cast<double>(dts_to_sec(frame_number));
-        break;
-
-    case CV_FFMPEG_CAP_PROP_FRAME_COUNT:
-        return (double)static_cast<int>(get_total_frames());
-        break;
-
-    case CV_FFMPEG_CAP_PROP_FRAME_WIDTH:
-        return (double)static_cast<int>(width);
-    break;
-
-    case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT:
-        return (double)static_cast<int>(height);
-    break;
-
-    case CV_FFMPEG_CAP_PROP_FPS:
-#if LIBAVCODEC_BUILD > 4753
-        return av_q2d (video_st->r_frame_rate);
-#else
-        return (double)video_st->codec.frame_rate
-            / (double)video_st->codec.frame_rate_base;
-#endif
-    break;
-    case CV_FFMPEG_CAP_PROP_FOURCC:
-#if LIBAVFORMAT_BUILD > 4628
-        return (double)video_st->codec->codec_tag;
-#else
-        return (double)video_st->codec.codec_tag;
-#endif
-    break;
-    }
-
-return 0;
-}
 
 ///////////////// FFMPEG CvVideoWriter implementation //////////////////////////
 struct CvVideoWriter_FFMPEG
@@ -980,8 +1016,8 @@ struct CvVideoWriter_FFMPEG
 
     void init();
 
-    AVOutputFormat *fmt;
-    AVFormatContext *oc;
+    AVOutputFormat     * fmt;
+    AVFormatContext * oc;
     uint8_t         * outbuf;
     uint32_t          outbuf_size;
     FILE            * outfile;
@@ -1067,9 +1103,9 @@ void CvVideoWriter_FFMPEG::init()
     video_st = 0;
     input_pix_fmt = 0;
     memset(&temp_image, 0, sizeof(temp_image));
-#if defined(HAVE_FFMPEG_SWSCALE)
-    img_convert_ctx = 0;
-#endif
+       #if defined(HAVE_FFMPEG_SWSCALE)
+               img_convert_ctx = 0;
+       #endif
 }
 
 /**
@@ -1115,21 +1151,21 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
 
     st = av_new_stream(oc, 0);
     if (!st) {
-        /* CV_WARN("Could not allocate stream"); */
+        CV_WARN("Could not allocate stream");
         return NULL;
     }
 
-#if LIBAVFORMAT_BUILD > 4628
-    c = st->codec;
-#else
-    c = &(st->codec);
-#endif
+       #if LIBAVFORMAT_BUILD > 4628
+               c = st->codec;
+       #else
+               c = &(st->codec);
+       #endif
 
-#if LIBAVFORMAT_BUILD > 4621
-    c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
-#else
-    c->codec_id = oc->oformat->video_codec;
-#endif
+       #if LIBAVFORMAT_BUILD > 4621
+               c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
+       #else
+               c->codec_id = oc->oformat->video_codec;
+       #endif
 
     if(codec_id != CODEC_ID_NONE){
         c->codec_id = codec_id;
@@ -1157,30 +1193,30 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
         frame_rate_base*=10;
         frame_rate=(int)(fps*frame_rate_base + 0.5);
     }
-#if LIBAVFORMAT_BUILD > 4752
-    c->time_base.den = frame_rate;
-    c->time_base.num = frame_rate_base;
-    /* adjust time base for supported framerates */
-    if(codec && codec->supported_framerates){
-        const AVRational *p= codec->supported_framerates;
-        AVRational req = {frame_rate, frame_rate_base};
-        const AVRational *best=NULL;
-        AVRational best_error= {INT_MAX, 1};
-        for(; p->den!=0; p++){
-            AVRational error= av_sub_q(req, *p);
-            if(error.num <0) error.num *= -1;
-            if(av_cmp_q(error, best_error) < 0){
-                best_error= error;
-                best= p;
-            }
-        }
-        c->time_base.den= best->num;
-        c->time_base.num= best->den;
-    }
-#else
-    c->frame_rate = frame_rate;
-    c->frame_rate_base = frame_rate_base;
-#endif
+       #if LIBAVFORMAT_BUILD > 4752
+               c->time_base.den = frame_rate;
+               c->time_base.num = frame_rate_base;
+               /* adjust time base for supported framerates */
+               if(codec && codec->supported_framerates){
+                       const AVRational *p= codec->supported_framerates;
+                       AVRational req = {frame_rate, frame_rate_base};
+                       const AVRational *best=NULL;
+                       AVRational best_error= {INT_MAX, 1};
+                       for(; p->den!=0; p++){
+                               AVRational error= av_sub_q(req, *p);
+                               if(error.num <0) error.num *= -1;
+                               if(av_cmp_q(error, best_error) < 0){
+                                       best_error= error;
+                                       best= p;
+                               }
+                       }
+                       c->time_base.den= best->num;
+                       c->time_base.num= best->den;
+               }
+       #else
+               c->frame_rate = frame_rate;
+               c->frame_rate_base = frame_rate_base;
+       #endif
 
     c->gop_size = 12; /* emit one intra frame every twelve frames at most */
     c->pix_fmt = (PixelFormat) pixel_format;
@@ -1195,25 +1231,24 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
         /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */
         c->mb_decision=2;
     }
-#if LIBAVCODEC_VERSION_INT>0x000409
-    // some formats want stream headers to be seperate
-    if(oc->oformat->flags & AVFMT_GLOBALHEADER)
-    {
-        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
-    }
-#endif
+       #if LIBAVCODEC_VERSION_INT>0x000409
+               // some formats want stream headers to be seperate
+               if(oc->oformat->flags & AVFMT_GLOBALHEADER)
+               {
+                       c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+               }
+       #endif
 
     return st;
 }
 
 int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture )
 {
-
-#if LIBAVFORMAT_BUILD > 4628
-    AVCodecContext * c = video_st->codec;
-#else
-    AVCodecContext * c = &(video_st->codec);
-#endif
+       #if LIBAVFORMAT_BUILD > 4628
+               AVCodecContext * c = video_st->codec;
+       #else
+               AVCodecContext * c = &(video_st->codec);
+       #endif
     int out_size;
     int ret;
 
@@ -1241,11 +1276,11 @@ int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_
             AVPacket pkt;
             av_init_packet(&pkt);
 
-#if LIBAVFORMAT_BUILD > 4752
-            pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
-#else
-            pkt.pts = c->coded_frame->pts;
-#endif
+       #if LIBAVFORMAT_BUILD > 4752
+                               pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
+       #else
+                               pkt.pts = c->coded_frame->pts;
+       #endif
             if(c->coded_frame->key_frame)
                 pkt.flags |= PKT_FLAG_KEY;
             pkt.stream_index= video_st->index;
@@ -1269,50 +1304,50 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     bool ret = false;
 
     // typecast from opaque data type to implemented struct
-#if LIBAVFORMAT_BUILD > 4628
-    AVCodecContext *c = video_st->codec;
-#else
-    AVCodecContext *c = &(video_st->codec);
-#endif
-
-#if LIBAVFORMAT_BUILD < 5231
-    // It is not needed in the latest versions of the ffmpeg
-    if( c->codec_id == CODEC_ID_RAWVIDEO && origin != 1 )
-    {
-        if( !temp_image.data )
-        {
-            temp_image.step = (width*cn + 3) & -4;
-            temp_image.width = width;
-            temp_image.height = height;
-            temp_image.cn = cn;
-            temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
-        }
-        for( int y = 0; y < height; y++ )
-            memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn);
-        data = temp_image.data;
-        step = temp_image.step;
-    }
-#else
-    if( width*cn != step )
-    {
-        if( !temp_image.data )
-        {
-            temp_image.step = width*cn;
-            temp_image.width = width;
-            temp_image.height = height;
-            temp_image.cn = cn;
-            temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
-        }
-        if (origin == 1)
-            for( int y = 0; y < height; y++ )
-                memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step);
-        else
-            for( int y = 0; y < height; y++ )
-                memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step);
-        data = temp_image.data;
-        step = temp_image.step;
-    }
-#endif
+       #if LIBAVFORMAT_BUILD > 4628
+               AVCodecContext *c = video_st->codec;
+       #else
+               AVCodecContext *c = &(video_st->codec);
+       #endif
+
+       #if LIBAVFORMAT_BUILD < 5231
+               // It is not needed in the latest versions of the ffmpeg
+               if( c->codec_id == CODEC_ID_RAWVIDEO && origin != 1 )
+               {
+                       if( !temp_image.data )
+                       {
+                               temp_image.step = (width*cn + 3) & -4;
+                               temp_image.width = width;
+                               temp_image.height = height;
+                               temp_image.cn = cn;
+                               temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
+                       }
+                       for( int y = 0; y < height; y++ )
+                               memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn);
+                       data = temp_image.data;
+                       step = temp_image.step;
+               }
+       #else
+               if( width*cn != step )
+               {
+                       if( !temp_image.data )
+                       {
+                               temp_image.step = width*cn;
+                               temp_image.width = width;
+                               temp_image.height = height;
+                               temp_image.cn = cn;
+                               temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height);
+                       }
+                       if (origin == 1)
+                               for( int y = 0; y < height; y++ )
+                                       memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step);
+                       else
+                               for( int y = 0; y < height; y++ )
+                                       memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step);
+                       data = temp_image.data;
+                       step = temp_image.step;
+               }
+       #endif
 
     // check parameters
     if (input_pix_fmt == PIX_FMT_BGR24) {
@@ -1329,13 +1364,6 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
         assert(false);
     }
 
-    // check if buffer sizes match, i.e. image has expected format (size, channels, bitdepth, alignment)
-/*#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(37<<8)+0)
-    assert (image->imageSize == avpicture_get_size( (PixelFormat)input_pix_fmt, image->width, image->height ));
-#else
-    assert (image->imageSize == avpicture_get_size( input_pix_fmt, image->width, image->height ));
-#endif*/
-
     if ( c->pix_fmt != input_pix_fmt ) {
         assert( input_picture );
         // let input_picture point to the raw data buffer of 'image'
@@ -1397,11 +1425,11 @@ void CvVideoWriter_FFMPEG::close()
     av_write_trailer(oc);
 
     // free pictures
-#if LIBAVFORMAT_BUILD > 4628
-    if( video_st->codec->pix_fmt != input_pix_fmt){
-#else
-    if( video_st->codec.pix_fmt != input_pix_fmt){
-#endif
+       #if LIBAVFORMAT_BUILD > 4628
+               if( video_st->codec->pix_fmt != input_pix_fmt){
+       #else
+               if( video_st->codec.pix_fmt != input_pix_fmt){
+       #endif
         if(picture->data[0])
            free(picture->data[0]);
         picture->data[0] = 0;
@@ -1413,11 +1441,11 @@ void CvVideoWriter_FFMPEG::close()
     }
 
     /* close codec */
-#if LIBAVFORMAT_BUILD > 4628
-    avcodec_close(video_st->codec);
-#else
-    avcodec_close(&(video_st->codec));
-#endif
+       #if LIBAVFORMAT_BUILD > 4628
+               avcodec_close(video_st->codec);
+       #else
+               avcodec_close(&(video_st->codec));
+       #endif
 
     av_free(outbuf);
 
@@ -1430,13 +1458,15 @@ void CvVideoWriter_FFMPEG::close()
     if (!(fmt->flags & AVFMT_NOFILE)) {
         /* close the output file */
 
-    #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) && LIBAVCODEC_VERSION_INT <= ((54<<16)+(5<<8)+0)
-        url_fclose(oc->pb);
-    #else
-    #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
-        url_fclose(&oc->pb);
-#endif
-    #endif
+       #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
+       #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
+                       url_fclose(oc->pb);
+       #else
+                       url_fclose(&oc->pb);
+       #endif
+       #else
+                       avio_close(oc->pb);
+       #endif
 
     }
 
@@ -1471,11 +1501,11 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
 
     /* auto detect the output format from the name and fourcc code. */
 
-#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
-    fmt = av_guess_format(NULL, filename, NULL);
-#else
-    fmt = guess_format(NULL, filename, NULL);
-#endif
+       #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
+               fmt = av_guess_format(NULL, filename, NULL);
+       #else
+               fmt = guess_format(NULL, filename, NULL);
+       #endif
 
     if (!fmt)
         return false;
@@ -1489,21 +1519,21 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
     }
 
     /* Lookup codec_id for given fourcc */
-#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
-    if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE )
-        return false;
-#else
-   /*  const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
-    if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE )
-        return false; */
-#endif
+       #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
+               if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE )
+                       return false;
+       #else
+               const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
+               if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE )
+                       return false;
+       #endif
 
     // alloc memory for context
-#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
-    oc = avformat_alloc_context();
-#else
-    oc = av_alloc_format_context();
-#endif
+       #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
+               oc = avformat_alloc_context();
+       #else
+               oc = av_alloc_format_context();
+       #endif
     assert (oc);
 
     /* set file name */
@@ -1515,12 +1545,12 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
 
     // set a few optimal pixel formats for lossless codecs of interest..
     switch (codec_id) {
-#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
-    case CODEC_ID_JPEGLS:
-        // BGR24 or GRAY8 depending on is_color...
-        codec_pix_fmt = input_pix_fmt;
-        break;
-#endif
+       #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
+               case CODEC_ID_JPEGLS:
+                       // BGR24 or GRAY8 depending on is_color...
+                       codec_pix_fmt = input_pix_fmt;
+                       break;
+       #endif
     case CODEC_ID_HUFFYUV:
         codec_pix_fmt = PIX_FMT_YUV422P;
         break;
@@ -1546,19 +1576,20 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
 
     /* set the output parameters (must be done even if no
        parameters). */
-    #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
-
-    if (av_set_parameters(oc, NULL) < 0) {
+       #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
+               if (av_set_parameters(oc, NULL) < 0)
+       #else
+               if (avformat_write_header(oc, NULL) < 0)
+       #endif
+        {
         return false;
     }
 
-    #endif
-
-#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
-    av_dump_format(oc, 0, filename, 1);
-#else
-    dump_format(oc, 0, filename, 1);
-#endif
+       #if FF_API_DUMP_FORMAT
+               dump_format(oc, 0, filename, 1);
+       #else
+               av_dump_format(oc, 0, filename, 1);
+       #endif
 
     /* now that all the parameters are set, we can open the audio and
        video codecs and allocate the necessary encode buffers */
@@ -1569,11 +1600,11 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
     AVCodec *codec;
     AVCodecContext *c;
 
-#if LIBAVFORMAT_BUILD > 4628
-    c = (video_st->codec);
-#else
-    c = &(video_st->codec);
-#endif
+       #if LIBAVFORMAT_BUILD > 4628
+               c = (video_st->codec);
+       #else
+               c = &(video_st->codec);
+       #endif
 
     c->codec_tag = fourcc;
     /* find the video encoder */
@@ -1621,105 +1652,97 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
     }
 
     /* open the output file, if needed */
-    #ifndef URL_RDONLY
-        #define URL_RDONLY 1
-    #endif
-    #ifndef URL_WRONLY
-       #define URL_WRONLY 2
-    #endif
-    #ifndef URL_RWONLY
-        #define URL_RWONLY (URL_RDONLY|URL_WRONLY)
-    #endif
-
-    if (!(fmt->flags & AVFMT_NOFILE))
-    {
-        #if LIBAVCODEC_VERSION_INT <= ((54<<16)+(5<<8)+0)
-        if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
+    if (!(fmt->flags & AVFMT_NOFILE)) {
+       #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
+                       if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
+       #else
+                               if (avio_open(&oc->pb, filename, 1) < 0)
+       #endif
         {
             return false;
         }
-        #endif
     }
 
     /* write the stream header, if any */
-#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
     avformat_write_header(oc, NULL);
-#else
-    av_write_header( oc );
-#endif
+
     return true;
 }
 
 
-CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
-                                                  int width, int height, int isColor )
+
+CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
 {
-    CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer));
-    writer->init();
-    if( writer->open( filename, fourcc, fps, width, height, isColor != 0 ))
-        return writer;
-    writer->close();
-    free(writer);
+    CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture));
+    capture->init();
+    if( capture->open( filename ))
+        return capture;
+    capture->close();
+    free(capture);
     return 0;
 }
 
 
-void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
+void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture)
 {
-    if( writer && *writer )
+    if( capture && *capture )
     {
-        (*writer)->close();
-        free(*writer);
-        *writer = 0;
+        (*capture)->close();
+        free(*capture);
+        *capture = 0;
     }
 }
 
-
-int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer,
-                         const unsigned char* data, int step,
-                         int width, int height, int cn, int origin)
-{
-    return writer->writeFrame(data, step, width, height, cn, origin);
-}
-
-int cvSetCaptureProperty_FFMPEG_2(CvCapture_FFMPEG_2* capture, int prop_id, double value)
+int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value)
 {
     return capture->setProperty(prop_id, value);
 }
 
-double cvGetCaptureProperty_FFMPEG_2(CvCapture_FFMPEG_2* capture, int prop_id)
+double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id)
 {
     return capture->getProperty(prop_id);
 }
 
-int cvGrabFrame_FFMPEG_2(CvCapture_FFMPEG_2* capture)
+int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture)
 {
     return capture->grabFrame();
 }
 
-int cvRetrieveFrame_FFMPEG_2(CvCapture_FFMPEG_2* capture, unsigned char** data, int* step, int* width, int* height, int* cn)
+int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn)
 {
     return capture->retrieveFrame(0, data, step, width, height, cn);
 }
 
-CvCapture_FFMPEG_2* cvCreateFileCapture_FFMPEG_2( const char* filename )
+
+
+CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
+                                                  int width, int height, int isColor )
 {
-    CvCapture_FFMPEG_2* capture = (CvCapture_FFMPEG_2*)malloc(sizeof(*capture));
-    capture->init();
-    if( capture->open( filename ))
-        return capture;
-    capture->close();
-    free(capture);
+    CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer));
+    writer->init();
+    if( writer->open( filename, fourcc, fps, width, height, isColor != 0 ))
+        return writer;
+    writer->close();
+    free(writer);
     return 0;
 }
 
-void cvReleaseCapture_FFMPEG_2(CvCapture_FFMPEG_2** capture)
+
+void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
 {
-    if( capture && *capture )
+    if( writer && *writer )
     {
-        (*capture)->close();
-        free(*capture);
-        *capture = 0;
+        (*writer)->close();
+        free(*writer);
+        *writer = 0;
     }
 }
 
+
+int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer,
+                         const unsigned char* data, int step,
+                         int width, int height, int cn, int origin)
+{
+    return writer->writeFrame(data, step, width, height, cn, origin);
+}
+
index 2ae7bc8..e2f4be9 100644 (file)
@@ -74,17 +74,17 @@ icvInitFFMPEG(void)
         if( icvFFOpenCV )
         {
             icvCreateFileCapture_FFMPEG_p =
-                (CvCreateFileCapture_Plugin)GetProcAddress(icvFFOpenCV, "cvCreateFileCapture_FFMPEG_2");
+                (CvCreateFileCapture_Plugin)GetProcAddress(icvFFOpenCV, "cvCreateFileCapture_FFMPEG");
             icvReleaseCapture_FFMPEG_p =
-                (CvReleaseCapture_Plugin)GetProcAddress(icvFFOpenCV, "cvReleaseCapture_FFMPEG_2");
+                (CvReleaseCapture_Plugin)GetProcAddress(icvFFOpenCV, "cvReleaseCapture_FFMPEG");
             icvGrabFrame_FFMPEG_p =
-                (CvGrabFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvGrabFrame_FFMPEG_2");
+                (CvGrabFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvGrabFrame_FFMPEG");
             icvRetrieveFrame_FFMPEG_p =
-                (CvRetrieveFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvRetrieveFrame_FFMPEG_2");
+                (CvRetrieveFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvRetrieveFrame_FFMPEG");
             icvSetCaptureProperty_FFMPEG_p =
-                (CvSetCaptureProperty_Plugin)GetProcAddress(icvFFOpenCV, "cvSetCaptureProperty_FFMPEG_2");
+                (CvSetCaptureProperty_Plugin)GetProcAddress(icvFFOpenCV, "cvSetCaptureProperty_FFMPEG");
             icvGetCaptureProperty_FFMPEG_p =
-                (CvGetCaptureProperty_Plugin)GetProcAddress(icvFFOpenCV, "cvGetCaptureProperty_FFMPEG_2");
+                (CvGetCaptureProperty_Plugin)GetProcAddress(icvFFOpenCV, "cvGetCaptureProperty_FFMPEG");
             icvCreateVideoWriter_FFMPEG_p =
                 (CvCreateVideoWriter_Plugin)GetProcAddress(icvFFOpenCV, "cvCreateVideoWriter_FFMPEG");
             icvReleaseVideoWriter_FFMPEG_p =
@@ -112,12 +112,12 @@ icvInitFFMPEG(void)
 #endif
         }
     #elif defined HAVE_FFMPEG
-        icvCreateFileCapture_FFMPEG_p = (CvCreateFileCapture_Plugin)cvCreateFileCapture_FFMPEG_2;
-        icvReleaseCapture_FFMPEG_p = (CvReleaseCapture_Plugin)cvReleaseCapture_FFMPEG_2;
-        icvGrabFrame_FFMPEG_p = (CvGrabFrame_Plugin)cvGrabFrame_FFMPEG_2;
-        icvRetrieveFrame_FFMPEG_p = (CvRetrieveFrame_Plugin)cvRetrieveFrame_FFMPEG_2;
-        icvSetCaptureProperty_FFMPEG_p = (CvSetCaptureProperty_Plugin)cvSetCaptureProperty_FFMPEG_2;
-        icvGetCaptureProperty_FFMPEG_p = (CvGetCaptureProperty_Plugin)cvGetCaptureProperty_FFMPEG_2;
+        icvCreateFileCapture_FFMPEG_p = (CvCreateFileCapture_Plugin)cvCreateFileCapture_FFMPEG;
+        icvReleaseCapture_FFMPEG_p = (CvReleaseCapture_Plugin)cvReleaseCapture_FFMPEG;
+        icvGrabFrame_FFMPEG_p = (CvGrabFrame_Plugin)cvGrabFrame_FFMPEG;
+        icvRetrieveFrame_FFMPEG_p = (CvRetrieveFrame_Plugin)cvRetrieveFrame_FFMPEG;
+        icvSetCaptureProperty_FFMPEG_p = (CvSetCaptureProperty_Plugin)cvSetCaptureProperty_FFMPEG;
+        icvGetCaptureProperty_FFMPEG_p = (CvGetCaptureProperty_Plugin)cvGetCaptureProperty_FFMPEG;
         icvCreateVideoWriter_FFMPEG_p = (CvCreateVideoWriter_Plugin)cvCreateVideoWriter_FFMPEG;
         icvReleaseVideoWriter_FFMPEG_p = (CvReleaseVideoWriter_Plugin)cvReleaseVideoWriter_FFMPEG;
         icvWriteFrame_FFMPEG_p = (CvWriteFrame_Plugin)cvWriteFrame_FFMPEG;
@@ -152,7 +152,7 @@ public:
         int step=0, width=0, height=0, cn=0;
 
         if(!ffmpegCapture ||
-           !icvRetrieveFrame_FFMPEG_p(ffmpegCapture, &data, &step, &width, &height, &cn))
+           !icvRetrieveFrame_FFMPEG_p(ffmpegCapture,&data,&step,&width,&height,&cn))
            return 0;
         cvInitImageHeader(&frame, cvSize(width, height), 8, cn);
         cvSetData(&frame, data, step);