cmake: cleanup ffmpeg detection
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Sun, 27 Nov 2016 20:31:04 +0000 (23:31 +0300)
committerAlexander Alekhin <alexander.alekhin@intel.com>
Thu, 1 Dec 2016 16:33:27 +0000 (19:33 +0300)
3rdparty/ffmpeg/ffmpeg.cmake
CMakeLists.txt
cmake/OpenCVFindLibsVideo.cmake
cmake/OpenCVUtils.cmake
cmake/checks/ffmpeg_test.cpp [new file with mode: 0644]
cmake/templates/cvconfig.h.in
modules/videoio/src/cap_ffmpeg_impl.hpp
modules/videoio/src/ffmpeg_codecs.hpp

index d89b0a5..259aea2 100644 (file)
@@ -23,3 +23,16 @@ ocv_download(PACKAGE ffmpeg_version.cmake
              DESTINATION_DIR ${CMAKE_CURRENT_LIST_DIR})
 
 include(${CMAKE_CURRENT_LIST_DIR}/ffmpeg_version.cmake)
+
+# Compatibility glue code
+set(FFMPEG_libavcodec_FOUND 1)
+set(FFMPEG_libavformat_FOUND 1)
+set(FFMPEG_libavutil_FOUND 1)
+set(FFMPEG_libswscale_FOUND 1)
+set(FFMPEG_libavresample_FOUND 1)
+
+set(FFMPEG_libavcodec_VERSION ${ALIASOF_libavcodec_VERSION})
+set(FFMPEG_libavformat_VERSION ${ALIASOF_libavformat_VERSION})
+set(FFMPEG_libavutil_VERSION ${ALIASOF_libavutil_VERSION})
+set(FFMPEG_libswscale_VERSION ${ALIASOF_libswscale_VERSION})
+set(FFMPEG_libavresample_VERSION ${ALIASOF_libavresample_VERSION})
index 8337ec9..f399036 100644 (file)
@@ -1070,19 +1070,18 @@ if(DEFINED WITH_1394)
   status("    DC1394 2.x:"     HAVE_DC1394_2       THEN "YES (ver ${ALIASOF_libdc1394-2_VERSION})" ELSE NO)
 endif(DEFINED WITH_1394)
 
-if(DEFINED WITH_FFMPEG)
+if(DEFINED WITH_FFMPEG OR HAVE_FFMPEG)
   if(WIN32)
     status("    FFMPEG:"       WITH_FFMPEG         THEN "YES (prebuilt binaries)"                  ELSE NO)
   else()
     status("    FFMPEG:"       HAVE_FFMPEG         THEN YES ELSE NO)
   endif()
-  status("      codec:"        HAVE_FFMPEG_CODEC   THEN "YES (ver ${ALIASOF_libavcodec_VERSION})"  ELSE NO)
-  status("      format:"       HAVE_FFMPEG_FORMAT  THEN "YES (ver ${ALIASOF_libavformat_VERSION})" ELSE NO)
-  status("      util:"         HAVE_FFMPEG_UTIL    THEN "YES (ver ${ALIASOF_libavutil_VERSION})"   ELSE NO)
-  status("      swscale:"      HAVE_FFMPEG_SWSCALE THEN "YES (ver ${ALIASOF_libswscale_VERSION})"  ELSE NO)
-  status("      resample:"     HAVE_FFMPEG_RESAMPLE THEN "YES (ver ${ALIASOF_libavresample_VERSION})"  ELSE NO)
-  status("      gentoo-style:" HAVE_GENTOO_FFMPEG  THEN YES                                        ELSE NO)
-endif(DEFINED WITH_FFMPEG)
+  status("      avcodec:"      FFMPEG_libavcodec_FOUND    THEN "YES (ver ${FFMPEG_libavcodec_VERSION})"    ELSE NO)
+  status("      avformat:"     FFMPEG_libavformat_FOUND   THEN "YES (ver ${FFMPEG_libavformat_VERSION})"   ELSE NO)
+  status("      avutil:"       FFMPEG_libavutil_FOUND     THEN "YES (ver ${FFMPEG_libavutil_VERSION})"     ELSE NO)
+  status("      swscale:"      FFMPEG_libswscale_FOUND    THEN "YES (ver ${FFMPEG_libswscale_VERSION})"    ELSE NO)
+  status("      avresample:"   FFMPEG_libavresample_FOUND THEN "YES (ver ${FFMPEG_libavresample_VERSION})" ELSE NO)
+endif()
 
 if(DEFINED WITH_GSTREAMER)
   status("    GStreamer:"      HAVE_GSTREAMER      THEN ""                                         ELSE NO)
