Merge branch '2.4'
authorAndrey Kamaev <andrey.kamaev@itseez.com>
Mon, 18 Feb 2013 11:35:42 +0000 (15:35 +0400)
committerAndrey Kamaev <andrey.kamaev@itseez.com>
Mon, 18 Feb 2013 11:35:42 +0000 (15:35 +0400)
14 files changed:
1  2 
CMakeLists.txt
android/scripts/ABI_compat_generator.py
cmake/OpenCVDetectCUDA.cmake
cmake/OpenCVFindLibsPerf.cmake
cmake/templates/OpenCVConfig.cmake.in
doc/tutorials/definitions/tocDefinitions.rst
modules/gpu/include/opencv2/gpu/gpu.hpp
modules/gpu/perf4au/CMakeLists.txt
modules/gpu/src/cuda/matrix_reductions.cu
modules/gpu/test/test_core.cpp
modules/highgui/src/cap_ffmpeg.cpp
modules/highgui/src/cap_ffmpeg_impl.hpp
modules/video/doc/motion_analysis_and_object_tracking.rst
modules/video/include/opencv2/video/tracking.hpp

diff --cc CMakeLists.txt
@@@ -140,10 -141,9 +140,10 @@@ OCV_OPTION(WITH_V4L            "Includ
  OCV_OPTION(WITH_VIDEOINPUT     "Build HighGUI with DirectShow support"       ON   IF WIN32 )
  OCV_OPTION(WITH_XIMEA          "Include XIMEA cameras support"               OFF  IF (NOT ANDROID AND NOT APPLE) )
  OCV_OPTION(WITH_XINE           "Include Xine support (GPL)"                  OFF  IF (UNIX AND NOT APPLE AND NOT ANDROID) )
- OCV_OPTION(WITH_OPENCL         "Include OpenCL Runtime support"              OFF  IF (NOT ANDROID AND NOT IOS AND NOT CARMA) )
- OCV_OPTION(WITH_OPENCLAMDFFT   "Include AMD OpenCL FFT library support"      OFF  IF (NOT ANDROID AND NOT IOS AND NOT CARMA) )
- OCV_OPTION(WITH_OPENCLAMDBLAS  "Include AMD OpenCL BLAS library support"     OFF  IF (NOT ANDROID AND NOT IOS AND NOT CARMA) )
 +OCV_OPTION(WITH_CLP            "Include Clp support (EPL)"                   OFF)
+ OCV_OPTION(WITH_OPENCL         "Include OpenCL Runtime support"              OFF  IF (NOT ANDROID AND NOT IOS) )
+ OCV_OPTION(WITH_OPENCLAMDFFT   "Include AMD OpenCL FFT library support"      OFF  IF (NOT ANDROID AND NOT IOS) )
+ OCV_OPTION(WITH_OPENCLAMDBLAS  "Include AMD OpenCL BLAS library support"     OFF  IF (NOT ANDROID AND NOT IOS) )
  
  
  # OpenCV build components
  #!/usr/bin/python
  
+ from optparse import OptionParser
+ from shutil import rmtree
  import os
- import sys
- ANDROID_SDK_PATH = "/opt/android-sdk-linux"
- ANDROID_NDK_PATH = None
- INSTALL_DIRECTORY = None
- CLASS_PATH = None
- TMP_HEADER_PATH="tmp_include"
- HEADER_EXTS = set(['h', 'hpp'])
- SYS_INCLUDES = ["platforms/android-8/arch-arm/usr/include", "sources/cxx-stl/gnu-libstdc++/include", "sources/cxx-stl/gnu-libstdc++/libs/armeabi/include"]
- PROJECT_NAME = "OpenCV-branch"
- TARGET_LIBS = ["libopencv_java.so"]
- ARCH = "armeabi"
- GCC_OPTIONS = "-fpermissive"
- EXCLUDE_HEADERS = set(["hdf5.h", "eigen.hpp", "cxeigen.hpp"]);
- def FindClasses(root, prefix):
+ architecture = 'armeabi'
 -excludedHeaders = set(['hdf5.h', 'cap_ios.h', 
++excludedHeaders = set(['hdf5.h', 'cap_ios.h',
+     'eigen.hpp', 'cxeigen.hpp' #TOREMOVE
+     ])
+ systemIncludes = ['sources/cxx-stl/gnu-libstdc++/4.6/include', \
+     '/opt/android-ndk-r8c/platforms/android-8/arch-arm', # TODO: check if this one could be passed as command line arg
+     'sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include']
+ targetLibs = ['libopencv_java.so']
+ preamble = ['Eigen/Core']
+ # TODO: get gcc_options automatically
+ gcc_options = ['-fexceptions', '-frtti', '-Wno-psabi', '--sysroot=/opt/android-ndk-r8c/platforms/android-8/arch-arm', '-fpic', '-D__ARM_ARCH_5__', '-D__ARM_ARCH_5T__', '-D__ARM_ARCH_5E__', '-D__ARM_ARCH_5TE__', '-fsigned-char', '-march=armv5te', '-mtune=xscale', '-msoft-float', '-fdata-sections', '-ffunction-sections', '-Wa,--noexecstack   ', '-W', '-Wall', '-Werror=return-type', '-Werror=address', '-Werror=sequence-point', '-Wformat', '-Werror=format-security', '-Wmissing-declarations', '-Wundef', '-Winit-self', '-Wpointer-arith', '-Wshadow', '-Wsign-promo', '-Wno-narrowing', '-fdiagnostics-show-option', '-fomit-frame-pointer', '-mthumb', '-fomit-frame-pointer', '-O3', '-DNDEBUG ', '-DNDEBUG']
+ excludedOptionsPrefix = '-W'
+ def GetHeaderFiles(root):
+     headers = []
+     for path in os.listdir(root):
+         if not os.path.isdir(os.path.join(root, path)) \
+             and os.path.splitext(path)[1] in ['.h', '.hpp'] \
+             and not path in excludedHeaders:
+             headers.append(os.path.join(root, path))
+     return sorted(headers)
+ def GetClasses(root, prefix):
      classes = []
-     if ("" != prefix):
-     prefix = prefix + "."
+     if ('' != prefix):
+         prefix = prefix + '.'
      for path in os.listdir(root):
-     currentPath = os.path.join(root, path)
-     if (os.path.isdir(currentPath)):
-         classes += FindClasses(currentPath, prefix + path)
-     else:
-         name = str.split(path, ".")[0]
-         ext = str.split(path, ".")[1]
-         if (ext == "class"):
-         #print("class: %s" % (prefix + name))
-         classes.append(prefix+name)
+         currentPath = os.path.join(root, path)
+         if (os.path.isdir(currentPath)):
+             classes += GetClasses(currentPath, prefix + path)
+         else:
+             name = str.split(path, '.')[0]
+             ext = str.split(path, '.')[1]
+             if (ext == 'class'):
+                 classes.append(prefix + name)
      return classes
  
- def FindHeaders(root):
+ def GetJavaHHeaders():
+     print('\nGenerating JNI headers for Java API ...')
+     javahHeaders = os.path.join(managerDir, 'javah_generated_headers')
+     if os.path.exists(javahHeaders):
+         rmtree(javahHeaders)
+     os.makedirs(os.path.join(os.getcwd(), javahHeaders))
+     AndroidJavaDeps = os.path.join(SDK_path, 'platforms/android-11/android.jar')
+     classPath = os.path.join(managerDir, 'sdk/java/bin/classes')
+     if not os.path.exists(classPath):
+         print('Error: no Java classes found in \'%s\'' % classPath)
+         quit()
+     allJavaClasses = GetClasses(classPath, '')
+     if not allJavaClasses:
+         print('Error: no Java classes found')
+         quit()
+     for currentClass in allJavaClasses:
+         os.system('javah -d %s -classpath %s:%s %s' % (javahHeaders, classPath, \
+             AndroidJavaDeps, currentClass))
+     print('\nBuilding JNI headers list ...')
+     jniHeaders = GetHeaderFiles(javahHeaders)
+     return jniHeaders
+ def GetImmediateSubdirs(dir):
+     return [name for name in os.listdir(dir)
+             if os.path.isdir(os.path.join(dir, name))]
+ def GetOpenCVModules():
+     makefile = open(os.path.join(managerDir, 'sdk/native/jni/OpenCV.mk'), 'r')
+     makefileStr = makefile.read()
+     left = makefileStr.find('OPENCV_MODULES:=') + len('OPENCV_MODULES:=')
+     right = makefileStr[left:].find('\n')
+     modules = makefileStr[left:left+right].split()
+     modules = filter(lambda x: x != 'ts' and x != 'androidcamera', modules)
+     return modules
+ def FindHeaders():
      headers = []
-     for path in os.listdir(root):
-     currentPath = os.path.join(root, path)
-     if (os.path.isdir(currentPath)):
-         headers += FindHeaders(currentPath)
-     else:
-         ext = str.split(path, ".")[-1]
-         #print("%s: \"%s\"" % (currentPath, ext))
-         if (ext in HEADER_EXTS):
-         #print("Added as header file")
-         if (path not in EXCLUDE_HEADERS):
-             headers.append(currentPath)
+     print('\nBuilding Native OpenCV header list ...')
+     cppHeadersFolder = os.path.join(managerDir, 'sdk/native/jni/include/opencv2')
+     modulesFolders = GetImmediateSubdirs(cppHeadersFolder)
+     modules = GetOpenCVModules()
+     cppHeaders = []
+     for m in modules:
+         for f in modulesFolders:
+             moduleHeaders = []
+             if f == m:
+                 moduleHeaders += GetHeaderFiles(os.path.join(cppHeadersFolder, f))
+                 if m == 'flann':
 -                    flann = os.path.join(cppHeadersFolder, f, 'flann.hpp') 
++                    flann = os.path.join(cppHeadersFolder, f, 'flann.hpp')
+                     moduleHeaders.remove(flann)
+                     moduleHeaders.insert(0, flann)
+                 cppHeaders += moduleHeaders
+     cppHeaders += GetHeaderFiles(cppHeadersFolder)
+     headers += cppHeaders
+     cHeaders = GetHeaderFiles(os.path.join(managerDir, \
+         'sdk/native/jni/include/opencv'))
+     headers += cHeaders
+     headers += GetJavaHHeaders()
      return headers
  
- if (len(sys.argv) < 3):
-     print("Error: Invalid command line arguments")
-     exit(-1)
- INSTALL_DIRECTORY = sys.argv[1]
- PROJECT_NAME = sys.argv[2]
- CLASS_PATH = os.path.join(INSTALL_DIRECTORY, "sdk/java/bin/classes")
- if (not os.path.exists(CLASS_PATH)):
-     print("Error: no java classes found in \"%s\"" % CLASS_PATH)
-     exit(-2)
- if (os.environ.has_key("NDK_ROOT")):
-     ANDROID_NDK_PATH = os.environ["NDK_ROOT"];
-     print("Using Android NDK from NDK_ROOT (\"%s\")" % ANDROID_NDK_PATH)
- if (not ANDROID_NDK_PATH):
-     pipe = os.popen("which ndk-build")
-     tmp = str.strip(pipe.readline(), "\n")
-     while(not tmp):
-     tmp = str.strip(pipe.readline(), "\n")
-     pipe.close()
-     ANDROID_NDK_PATH = os.path.split(tmp)[0]
-     print("Using Android NDK from PATH (\"%s\")" % ANDROID_NDK_PATH)
- print("Using Android SDK from \"%s\"" % ANDROID_SDK_PATH)
- outputFileName = PROJECT_NAME + ".xml"
- try:
-     outputFile = open(outputFileName, "w")
- except:
-     print("Error: Cannot open output file \"%s\" for writing" % outputFileName)
- allJavaClasses = FindClasses(CLASS_PATH, "")
- if (not allJavaClasses):
-     print("Error: No Java classes found :(")
-     exit(-1)
- if (not os.path.exists(TMP_HEADER_PATH)):
-     os.makedirs(os.path.join(os.getcwd(), TMP_HEADER_PATH))
- print("Generating JNI headers for Java API ...")
- AndroidJavaDeps = os.path.join(ANDROID_SDK_PATH, "platforms/android-11/android.jar")
- for currentClass in allJavaClasses:
-     os.system("javah -d %s -classpath %s:%s %s" % (TMP_HEADER_PATH, CLASS_PATH, AndroidJavaDeps, currentClass))
- print("Building JNI headers list ...")
- jniHeaders = FindHeaders(TMP_HEADER_PATH)
- #print(jniHeaders)
- print("Building Native OpenCV header list ...")
- cHeaders = FindHeaders(os.path.join(INSTALL_DIRECTORY, "sdk/native/jni/include/opencv"))
- cppHeaders = FindHeaders(os.path.join(INSTALL_DIRECTORY, "sdk/native/jni/include/opencv2"))
- #print(cHeaders)
- #print(cppHeaders)
- print("Writing config file ...")
- outputFile.write("<descriptor>\n\n<version>\n\t%s\n</version>\n\n<headers>\n" % PROJECT_NAME)
- outputFile.write("\t"   + "\n\t".join(cHeaders))
- outputFile.write("\n\t" + "\n\t".join(cppHeaders))
- outputFile.write("\n\t" + "\n\t".join(jniHeaders))
- outputFile.write("\n</headers>\n\n")
- includes = [os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include"),
-     os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include", "opencv"),
-     os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include", "opencv2")]
- for inc in SYS_INCLUDES:
-     includes.append(os.path.join(ANDROID_NDK_PATH, inc))
- outputFile.write("<include_paths>\n\t%s\n</include_paths>\n\n" % "\n\t".join(includes))
- libraries = []
- for lib in TARGET_LIBS:
-     libraries.append(os.path.join(INSTALL_DIRECTORY, "sdk/native/libs", ARCH, lib))
- outputFile.write("<libs>\n\t%s\n</libs>\n\n" % "\n\t".join(libraries))
- outputFile.write("<gcc_options>\n\t%s\n</gcc_options>\n\n</descriptor>" % GCC_OPTIONS)
- print("done!")
+ def FindLibraries():
+     libraries = []
+     for lib in targetLibs:
+         libraries.append(os.path.join(managerDir, 'sdk/native/libs', architecture, lib))
+     return libraries
+ def FindIncludes():
+     includes = [os.path.join(managerDir, 'sdk', 'native', 'jni', 'include'),
+         os.path.join(managerDir, 'sdk', 'native', 'jni', 'include', 'opencv'),
+         os.path.join(managerDir, 'sdk', 'native', 'jni', 'include', 'opencv2')]
+     for inc in systemIncludes:
+         includes.append(os.path.join(NDK_path, inc))
+     return includes
+ def FilterGCCOptions():
+     gcc = filter(lambda x: not x.startswith(excludedOptionsPrefix), gcc_options)
+     return sorted(gcc)
+ def WriteXml(version, headers, includes, libraries):
+     xmlName = version + '.xml'
+     print '\noutput file: ' + xmlName
+     try:
+         xml = open(xmlName, 'w')
+     except:
+         print 'Error: Cannot open output file "%s" for writing' % xmlName
+         quit()
+     xml.write('<descriptor>')
+     xml.write('\n\n<version>')
+     xml.write('\n\t%s' % version)
+     xml.write('\n</version>')
+     xml.write('\n\n<headers>')
+     xml.write('\n\t%s' % '\n\t'.join(headers))
+     xml.write('\n</headers>')
+     xml.write('\n\n<include_paths>')
+     xml.write('\n\t%s' % '\n\t'.join(includes))
+     xml.write('\n</include_paths>')
+     # TODO: uncomment when Eigen problem is solved
+     # xml.write('\n\n<include_preamble>')
+     # xml.write('\n\t%s' % '\n\t'.join(preamble))
+     # xml.write('\n</include_preamble>')
+     xml.write('\n\n<libs>')
+     xml.write('\n\t%s' % '\n\t'.join(libraries))
+     xml.write('\n</libs>')
+     xml.write('\n\n<gcc_options>')
+     xml.write('\n\t%s' % '\n\t'.join(gcc_options))
+     xml.write('\n</gcc_options>')
+     xml.write('\n\n</descriptor>')
+ if __name__ == '__main__':
+     usage = '%prog <OpenCV_Manager install directory> <OpenCV_Manager version>'
+     parser = OptionParser(usage = usage)
+     args = parser.parse_args()
+     if 2 != len(args):
+         parser.print_help()
+         quit()
+     managerDir = args[1][0]
+     version = args[1][1]
+     NDK_path = '/opt/android-ndk-r8c'
+     print '\nUsing Android NDK from "%s"' % NDK_path
+     SDK_path = '~/NVPACK/android-sdk-linux'
+     print '\nUsing Android SDK from "%s"' % SDK_path
+     headers = FindHeaders()
+     includes = FindIncludes()
+     libraries = FindLibraries()
+     gcc_options = FilterGCCOptions()
+     WriteXml(version, headers, includes, libraries)
Simple merge
@@@ -44,41 -39,34 +39,73 @@@ if(WITH_EIGEN
    endif()
  endif(WITH_EIGEN)
  
- endif(WITH_CLP)
 +# --- Clp ---
 +# Ubuntu: sudo apt-get install coinor-libclp-dev coinor-libcoinutils-dev
 +ocv_clear_vars(HAVE_CLP)
 +if(WITH_CLP)
 +  if(UNIX)
 +    PKG_CHECK_MODULES(CLP clp)
 +    if(CLP_FOUND)
 +      set(HAVE_CLP TRUE)
 +      if(NOT ${CLP_INCLUDE_DIRS} STREQUAL "")
 +        ocv_include_directories(${CLP_INCLUDE_DIRS})
 +      endif()
 +      link_directories(${CLP_LIBRARY_DIRS})
 +      set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CLP_LIBRARIES})
 +    endif()
 +  endif()
 +
 +  if(NOT CLP_FOUND)
 +    find_path(CLP_INCLUDE_PATH "coin"
 +              PATHS "/usr/local/include" "/usr/include" "/opt/include"
 +              DOC "The path to Clp headers")
 +    if(CLP_INCLUDE_PATH)
 +      ocv_include_directories(${CLP_INCLUDE_PATH} "${CLP_INCLUDE_PATH}/coin")
 +      get_filename_component(_CLP_LIBRARY_DIR "${CLP_INCLUDE_PATH}/../lib" ABSOLUTE)
 +      set(CLP_LIBRARY_DIR "${_CLP_LIBRARY_DIR}" CACHE PATH "Full path of Clp library directory")
 +      link_directories(${CLP_LIBRARY_DIR})
 +      if(UNIX)
 +        set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils m)
 +      else()
 +        if(MINGW)
 +            set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils)
 +        else()
 +            set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libClp libCoinUtils)
 +        endif()
 +      endif()
 +      set(HAVE_CLP TRUE)
 +    endif()
 +  endif()
