From 39ff8a0d267d3b21c97991de43be19e9470b6388 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Sun, 27 Nov 2016 23:31:04 +0300 Subject: [PATCH] cmake: cleanup ffmpeg detection --- 3rdparty/ffmpeg/ffmpeg.cmake | 13 +++++ CMakeLists.txt | 15 +++--- cmake/OpenCVFindLibsVideo.cmake | 90 +++++++++------------------------ cmake/OpenCVUtils.cmake | 38 ++++++++++++++ cmake/checks/ffmpeg_test.cpp | 24 +++++++++ cmake/templates/cvconfig.h.in | 6 --- modules/videoio/src/cap_ffmpeg_impl.hpp | 44 +--------------- modules/videoio/src/ffmpeg_codecs.hpp | 19 +------ 8 files changed, 108 insertions(+), 141 deletions(-) create mode 100644 cmake/checks/ffmpeg_test.cpp diff --git a/3rdparty/ffmpeg/ffmpeg.cmake b/3rdparty/ffmpeg/ffmpeg.cmake index d89b0a5..259aea2 100644 --- a/3rdparty/ffmpeg/ffmpeg.cmake +++ b/3rdparty/ffmpeg/ffmpeg.cmake @@ -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}) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8337ec9..f399036 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/cmake/OpenCVFindLibsVideo.cmake b/cmake/OpenCVFindLibsVideo.cmake index 3f43717..b2b74b7 100644 --- a/cmake/OpenCVFindLibsVideo.cmake +++ b/cmake/OpenCVFindLibsVideo.cmake @@ -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) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 34b4565..9fc602b 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -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 index 0000000..7b49c38 --- /dev/null +++ b/cmake/checks/ffmpeg_test.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include +#include +#include +} + +#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; } diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index c4b147f..514d1f5 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -71,12 +71,6 @@ /* 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 diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index daa235e..fc5141e 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -75,48 +75,8 @@ extern "C" { #include #endif -#ifdef WIN32 - #define HAVE_FFMPEG_SWSCALE 1 - #include - #include -#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 -#endif -#if defined(HAVE_FFMPEG_SWSCALE_H) - #include -#endif - -#if defined(HAVE_LIBAVCODEC_AVCODEC_H) - #include -#endif -#if defined(HAVE_LIBSWSCALE_SWSCALE_H) - #include -#endif - -#endif +#include +#include #ifdef __cplusplus } diff --git a/modules/videoio/src/ffmpeg_codecs.hpp b/modules/videoio/src/ffmpeg_codecs.hpp index 42eded7..a2a7a3b 100644 --- a/modules/videoio/src/ffmpeg_codecs.hpp +++ b/modules/videoio/src/ffmpeg_codecs.hpp @@ -60,24 +60,7 @@ extern "C" { #include #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 -#endif - -#if defined(HAVE_LIBAVFORMAT_AVFORMAT_H) || defined(WIN32) - #include -#endif - -#endif +#include #ifdef __cplusplus } -- 2.7.4