index 3f43717..b2b74b7 100644 (file)
@@ -213,79 +213,35 @@ if(WITH_XIMEA)
 endif(WITH_XIMEA)
 
 # --- FFMPEG ---
-ocv_clear_vars(HAVE_FFMPEG HAVE_FFMPEG_CODEC HAVE_FFMPEG_FORMAT HAVE_FFMPEG_UTIL HAVE_FFMPEG_SWSCALE HAVE_FFMPEG_RESAMPLE HAVE_GENTOO_FFMPEG HAVE_FFMPEG_FFMPEG)
+ocv_clear_vars(HAVE_FFMPEG)
 if(WITH_FFMPEG)
   if(WIN32 AND NOT ARM)
     include("${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/ffmpeg.cmake")
-  elseif(UNIX)
-    CHECK_MODULE(libavcodec HAVE_FFMPEG_CODEC)
-    CHECK_MODULE(libavformat HAVE_FFMPEG_FORMAT)
-    CHECK_MODULE(libavutil HAVE_FFMPEG_UTIL)
-    CHECK_MODULE(libswscale HAVE_FFMPEG_SWSCALE)
-    CHECK_MODULE(libavresample HAVE_FFMPEG_RESAMPLE)
-
-    CHECK_INCLUDE_FILE(libavformat/avformat.h HAVE_GENTOO_FFMPEG)
-    CHECK_INCLUDE_FILE(ffmpeg/avformat.h HAVE_FFMPEG_FFMPEG)
-    if(NOT HAVE_GENTOO_FFMPEG AND NOT HAVE_FFMPEG_FFMPEG)
-      if((NOT CMAKE_CROSSCOMPILING AND EXISTS /usr/include/ffmpeg/libavformat/avformat.h) OR HAVE_FFMPEG_SWSCALE)
-        set(HAVE_GENTOO_FFMPEG TRUE)
-      endif()
+    set(HAVE_FFMPEG TRUE)
+  elseif(PKG_CONFIG_FOUND)
+    ocv_check_modules(FFMPEG libavcodec libavformat libavutil libswscale)
+    ocv_check_modules(FFMPEG_libavresample libavresample)
+    if(FFMPEG_libavresample_FOUND)
+      ocv_append_build_options(FFMPEG FFMPEG_libavresample)
     endif()
-    if(HAVE_FFMPEG_CODEC AND HAVE_FFMPEG_FORMAT AND HAVE_FFMPEG_UTIL AND HAVE_FFMPEG_SWSCALE)
-      set(HAVE_FFMPEG TRUE)
-    endif()
-
     if(HAVE_FFMPEG)