++endif(WITH_CLP)
++
+ # --- C= ---
+ if(WITH_CSTRIPES AND NOT HAVE_TBB)
+   include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCStripes.cmake")
+ else()
+   set(HAVE_CSTRIPES 0)
+ endif()
+ # --- OpenMP ---
+ if(NOT HAVE_TBB AND NOT HAVE_CSTRIPES)
+   set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/omptest.cpp")
+   FILE(WRITE "${_fname}" "#ifndef _OPENMP\n#error\n#endif\nint main() { return 0; }\n")
+   TRY_COMPILE(HAVE_OPENMP "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp" "${_fname}")
+ else()
+   set(HAVE_OPENMP 0)
+ endif()
+ # --- GCD ---
+ if(APPLE AND NOT HAVE_TBB AND NOT HAVE_CSTRIPES AND NOT HAVE_OPENMP)
+   set(HAVE_GCD 1)
+ else()
+   set(HAVE_GCD 0)
+ endif()
+ # --- Concurrency ---
+ if(MSVC AND NOT HAVE_TBB AND NOT HAVE_CSTRIPES AND NOT HAVE_OPENMP)
+   set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/concurrencytest.cpp")
+   FILE(WRITE "${_fname}" "#if _MSC_VER < 1600\n#error\n#endif\nint main() { return 0; }\n")
+   TRY_COMPILE(HAVE_CONCURRENCY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp" "${_fname}")
+ else()
+   set(HAVE_CONCURRENCY 0)
+ endif()
Simple merge
index 0000000,7452203..376e7b2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,28 +1,27 @@@
 -
+ set(PERF4AU_REQUIRED_DEPS opencv_core opencv_imgproc opencv_highgui opencv_video opencv_legacy opencv_gpu opencv_ts)
+ ocv_check_dependencies(${PERF4AU_REQUIRED_DEPS})
+ set(the_target gpu_perf4au)
+ project(${the_target})
+ ocv_include_modules(${PERF4AU_REQUIRED_DEPS})
+ if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS)
+     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
+ endif()
+ file(GLOB srcs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h *.hpp)
+ add_executable(${the_target} ${srcs})
+ target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${PERF4AU_REQUIRED_DEPS})
+ if(ENABLE_SOLUTION_FOLDERS)
+   set_target_properties(${the_target} PROPERTIES FOLDER "tests performance")
+ endif()
+ if(WIN32)
+     if(MSVC AND NOT BUILD_SHARED_LIBS)
+         set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG")
+     endif()
+ endif()
Simple merge
@@@ -117,13 -144,12 +144,12 @@@ private
          icvReleaseVideoWriter_FFMPEG_p = (CvReleaseVideoWriter_Plugin)cvReleaseVideoWriter_FFMPEG;
          icvWriteFrame_FFMPEG_p = (CvWriteFrame_Plugin)cvWriteFrame_FFMPEG;
      #endif
