static CvReleaseVideoWriter_Plugin icvReleaseVideoWriter_FFMPEG_p = 0;
static CvWriteFrame_Plugin icvWriteFrame_FFMPEG_p = 0;
-static cv::Mutex _icvInitFFMPEG_mutex;
-
-class icvInitFFMPEG
+static void
+icvInitFFMPEG(void)
{
-public:
- static void Init()
- {
- cv::AutoLock al(_icvInitFFMPEG_mutex);
- static icvInitFFMPEG init;
- }
-
-private:
- #if defined WIN32 || defined _WIN32
- HMODULE icvFFOpenCV;
-
- ~icvInitFFMPEG()
- {
- if (icvFFOpenCV)
- {
- FreeLibrary(icvFFOpenCV);
- icvFFOpenCV = 0;
- }
- }
- #endif
-
- icvInitFFMPEG()
+ static int ffmpegInitialized = 0;
+ if( !ffmpegInitialized )
{
#if defined WIN32 || defined _WIN32
const char* module_name = "opencv_ffmpeg"
#endif
".dll";
- icvFFOpenCV = LoadLibrary( module_name );
+ static HMODULE icvFFOpenCV = LoadLibrary( module_name );
if( icvFFOpenCV )
{
icvCreateFileCapture_FFMPEG_p =
icvReleaseVideoWriter_FFMPEG_p = (CvReleaseVideoWriter_Plugin)cvReleaseVideoWriter_FFMPEG;
icvWriteFrame_FFMPEG_p = (CvWriteFrame_Plugin)cvWriteFrame_FFMPEG;
#endif
+
+ ffmpegInitialized = 1;
}
-};
+}
class CvCapture_FFMPEG_proxy : public CvCapture
}
virtual bool open( const char* filename )
{
- icvInitFFMPEG::Init();
close();
+ icvInitFFMPEG();
if( !icvCreateFileCapture_FFMPEG_p )
return false;
ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename );
#endif
}
+
class CvVideoWriter_FFMPEG_proxy : public CvVideoWriter
{
public:
}
virtual bool open( const char* filename, int fourcc, double fps, CvSize frameSize, bool isColor )
{
- icvInitFFMPEG::Init();
close();
+ icvInitFFMPEG();
if( !icvCreateVideoWriter_FFMPEG_p )
return false;
ffmpegWriter = icvCreateVideoWriter_FFMPEG_p( filename, fourcc, fps, frameSize.width, frameSize.height, isColor );
#define AVSEEK_FLAG_ANY 1
#endif
-class ImplMutex
+static void icvInitFFMPEG_internal()
{
-public:
- ImplMutex();
- ~ImplMutex();
-
- void lock();
- bool trylock();
- void unlock();
-
- struct Impl;
-protected:
- Impl* impl;
-
-private:
- ImplMutex(const ImplMutex&);
- ImplMutex& operator = (const ImplMutex& m);
-};
-
-#if defined WIN32 || defined _WIN32 || defined WINCE
-
-struct ImplMutex::Impl
-{
- Impl() { InitializeCriticalSection(&cs); refcount = 1; }
- ~Impl() { DeleteCriticalSection(&cs); }
-
- void lock() { EnterCriticalSection(&cs); }
- bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
- void unlock() { LeaveCriticalSection(&cs); }
-
- CRITICAL_SECTION cs;
- int refcount;
-};
-
-#ifndef __GNUC__
-static int _interlockedExchangeAdd(int* addr, int delta)
-{
-#if defined _MSC_VER && _MSC_VER >= 1500
- return (int)_InterlockedExchangeAdd((long volatile*)addr, delta);
-#else
- return (int)InterlockedExchangeAdd((long volatile*)addr, delta);
-#endif
-}
-#endif // __GNUC__
-
-#elif defined __APPLE__
-
-#include <libkern/OSAtomic.h>
-
-struct ImplMutex::Impl
-{
- Impl() { sl = OS_SPINLOCK_INIT; refcount = 1; }
- ~Impl() {}
-
- void lock() { OSSpinLockLock(&sl); }
- bool trylock() { return OSSpinLockTry(&sl); }
- void unlock() { OSSpinLockUnlock(&sl); }
-
- OSSpinLock sl;
- int refcount;
-};
-
-#elif defined __linux__ && !defined ANDROID
-
-struct ImplMutex::Impl
-{
- Impl() { pthread_spin_init(&sl, 0); refcount = 1; }
- ~Impl() { pthread_spin_destroy(&sl); }
-
- void lock() { pthread_spin_lock(&sl); }
- bool trylock() { return pthread_spin_trylock(&sl) == 0; }
- void unlock() { pthread_spin_unlock(&sl); }
-
- pthread_spinlock_t sl;
- int refcount;
-};
-
-#else
-
-struct ImplMutex::Impl
-{
- Impl() { pthread_mutex_init(&sl, 0); refcount = 1; }
- ~Impl() { pthread_mutex_destroy(&sl); }
-
- void lock() { pthread_mutex_lock(&sl); }
- bool trylock() { return pthread_mutex_trylock(&sl) == 0; }
- void unlock() { pthread_mutex_unlock(&sl); }
-
- pthread_mutex_t sl;
- int refcount;
-};
-
-#endif
-
-ImplMutex::ImplMutex()
-{
- impl = new ImplMutex::Impl;
-}
-
-ImplMutex::~ImplMutex()
-{
- delete impl;
- impl = 0;
-}
-
-void ImplMutex::lock() { impl->lock(); }
-void ImplMutex::unlock() { impl->unlock(); }
-bool ImplMutex::trylock() { return impl->trylock(); }
-
-static int LockCallBack(void **mutex, AVLockOp op)
-{
- switch (op)
- {
- case AV_LOCK_CREATE:
- *mutex = reinterpret_cast<void*>(new ImplMutex());
- if (!*mutex)
- return 1;
- break;
-
- case AV_LOCK_OBTAIN:
- reinterpret_cast<ImplMutex*>(*mutex)->lock();
- break;
-
- case AV_LOCK_RELEASE:
- reinterpret_cast<ImplMutex*>(*mutex)->unlock();
- break;
-
- case AV_LOCK_DESTROY:
- ImplMutex* cv_mutex = reinterpret_cast<ImplMutex*>(*mutex);
- delete cv_mutex;
- cv_mutex = NULL;
- break;
- }
- return 0;
-}
-
-static ImplMutex _InternalFFMpegRegister_mutex;
-
-class InternalFFMpegRegister
-{
-public:
- static void Register()
- {
- _InternalFFMpegRegister_mutex.lock();
- static InternalFFMpegRegister init;
- _InternalFFMpegRegister_mutex.unlock();
- }
-
- ~InternalFFMpegRegister()
- {
- av_lockmgr_register(NULL);
- }
-
-private:
- InternalFFMpegRegister()
+ static volatile bool initialized = false;
+ if( !initialized )
{
-#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
+ #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
avformat_network_init();
-#endif
+ #endif
/* register all codecs, demux and protocols */
av_register_all();
- /* register a callback function for synchronization */
- av_lockmgr_register(&LockCallBack);
-
av_log_set_level(AV_LOG_ERROR);
+
+ initialized = true;
}
-};
+}
bool CvCapture_FFMPEG::open( const char* _filename )
{
- InternalFFMpegRegister::Register();
+ icvInitFFMPEG_internal();
+
unsigned i;
bool valid = false;
int err = av_open_input_file(&ic, _filename, NULL, 0, NULL);
#endif
- if (err < 0)
- {
+ if (err < 0) {
CV_WARN("Error opening file");
goto exit_func;
}
#else
av_find_stream_info(ic);
#endif
- if (err < 0)
- {
+ if (err < 0) {
CV_WARN("Could not find codec parameters");
goto exit_func;
}
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
#endif
- if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0)
- {
+ 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)
#else
avcodec_open(enc, codec)
#endif
- < 0)
- goto exit_func;
+ < 0) goto exit_func;
video_stream = i;
video_st = ic->streams[i];
bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
double fps, int width, int height, bool is_color )
{
- InternalFFMpegRegister::Register();
+ icvInitFFMPEG_internal();
CodecID codec_id = CODEC_ID_NONE;
int err, codec_pix_fmt;
frame_width = width;
frame_height = height;
ok = true;
-
return true;
}
capture->init();
if( capture->open( filename ))
return capture;
-
capture->close();
free(capture);
return 0;
return 0;
}
+
void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
{
if( writer && *writer )
bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, double fps)
{
- InternalFFMpegRegister::Register();
-
fmt_ = 0;
oc_ = 0;
video_st_ = 0;
+ // tell FFMPEG to register codecs
+ av_register_all();
+
+ av_log_set_level(AV_LOG_ERROR);
+
// 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);
bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
{
- InternalFFMpegRegister::Register();
-
int err;
ctx_ = 0;
avformat_network_init();
#endif
+ // register all codecs, demux and protocols
+ av_register_all();
+
+ av_log_set_level(AV_LOG_ERROR);
+
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
err = avformat_open_input(&ctx_, fileName, 0, 0);
#else
if (ret < 0)
{
- if (ret == (int)AVERROR_EOF)
+ if (ret == AVERROR_EOF)
*endOfFile = true;
return false;
}