-      # Find the bzip2 library because it is required on some systems
-      FIND_LIBRARY(BZIP2_LIBRARIES NAMES bz2 bzip2 libbz2.so.1)
-    else()
-      find_path(FFMPEG_INCLUDE_DIR "libavformat/avformat.h"
-                PATHS /usr/local /usr /opt
-                PATH_SUFFIXES include
-                DOC "The path to FFMPEG headers")
-      if(FFMPEG_INCLUDE_DIR)
-        set(HAVE_GENTOO_FFMPEG TRUE)
-        set(FFMPEG_LIB_DIR "${FFMPEG_INCLUDE_DIR}/../lib" CACHE PATH "Full path of FFMPEG library directory")
-        find_library(FFMPEG_CODEC_LIB "avcodec" HINTS "${FFMPEG_LIB_DIR}")
-        find_library(FFMPEG_FORMAT_LIB "avformat" HINTS "${FFMPEG_LIB_DIR}")
-        find_library(FFMPEG_UTIL_LIB "avutil" HINTS "${FFMPEG_LIB_DIR}")
-        find_library(FFMPEG_SWSCALE_LIB "swscale" HINTS "${FFMPEG_LIB_DIR}")
-        find_library(FFMPEG_RESAMPLE_LIB "avresample" HINTS "${FFMPEG_LIB_DIR}")
-        if(FFMPEG_CODEC_LIB)
-          set(HAVE_FFMPEG_CODEC 1)
-        endif()
-        if(FFMPEG_FORMAT_LIB)
-          set(HAVE_FFMPEG_FORMAT 1)
-        endif()
-        if(FFMPEG_UTIL_LIB)
-          set(HAVE_FFMPEG_UTIL 1)
-        endif()
-        if(FFMPEG_SWSCALE_LIB)
-          set(HAVE_FFMPEG_SWSCALE 1)
-        endif()
-        if(FFMPEG_CODEC_LIB AND FFMPEG_FORMAT_LIB AND
-           FFMPEG_UTIL_LIB AND FFMPEG_SWSCALE_LIB)
-          set(ALIASOF_libavcodec_VERSION "Unknown")
-          set(ALIASOF_libavformat_VERSION "Unknown")
-          set(ALIASOF_libavutil_VERSION "Unknown")
-          set(ALIASOF_libswscale_VERSION "Unknown")
-          set(HAVE_FFMPEG 1)
-          if(FFMPEG_RESAMPLE_LIB)
-            set(HAVE_FFMPEG_RESAMPLE 1)
-            set(ALIASOF_libavresample_VERSION "Unknown")
-          endif()
-        endif()
-      endif(FFMPEG_INCLUDE_DIR)
-      if(HAVE_FFMPEG)
-        set(VIDEOIO_LIBRARIES ${VIDEOIO_LIBRARIES} "${FFMPEG_LIB_DIR}/libavcodec.a"
-            "${FFMPEG_LIB_DIR}/libavformat.a" "${FFMPEG_LIB_DIR}/libavutil.a"
-            "${FFMPEG_LIB_DIR}/libswscale.a")
-        if(HAVE_FFMPEG_RESAMPLE)
-          set(VIDEOIO_LIBRARIES ${VIDEOIO_LIBRARIES} "${FFMPEG_LIB_DIR}/libavresample.a")
-        endif()
-        ocv_include_directories(${FFMPEG_INCLUDE_DIR})
-      endif(HAVE_FFMPEG)
+      try_compile(__VALID_FFMPEG
+          "${OpenCV_BINARY_DIR}"
+          "${OpenCV_SOURCE_DIR}/cmake/checks/ffmpeg_test.cpp"
+          CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${FFMPEG_INCLUDE_DIRS}"
+                      "-DLINK_DIRECTORIES:STRING=${FFMPEG_LIBRARY_DIRS}"
+                      "-DLINK_LIBRARIES:STRING=${FFMPEG_LIBRARIES}"
+          OUTPUT_VARIABLE TRY_OUT
+      )
+      if(NOT __VALID_FFMPEG)
+        #message(FATAL_ERROR "FFMPEG: test check build log:\n${TRY_OUT}")
+        message(STATUS "WARNING: Can't build ffmpeg test code")
+      else()
+        ocv_append_build_options(VIDEOIO FFMPEG)
+      endif()
     endif()
+  else()
+    message(STATUS "Can't find ffmpeg - 'pkg-config' utility is missing")
   endif()
 endif(WITH_FFMPEG)
 
index 34b4565..9fc602b 100644 (file)
@@ -398,6 +398,44 @@ macro(OCV_OPTION variable description value)
   unset(__value)
 endmacro()
 