-         ffmpegInitialized = 1;
      }
- }
+ };
  
  
- class CvCapture_FFMPEG_proxy : public CvCapture
 -class CvCapture_FFMPEG_proxy : 
 -      public CvCapture
++class CvCapture_FFMPEG_proxy :
++    public CvCapture
  {
  public:
      CvCapture_FFMPEG_proxy() { ffmpegCapture = 0; }
          unsigned char* data = 0;
          int step=0, width=0, height=0, cn=0;
  
-         if(!ffmpegCapture ||
-            !icvRetrieveFrame_FFMPEG_p(ffmpegCapture,&data,&step,&width,&height,&cn))
-            return 0;
+         if (!ffmpegCapture ||
+            !icvRetrieveFrame_FFMPEG_p(ffmpegCapture, &data, &step, &width, &height, &cn))
 -                      return 0;
++            return 0;
          cvInitImageHeader(&frame, cvSize(width, height), 8, cn);
          cvSetData(&frame, data, step);
          return &frame;
@@@ -190,8 -216,8 +216,8 @@@ CvCapture* cvCreateFileCapture_FFMPEG_p
  #endif
  }
  
- class CvVideoWriter_FFMPEG_proxy : public CvVideoWriter
 -class CvVideoWriter_FFMPEG_proxy : 
 -      public CvVideoWriter
