diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ebd639..96fbd66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") +SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + add_subdirectory(lib) add_subdirectory(pipe) -add_subdirectory(app) \ No newline at end of file +add_subdirectory(app) diff --git a/README.md b/README.md index c55f4f4..f72a690 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ At a minimum, you will need an adapter that supports 802.11n 5GHz. Newer standar In practice, not all hardware/drivers appear to work at this time. Check the [Wireless Compatibility](https://github.com/vanilla-wiiu/vanilla/wiki/Wireless-Compatibility) page on the wiki to check if a card is confirmed working or not. ## Compiling (Linux) - +#### Note: Qt 6.4 or later is required! Vanilla currently requires the following dependencies: -- Debian/Ubuntu +- Debian/Ubuntu ``` # apt install qt6-base-dev qt6-multimedia-dev libavcodec-dev libavutil-dev libavfilter-dev libsdl2-dev libnl-genl-3-dev isc-dhcp-client ``` diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake new file mode 100644 index 0000000..bf28f8a --- /dev/null +++ b/cmake/FindFFmpeg.cmake @@ -0,0 +1,345 @@ +#[=======================================================================[.rst +FindFFmpeg +---------- + +FindModule for FFmpeg and associated libraries + +.. versionchanged:: 3.0 + Updated FindModule to CMake standards + +Components +^^^^^^^^^^ + +.. versionadded:: 1.0 + +This module contains provides several components: + +``avcodec`` +``avdevice`` +``avfilter`` +``avformat`` +``avutil`` +``postproc`` +``swscale`` +``swresample`` + +Import targets exist for each component. + +Imported Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 2.0 + +This module defines the :prop_tgt:`IMPORTED` targets: + +``FFmpeg::avcodec`` + AVcodec component + +``FFmpeg::avdevice`` + AVdevice component + +``FFmpeg::avfilter`` + AVfilter component + +``FFmpeg::avformat`` + AVformat component + +``FFmpeg::avutil`` + AVutil component + +``FFmpeg::postproc`` + postproc component + +``FFmpeg::swscale`` + SWscale component + +``FFmpeg::swresample`` + SWresample component + +Result Variables +^^^^^^^^^^^^^^^^ + +This module sets the following variables: + +``FFmpeg_FOUND`` + True, if all required components and the core library were found. +``FFmpeg_VERSION`` + Detected version of found FFmpeg libraries. +``FFmpeg_INCLUDE_DIRS`` + Include directories needed for FFmpeg. +``FFmpeg_LIBRARIES`` + Libraries needed to link to FFmpeg. +``FFmpeg_DEFINITIONS`` + Compiler flags required for FFmpeg. + +``FFmpeg__VERSION`` + Detected version of found FFmpeg component library. +``FFmpeg__INCLUDE_DIRS`` + Include directories needed for FFmpeg component. +``FFmpeg__LIBRARIES`` + Libraries needed to link to FFmpeg component. +``FFmpeg__DEFINITIONS`` + Compiler flags required for FFmpeg component. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``FFmpeg__LIBRARY`` + Path to the library component of FFmpeg. +``FFmpeg__INCLUDE_DIR`` + Directory containing ``.h``. + +#]=======================================================================] + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-lint: disable=C0307 +# cmake-format: on + +include(FindPackageHandleStandardArgs) + +set(_DEFAULT_COMPONENTS + avcodec + avdevice + avformat + avfilter + avresample + avutil + postproc + swscale + swresample) + +set(component_avcodec libavcodec avcodec avcodec.h) +set(component_avdevice libavdevice avdevice avdevice.h) +set(component_avformat libavformat avformat avformat.h) +set(component_avfilter libavfilter avfilter avfilter.h) +set(component_avresample libavresample avresample avresample.h) +set(component_avutil libavutil avutil avutil.h) +set(component_postproc libpostproc postproc postprocess.h) +set(component_swscale libswscale swscale swscale.h) +set(component_swresample libswresample swresample swresample.h) + +if(NOT FFmpeg_FIND_COMPONENTS) + set(FFmpeg_FIND_COMPONENTS ${_DEFAULT_COMPONENTS}) +endif() + +# FFmpeg_find_component: Find and set up requested FFmpeg component +macro(FFmpeg_find_component component) + list(GET component_${component} 0 component_libname) + list(GET component_${component} 1 component_name) + list(GET component_${component} 2 component_header) + + if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + pkg_search_module(PC_FFmpeg_${component} QUIET ${component_libname}) + endif() + endif() + + find_path( + FFmpeg_${component}_INCLUDE_DIR + NAMES ${component_libname}/${component_header} ${component_libname}/version.h + HINTS ${PC_FFmpeg_${component}_INCLUDE_DIRS} + PATHS /usr/include /usr/local/include + DOC "FFmpeg component ${component_name} include directory") + + ffmpeg_check_version() + + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + find_library( + FFmpeg_${component}_IMPLIB + NAMES ${component_libname} ${component_name} + DOC "FFmpeg component ${component_name} import library location") + + ffmpeg_find_dll() + else() + find_library( + FFmpeg_${component}_LIBRARY + NAMES ${component_libname} ${component_name} + HINTS ${PC_FFmpeg_${component}_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib + DOC "FFmpeg component ${component_name} location") + endif() + + if(FFmpeg_${component}_LIBRARY AND FFmpeg_${component}_INCLUDE_DIR) + set(FFmpeg_${component}_FOUND TRUE) + set(FFmpeg_${component}_LIBRARIES ${${_library_var}}) + set(FFmpeg_${component}_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIR}) + set(FFmpeg_${component}_DEFINITIONS ${PC_FFmpeg_${component}_CFLAGS_OTHER}) + mark_as_advanced(FFmpeg_${component}_LIBRARY FFmpeg_${component}_INCLUDE_DIR FFmpeg_${component}_IMPLIB) + endif() +endmacro() + +# FFmpeg_find_dll: Macro to find DLL for corresponding import library +macro(FFmpeg_find_dll) + cmake_path(GET FFmpeg_${component}_IMPLIB PARENT_PATH _implib_path) + cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") + + string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" _dll_version "${FFmpeg_${component}_VERSION}") + + find_program( + FFmpeg_${component}_LIBRARY + NAMES ${component_name}-${_dll_version}.dll + HINTS ${_implib_path} ${_bin_path} + DOC "FFmpeg component ${component_name} DLL location") + + if(NOT FFmpeg_${component}_LIBRARY) + set(FFmpeg_${component}_LIBRARY "${FFmpeg_${component}_IMPLIB}") + endif() + + unset(_implib_path) + unset(_bin_path) + unset(_dll_version) +endmacro() + +# FFmpeg_check_version: Macro to help extract version number from FFmpeg headers +macro(FFmpeg_check_version) + if(PC_FFmpeg_${component}_VERSION) + set(FFmpeg_${component}_VERSION ${PC_FFmpeg_${component}_VERSION}) + elseif(EXISTS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h") + if(EXISTS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version_major.h") + file(STRINGS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version_major.h" _version_string + REGEX "^.*VERSION_MAJOR[ \t]+[0-9]+[ \t]*$") + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") + + file(STRINGS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h" _version_string + REGEX "^.*VERSION_(MINOR|MICRO)[ \t]+[0-9]+[ \t]*$") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") + string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _version_patch "${_version_string}") + else() + file(STRINGS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h" _version_string + REGEX "^.*VERSION_(MAJOR|MINOR|MICRO)[ \t]+[0-9]+[ \t]*$") + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") + string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _version_patch "${_version_string}") + endif() + + set(FFmpeg_${component}_VERSION "${_version_major}.${_version_minor}.${_version_patch}") + unset(_version_major) + unset(_version_minor) + unset(_version_patch) + else() + if(NOT FFmpeg_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find ${component_name} version.") + endif() + set(FFmpeg_${component}_VERSION 0.0.0) + endif() +endmacro() + +# FFmpeg_set_soname: Set SONAME property on imported library targets +macro(FFmpeg_set_soname) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + execute_process( + COMMAND sh -c "otool -D '${FFmpeg_${component}_LIBRARY}' | grep -v '${FFmpeg_${component}_LIBRARY}'" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result) + + if(_result EQUAL 0 AND _output MATCHES "^@rpath/") + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_SONAME "${_output}") + endif() + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + execute_process( + COMMAND sh -c "objdump -p '${FFmpeg_${component}_LIBRARY}' | grep SONAME" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result) + + if(_result EQUAL 0) + string(REGEX REPLACE "[ \t]+SONAME[ \t]+([^ \t]+)" "\\1" _soname "${_output}") + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_SONAME "${_soname}") + unset(_soname) + endif() + endif() + unset(_output) + unset(_result) +endmacro() + +foreach(component IN LISTS FFmpeg_FIND_COMPONENTS) + if(NOT component IN_LIST _DEFAULT_COMPONENTS) + message(FATAL_ERROR "Unknown FFmpeg component specified: ${component}.") + endif() + + if(NOT FFmpeg_${component}_FOUND) + ffmpeg_find_component(${component}) + endif() + + if(FFmpeg_${component}_FOUND) + list(APPEND FFmpeg_LIBRARIES ${FFmpeg_${component}_LIBRARY}) + list(APPEND FFmpeg_DEFINITIONS ${FFmpeg_${component}_DEFINITIONS}) + list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIR}) + endif() +endforeach() + +if(NOT FFmpeg_avutil_FOUND) + ffmpeg_find_component(avutil) +endif() + +if(EXISTS "${FFmpeg_avutil_INCLUDE_DIR}/libavutil/ffversion.h") + file(STRINGS "${FFmpeg_avutil_INCLUDE_DIR}/libavutil/ffversion.h" _version_string + REGEX "^.*FFMPEG_VERSION[ \t]+\"n?[0-9a-z\\.-]+\"[ \t]*$") + string(REGEX REPLACE ".*FFMPEG_VERSION[ \t]+\"n?([0-9]+\\.[0-9]).*\".*" "\\1" FFmpeg_VERSION "${_version_string}") +endif() + +list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) +list(REMOVE_DUPLICATES FFmpeg_LIBRARIES) +list(REMOVE_DUPLICATES FFmpeg_DEFINITIONS) + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") + set(FFmpeg_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + set(FFmpeg_ERROR_REASON "Ensure that required FFmpeg libraries are installed on the system.") +endif() + +find_package_handle_standard_args( + FFmpeg + REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS + VERSION_VAR FFmpeg_VERSION + HANDLE_COMPONENTS REASON_FAILURE_MESSAGE "${FFmpeg_ERROR_REASON}") + +if(FFmpeg_FOUND AND NOT TARGET FFmpeg::FFmpeg) + add_library(FFmpeg::FFmpeg INTERFACE IMPORTED) +endif() + +foreach(component IN LISTS FFmpeg_FIND_COMPONENTS) + if(FFmpeg_${component}_FOUND AND NOT TARGET FFmpeg::${component}) + if(IS_ABSOLUTE "${FFmpeg_${component}_LIBRARY}") + if(DEFINED FFmpeg_${component}_IMPLIB) + if(FFmpeg_${component}_IMPLIB STREQUAL FFmpeg_${component}_LIBRARY) + add_library(FFmpeg::${component} STATIC IMPORTED) + else() + add_library(FFmpeg::${component} SHARED IMPORTED) + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_IMPLIB "${FFmpeg_${component}_IMPLIB}") + endif() + else() + add_library(FFmpeg::${component} UNKNOWN IMPORTED) + ffmpeg_set_soname() + endif() + + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_LOCATION "${FFmpeg_${component}_LIBRARY}") + + else() + add_library(FFmpeg::${component} INTERFACE IMPORTED) + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_LIBNAME "${FFmpeg_${component}_LIBRARY}") + endif() + set_target_properties( + FFmpeg::${component} + PROPERTIES INTERFACE_COMPILE_OPTIONS "${PC_FFmpeg_${component}_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${FFmpeg_${component}_INCLUDE_DIR}" + VERSION ${FFmpeg_${component}_VERSION}) + + get_target_property(_ffmpeg_interface_libraries FFmpeg::FFmpeg INTERFACE_LINK_LIBRARIES) + if(NOT FFmpeg::${component} IN_LIST _ffmpeg_interface_libraries) + set_property( + TARGET FFmpeg::FFmpeg + APPEND + PROPERTY INTERFACE_LINK_LIBRARIES FFmpeg::${component}) + endif() + endif() +endforeach() + +include(FeatureSummary) +set_package_properties( + FFmpeg PROPERTIES + URL "https://www.ffmpeg.org" + DESCRIPTION "A complete, cross-platform solution to record, convert and stream audio and video.")