+# Usage: ocv_append_build_options(HIGHGUI FFMPEG)
+macro(ocv_append_build_options var_prefix pkg_prefix)
+  foreach(suffix INCLUDE_DIRS LIBRARIES LIBRARY_DIRS)
+    if(${pkg_prefix}_${suffix})
+      list(APPEND ${var_prefix}_${suffix} ${${pkg_prefix}_${suffix}})
+      list(REMOVE_DUPLICATES ${var_prefix}_${suffix})
+    endif()
+  endforeach()
+endmacro()
+
+# Usage is similar to CMake 'pkg_check_modules' command
+# It additionally controls HAVE_${define} and ${define}_${modname}_FOUND variables
+macro(ocv_check_modules define)
+  unset(HAVE_${define})
+  foreach(m ${ARGN})
+    if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
+      set(__modname "${CMAKE_MATCH_1}")
+    else()
+      set(__modname "${m}")
+    endif()
+    unset(${define}_${__modname}_FOUND)
+  endforeach()
+  pkg_check_modules(${define} ${ARGN})
+  if(${define}_FOUND)
+    set(HAVE_${define} 1)
+  endif()
+  foreach(m ${ARGN})
+    if (m MATCHES "(.*[^><])(>=|=|<=)(.*)")
+      set(__modname "${CMAKE_MATCH_1}")
+    else()
+      set(__modname "${m}")
+    endif()
+    if(NOT DEFINED ${define}_${__modname}_FOUND AND ${define}_FOUND)
+      set(${define}_${__modname}_FOUND 1)
+    endif()
+  endforeach()
+endmacro()
+
 
 # Macros that checks if module have been installed.
 # After it adds module to build and define
diff --git a/cmake/checks/ffmpeg_test.cpp b/cmake/checks/ffmpeg_test.cpp
new file mode 100644 (file)
index 0000000..7b49c38
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+
+extern "C" {
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libswscale/swscale.h>
+}
+
+#define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c )
+
+static void test()
+{
+  AVFormatContext* c = 0;
+  AVCodec* avcodec = 0;
+  AVFrame* frame = 0;
+
+#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
+  int err = avformat_open_input(&c, "", NULL, NULL);
+#else
+  int err = av_open_input_file(&c, "", NULL, 0, NULL);
+#endif
+}
+
+int main() { test(); return 0; }
index c4b147f..514d1f5 100644 (file)
 /* FFMpeg video library */
 #cmakedefine HAVE_FFMPEG
 
-/* ffmpeg's libswscale */
-#cmakedefine HAVE_FFMPEG_SWSCALE
-
-/* ffmpeg in Gentoo */
-#cmakedefine HAVE_GENTOO_FFMPEG
-
 /* Geospatial Data Abstraction Library */
 #cmakedefine HAVE_GDAL
 
index daa235e..fc5141e 100644 (file)
@@ -75,48 +75,8 @@ extern "C" {
 #include <libavutil/imgutils.h>
 #endif
 
-#ifdef WIN32
-  #define HAVE_FFMPEG_SWSCALE 1
-  #include <libavcodec/avcodec.h>
-  #include <libswscale/swscale.h>
-#else
-
-#ifndef HAVE_FFMPEG_SWSCALE
-    #error "libswscale is necessary to build the newer OpenCV ffmpeg wrapper"
-#endif
-
-// 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
-  #if defined(HAVE_FFMPEG_SWSCALE)
-    #define HAVE_LIBSWSCALE_SWSCALE_H 1
-  #endif
-#elif defined HAVE_FFMPEG
-  #define HAVE_FFMPEG_AVCODEC_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_SWSCALE_H)
-  #include <ffmpeg/swscale.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
+#include <libavcodec/avcodec.h>
+#include <libswscale/swscale.h>
 
 #ifdef __cplusplus
 }
index 42eded7..a2a7a3b 100644 (file)
@@ -60,24 +60,7 @@ extern "C" {
 #include <errno.h>
 #endif
 
-// 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_LIBAVFORMAT_AVFORMAT_H 1
-#elif defined HAVE_FFMPEG
-  #define HAVE_FFMPEG_AVFORMAT_H 1
-#endif
-
-#if defined(HAVE_FFMPEG_AVFORMAT_H)
-  #include <ffmpeg/avformat.h>
-#endif
-
-#if defined(HAVE_LIBAVFORMAT_AVFORMAT_H) || defined(WIN32)
-  #include <libavformat/avformat.h>
-#endif
-
-#endif
+#include <libavformat/avformat.h>
 
 #ifdef __cplusplus
 }