++class CvVideoWriter_FFMPEG_proxy :
++    public CvVideoWriter
  {
  public:
      CvVideoWriter_FFMPEG_proxy() { ffmpegWriter = 0; }
@@@ -332,23 -332,184 +332,184 @@@ void CvCapture_FFMPEG::close(
  #define AVSEEK_FLAG_ANY 1
  #endif
  
- static void icvInitFFMPEG_internal()
+ class ImplMutex
  {
-     static volatile bool initialized = false;
-     if( !initialized )
+ public:
 -      ImplMutex() { init(); }
 -      ~ImplMutex() { destroy(); }
 -      
++    ImplMutex() { init(); }
++    ~ImplMutex() { destroy(); }
++
+     void init();
+     void destroy();
+     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
+ {
+     void init() { InitializeCriticalSection(&cs); refcount = 1; }
+     void destroy() { 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
+ {
+     void init() { sl = OS_SPINLOCK_INIT; refcount = 1; }
+     void destroy() { }
+     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
+ {
+     void init() { pthread_spin_init(&sl, 0); refcount = 1; }
+     void destroy() { 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
+ {
+     void init() { pthread_mutex_init(&sl, 0); refcount = 1; }
+     void destroy() { 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
+ void ImplMutex::init()
+ {
 -      impl = (Impl*)malloc(sizeof(Impl));
 -      impl->init();
++    impl = (Impl*)malloc(sizeof(Impl));
++    impl->init();
+ }
 -void ImplMutex::destroy() 
++void ImplMutex::destroy()
+ {
 -      impl->destroy();
 -      free(impl);
 -      impl = NULL;
++    impl->destroy();
++    free(impl);
++    impl = NULL;
+ }
+ void ImplMutex::lock() { impl->lock(); }
+ void ImplMutex::unlock() { impl->unlock(); }
+ bool ImplMutex::trylock() { return impl->trylock(); }
+ static int LockCallBack(void **mutex, AVLockOp op)
+ {
+     ImplMutex* localMutex = reinterpret_cast<ImplMutex*>(*mutex);
+     switch (op)
      {
+         case AV_LOCK_CREATE:
+             localMutex = reinterpret_cast<ImplMutex*>(malloc(sizeof(ImplMutex)));
+             localMutex->init();
+             *mutex = localMutex;
+             if (!*mutex)
+                 return 1;
+         break;
+         case AV_LOCK_OBTAIN:
+             localMutex->lock();
+         break;
+         case AV_LOCK_RELEASE:
+             localMutex->unlock();
+         break;
+         case AV_LOCK_DESTROY:
+             localMutex->destroy();
+             free(localMutex);
+             localMutex = NULL;
+         break;
+     }
+     return 0;
+ }
+ static ImplMutex _mutex;
+ static bool _initialized = false;
+ class InternalFFMpegRegister
+ {
+ public:
+     InternalFFMpegRegister()
+     {
+         _mutex.lock();
+         if (!_initialized)
+         {
      #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
-         avformat_network_init();
+             avformat_network_init();
      #endif
  
-         /* register all codecs, demux and protocols */
-         av_register_all();
+             /* register all codecs, demux and protocols */
+             av_register_all();
  
-         av_log_set_level(AV_LOG_ERROR);
+             /* register a callback function for synchronization */
+             av_lockmgr_register(&LockCallBack);
  
-         initialized = true;
+             av_log_set_level(AV_LOG_ERROR);
+             _initialized = true;
+         }
+         _mutex.unlock();
      }
- }
+     ~InternalFFMpegRegister()
+     {
+         _initialized = false;
+         av_lockmgr_register(NULL);
+     }
+ };
+ static InternalFFMpegRegister _init;
  
  bool CvCapture_FFMPEG::open( const char* _filename )
  {