aboutsummaryrefslogtreecommitdiff
path: root/cmake/modules/FindFFMPEG.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/modules/FindFFMPEG.cmake')
-rw-r--r--cmake/modules/FindFFMPEG.cmake292
1 files changed, 292 insertions, 0 deletions
diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake
new file mode 100644
index 0000000000..3d7fcc8ca3
--- /dev/null
+++ b/cmake/modules/FindFFMPEG.cmake
@@ -0,0 +1,292 @@
+# FindFFMPEG
+# --------
+# Finds FFmpeg libraries
+#
+# This module will first look for the required library versions on the system.
+# If they are not found, it will fall back to downloading and building kodi's own version
+#
+# --------
+# the following variables influence behaviour:
+# ENABLE_INTERNAL_FFMPEG - if enabled, kodi's own version will always be built
+#
+# FFMPEG_PATH - use external ffmpeg not found in system paths
+# usage: -DFFMPEG_PATH=/path/to/ffmpeg_install_prefix
+#
+# WITH_FFMPEG - use external ffmpeg not found in system paths
+# WARNING: this option is for developers as it will _disable ffmpeg version checks_!
+# Consider using FFMPEG_PATH instead, which _does_ check library versions
+# usage: -DWITH_FFMPEG=/path/to/ffmpeg_install_prefix
+#
+# --------
+# This module will will define the following variables:
+#
+# FFMPEG_FOUND - system has FFmpeg
+# FFMPEG_INCLUDE_DIRS - FFmpeg include directory
+# FFMPEG_LIBRARIES - FFmpeg libraries
+# FFMPEG_DEFINITIONS - pre-processor definitions
+# FFMPEG_LDFLAGS - linker flags
+#
+# and the following imported targets::
+#
+# ffmpeg - The FFmpeg libraries
+# --------
+#
+
+# required ffmpeg library versions
+set(REQUIRED_FFMPEG_VERSION 3.1)
+set(_avcodec_ver ">=57.48.101")
+set(_avfilter_ver ">=6.47.100")
+set(_avformat_ver ">=57.41.100")
+set(_avutil_ver ">=55.28.100")
+set(_swscale_ver ">=4.1.100")
+set(_swresample_ver ">=2.1.100")
+set(_postproc_ver ">=54.0.100")
+
+
+# Allows building with external ffmpeg not found in system paths,
+# without library version checks
+if(WITH_FFMPEG)
+ set(FFMPEG_PATH ${WITH_FFMPEG})
+ message(STATUS "Warning: FFmpeg version checking disabled")
+ set(REQUIRED_FFMPEG_VERSION undef)
+ unset(_avcodec_ver)
+ unset(_avfilter_ver)
+ unset(_avformat_ver)
+ unset(_avutil_ver)
+ unset(_swscale_ver)
+ unset(_swresample_ver)
+ unset(_postproc_ver)
+endif()
+
+# Allows building with external ffmpeg not found in system paths,
+# with library version checks
+if(FFMPEG_PATH)
+ set(ENABLE_INTERNAL_FFMPEG OFF)
+endif()
+
+# external FFMPEG
+if(NOT ENABLE_INTERNAL_FFMPEG OR KODI_DEPENDSBUILD)
+ if(FFMPEG_PATH)
+ set(ENV{PKG_CONFIG_PATH} "${FFMPEG_PATH}/lib/pkgconfig")
+ list(APPEND CMAKE_PREFIX_PATH ${FFMPEG_PATH})
+ endif()
+
+ set(FFMPEG_PKGS libavcodec${_avcodec_ver}
+ libavfilter${_avfilter_ver}
+ libavformat${_avformat_ver}
+ libavutil${_avutil_ver}
+ libswscale${_swscale_ver}
+ libswresample${_swresample_ver}
+ libpostproc${_postproc_ver})
+
+ if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PC_FFMPEG ${FFMPEG_PKGS} QUIET)
+ string(REGEX REPLACE "framework;" "framework " PC_FFMPEG_LDFLAGS "${PC_FFMPEG_LDFLAGS}")
+ endif()
+
+ find_path(FFMPEG_INCLUDE_DIRS libavcodec/avcodec.h libavfilter/avfilter.h libavformat/avformat.h
+ libavutil/avutil.h libswscale/swscale.h libpostproc/postprocess.h
+ PATH_SUFFIXES ffmpeg
+ PATHS ${PC_FFMPEG_INCLUDE_DIRS}
+ NO_DEFAULT_PATH)
+ find_path(FFMPEG_INCLUDE_DIRS libavcodec/avcodec.h libavfilter/avfilter.h libavformat/avformat.h
+ libavutil/avutil.h libswscale/swscale.h libpostproc/postprocess.h)
+
+ find_library(FFMPEG_LIBAVCODEC
+ NAMES avcodec libavcodec
+ PATH_SUFFIXES ffmpeg/libavcodec
+ PATHS ${PC_FFMPEG_libavcodec_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBAVCODEC NAMES avcodec libavcodec PATH_SUFFIXES ffmpeg/libavcodec)
+
+ find_library(FFMPEG_LIBAVFILTER
+ NAMES avfilter libavfilter
+ PATH_SUFFIXES ffmpeg/libavfilter
+ PATHS ${PC_FFMPEG_libavfilter_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBAVFILTER NAMES avfilter libavfilter PATH_SUFFIXES ffmpeg/libavfilter)
+
+ find_library(FFMPEG_LIBAVFORMAT
+ NAMES avformat libavformat
+ PATH_SUFFIXES ffmpeg/libavformat
+ PATHS ${PC_FFMPEG_libavformat_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBAVFORMAT NAMES avformat libavformat PATH_SUFFIXES ffmpeg/libavformat)
+
+ find_library(FFMPEG_LIBAVUTIL
+ NAMES avutil libavutil
+ PATH_SUFFIXES ffmpeg/libavutil
+ PATHS ${PC_FFMPEG_libavutil_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBAVUTIL NAMES avutil libavutil PATH_SUFFIXES ffmpeg/libavutil)
+
+ find_library(FFMPEG_LIBSWSCALE
+ NAMES swscale libswscale
+ PATH_SUFFIXES ffmpeg/libswscale
+ PATHS ${PC_FFMPEG_libswscale_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBSWSCALE NAMES swscale libswscale PATH_SUFFIXES ffmpeg/libswscale)
+
+ find_library(FFMPEG_LIBSWRESAMPLE
+ NAMES swresample libswresample
+ PATH_SUFFIXES ffmpeg/libswresample
+ PATHS ${PC_FFMPEG_libswresample_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBSWRESAMPLE NAMES NAMES swresample libswresample PATH_SUFFIXES ffmpeg/libswresample)
+
+ find_library(FFMPEG_LIBPOSTPROC
+ NAMES postproc libpostproc
+ PATH_SUFFIXES ffmpeg/libpostproc
+ PATHS ${PC_FFMPEG_libpostproc_LIBDIR}
+ NO_DEFAULT_PATH)
+ find_library(FFMPEG_LIBPOSTPROC NAMES postproc libpostproc PATH_SUFFIXES ffmpeg/libpostproc)
+
+ if((PC_FFMPEG_FOUND
+ AND PC_FFMPEG_libavcodec_VERSION
+ AND PC_FFMPEG_libavfilter_VERSION
+ AND PC_FFMPEG_libavformat_VERSION
+ AND PC_FFMPEG_libavutil_VERSION
+ AND PC_FFMPEG_libswscale_VERSION
+ AND PC_FFMPEG_libswresample_VERSION
+ AND PC_FFMPEG_libpostproc_VERSION)
+ OR WIN32)
+ set(FFMPEG_VERSION ${REQUIRED_FFMPEG_VERSION})
+
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(FFMPEG
+ VERSION_VAR FFMPEG_VERSION
+ REQUIRED_VARS FFMPEG_INCLUDE_DIRS
+ FFMPEG_LIBAVCODEC
+ FFMPEG_LIBAVFILTER
+ FFMPEG_LIBAVFORMAT
+ FFMPEG_LIBAVUTIL
+ FFMPEG_LIBSWSCALE
+ FFMPEG_LIBSWRESAMPLE
+ FFMPEG_LIBPOSTPROC
+ FFMPEG_VERSION
+ FAIL_MESSAGE "FFmpeg ${REQUIRED_FFMPEG_VERSION} not found, please consider using -DENABLE_INTERNAL_FFMPEG=ON")
+
+ else()
+ message(STATUS "FFmpeg ${REQUIRED_FFMPEG_VERSION} not found, falling back to internal build")
+ unset(FFMPEG_INCLUDE_DIRS)
+ unset(FFMPEG_INCLUDE_DIRS CACHE)
+ unset(FFMPEG_LIBRARIES)
+ unset(FFMPEG_LIBRARIES CACHE)
+ unset(FFMPEG_DEFINITIONS)
+ unset(FFMPEG_DEFINITIONS CACHE)
+ endif()
+
+ if(FFMPEG_FOUND)
+ set(FFMPEG_LDFLAGS ${PC_FFMPEG_LDFLAGS} CACHE STRING "ffmpeg linker flags")
+
+ # check if ffmpeg libs are statically linked
+ set(FFMPEG_LIB_TYPE SHARED)
+ foreach(_fflib IN LISTS FFMPEG_LIBRARIES)
+ if(${_fflib} MATCHES ".+\.a$" AND PC_FFMPEG_STATIC_LDFLAGS)
+ set(FFMPEG_LDFLAGS ${PC_FFMPEG_STATIC_LDFLAGS} CACHE STRING "ffmpeg linker flags" FORCE)
+ set(FFMPEG_LIB_TYPE STATIC)
+ break()
+ endif()
+ endforeach()
+
+ set(FFMPEG_LIBRARIES ${FFMPEG_LIBAVCODEC} ${FFMPEG_LIBAVFILTER}
+ ${FFMPEG_LIBAVFORMAT} ${FFMPEG_LIBAVUTIL}
+ ${FFMPEG_LIBSWSCALE} ${FFMPEG_LIBSWRESAMPLE}
+ ${FFMPEG_LIBPOSTPROC} ${FFMPEG_LDFLAGS})
+ list(APPEND FFMPEG_DEFINITIONS -DFFMPEG_VER_SHA=\"${FFMPEG_VERSION}\")
+
+ if(NOT TARGET ffmpeg)
+ add_library(ffmpeg ${FFMPEG_LIB_TYPE} IMPORTED)
+ set_target_properties(ffmpeg PROPERTIES
+ FOLDER "External Projects"
+ IMPORTED_LOCATION "${FFMPEG_LIBRARIES}"
+ INTERFACE_INCLUDE_DIRECTORIES "${FFMPEG_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES "${FFMPEG_LDFLAGS}"
+ INTERFACE_COMPILE_DEFINITIONS "${FFMPEG_DEFINITIONS}")
+ endif()
+ endif()
+endif()
+
+# Internal FFMPEG
+if(NOT FFMPEG_FOUND)
+ include(ExternalProject)
+ file(STRINGS ${CORE_SOURCE_DIR}/tools/depends/target/ffmpeg/FFMPEG-VERSION VER)
+ string(REGEX MATCH "VERSION=[^ ]*$.*" FFMPEG_VER "${VER}")
+ list(GET FFMPEG_VER 0 FFMPEG_VER)
+ string(SUBSTRING "${FFMPEG_VER}" 8 -1 FFMPEG_VER)
+ string(REGEX MATCH "BASE_URL=([^ ]*)" FFMPEG_BASE_URL "${VER}")
+ list(GET FFMPEG_BASE_URL 0 FFMPEG_BASE_URL)
+ string(SUBSTRING "${FFMPEG_BASE_URL}" 9 -1 FFMPEG_BASE_URL)
+
+ # allow user to override the download URL with a local tarball
+ # needed for offline build envs
+ if(FFMPEG_URL)
+ get_filename_component(FFMPEG_URL "${FFMPEG_URL}" ABSOLUTE)
+ else()
+ set(FFMPEG_URL ${FFMPEG_BASE_URL}/${FFMPEG_VER}.tar.gz)
+ endif()
+ if(VERBOSE)
+ message(STATUS "FFMPEG_URL: ${FFMPEG_URL}")
+ endif()
+
+ if(KODI_DEPENDSBUILD)
+ set(CROSS_ARGS -DDEPENDS_PATH=${DEPENDS_PATH}
+ -DPKG_CONFIG_EXECUTABLE=${PKG_CONFIG_EXECUTABLE}
+ -DCROSSCOMPILING=${CMAKE_CROSSCOMPILING}
+ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+ -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
+ -DCPU=${WITH_CPU}
+ -DOS=${OS}
+ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
+ -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
+ -DCMAKE_AR=${CMAKE_AR}
+ -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
+ -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS})
+ endif()
+
+ externalproject_add(ffmpeg
+ URL ${FFMPEG_URL}
+ DOWNLOAD_NAME ffmpeg-${FFMPEG_VER}.tar.gz
+ DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/download
+ PREFIX ${CORE_BUILD_DIR}/ffmpeg
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
+ -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+ -DFFMPEG_VER=${FFMPEG_VER}
+ -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
+ ${CROSS_ARGS}
+ PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+ ${CORE_SOURCE_DIR}/tools/depends/target/ffmpeg/CMakeLists.txt
+ <SOURCE_DIR> &&
+ ${CMAKE_COMMAND} -E copy
+ ${CORE_SOURCE_DIR}/tools/depends/target/ffmpeg/FindGnuTls.cmake
+ <SOURCE_DIR>)
+
+ file(WRITE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ffmpeg/ffmpeg-link-wrapper
+"#!/bin/bash
+if [[ $@ == *${APP_NAME_LC}.bin* || $@ == *${APP_NAME_LC}.so* || $@ == *${APP_NAME_LC}-test* ]]
+then
+ avformat=`PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/pkgconfig ${PKG_CONFIG_EXECUTABLE} --libs --static libavcodec`
+ avcodec=`PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/pkgconfig ${PKG_CONFIG_EXECUTABLE} --libs --static libavformat`
+ avfilter=`PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/pkgconfig ${PKG_CONFIG_EXECUTABLE} --libs --static libavfilter`
+ avutil=`PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/pkgconfig ${PKG_CONFIG_EXECUTABLE} --libs --static libavutil`
+ swscale=`PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/pkgconfig ${PKG_CONFIG_EXECUTABLE} --libs --static libswscale`
+ swresample=`PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/pkgconfig ${PKG_CONFIG_EXECUTABLE} --libs --static libswresample`
+ gnutls=`PKG_CONFIG_PATH=${DEPENDS_PATH}/lib/pkgconfig/ ${PKG_CONFIG_EXECUTABLE} --libs-only-l --static --silence-errors gnutls`
+ $@ $avcodec $avformat $avcodec $avfilter $swscale $swresample -lpostproc $gnutls
+else
+ $@
+fi")
+ file(COPY ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ffmpeg/ffmpeg-link-wrapper
+ DESTINATION ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+ set(FFMPEG_LINK_EXECUTABLE "${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ffmpeg-link-wrapper <CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" PARENT_SCOPE)
+ set(FFMPEG_CREATE_SHARED_LIBRARY "${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ffmpeg-link-wrapper <CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" PARENT_SCOPE)
+ set(FFMPEG_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include)
+ list(APPEND FFMPEG_DEFINITIONS -DFFMPEG_VER_SHA=\"${FFMPEG_VER}\"
+ -DUSE_STATIC_FFMPEG=1)
+ set(FFMPEG_FOUND 1)
+ set_target_properties(ffmpeg PROPERTIES FOLDER "External Projects")
+endif()
+
+mark_as_advanced(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES FFMPEG_LDFLAGS FFMPEG_DEFINITIONS FFMPEG_FOUND)