Skip to content

Commit

Permalink
Merge pull request #7 from norihiro/use-swr
Browse files Browse the repository at this point in the history
Use resampler library
  • Loading branch information
norihiro authored Dec 27, 2023
2 parents 1eeca28 + 186558b commit 83e98eb
Show file tree
Hide file tree
Showing 13 changed files with 782 additions and 108 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ jobs:

- name: Build plugin
run: |
sudo apt update
sudo apt install -y libsamplerate0 libsamplerate0-dev
OBS_QT_VERSION_MAJOR=${{ steps.obsdeps.outputs.OBS_QT_VERSION_MAJOR }}
mkdir build
cd build
Expand All @@ -66,6 +68,8 @@ jobs:
-D CMAKE_INSTALL_PREFIX=/usr \
-D CMAKE_BUILD_TYPE=RelWithDebInfo \
-D LINUX_PORTABLE=OFF \
-D USE_ERIKD_LIBSAMPLERATE_DEPS=OFF \
-D USE_ERIKD_LIBSAMPLERATE_SYSTEM=ON \
-D CPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON \
-D PKG_SUFFIX=-obs${{ matrix.obs }}-${{ matrix.ubuntu }}-x86_64 \
"${cmake_opt[@]}"
Expand Down Expand Up @@ -187,6 +191,8 @@ jobs:
-DCMAKE_OSX_ARCHITECTURES=${arch/#universal/x86_64;arm64} \
-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \
-DCMAKE_FRAMEWORK_PATH="$deps/Frameworks;$deps/lib/cmake;$deps" \
-D USE_ERIKD_LIBSAMPLERATE_DEPS=ON \
-D USE_ERIKD_LIBSAMPLERATE_SYSTEM=OFF \
-D PKG_SUFFIX=$PKG_SUFFIX \
"${cmake_opt[@]}"
cmake --build build --config RelWithDebInfo
Expand All @@ -201,10 +207,12 @@ jobs:
27)
(cd release/${PLUGIN_NAME} && ../../ci/macos/change-rpath.sh -obs ${{ matrix.obs }} -lib lib/ bin/${PLUGIN_NAME}.so)
cp LICENSE release/${PLUGIN_NAME}/data/LICENSE-$PLUGIN_NAME
cp deps/libsamplerate/COPYING release/${PLUGIN_NAME}/data/LICENSE-libsamplerate
;;
28)
(cd release/${PLUGIN_NAME}.plugin/Contents && ../../../ci/macos/change-rpath.sh -obs 28 -lib lib/ MacOS/${PLUGIN_NAME})
cp LICENSE release/${PLUGIN_NAME}.plugin/Contents/Resources/LICENSE-$PLUGIN_NAME
cp deps/libsamplerate/COPYING release/${PLUGIN_NAME}.plugin/Contents/Resources/LICENSE-libsamplerate
;;
esac
Expand Down Expand Up @@ -306,6 +314,8 @@ jobs:
'-DCMAKE_SYSTEM_VERSION=10.0.18363.657'
"-DCMAKE_INSTALL_PREFIX=$(Resolve-Path -Path "./obs-build-dependencies/plugin-deps-${{ matrix.arch }}")"
"-DCMAKE_PREFIX_PATH=$(Resolve-Path -Path "./obs-build-dependencies/plugin-deps-${{ matrix.arch }}")"
"-DUSE_ERIKD_LIBSAMPLERATE_DEPS=ON"
"-DUSE_ERIKD_LIBSAMPLERATE_SYSTEM=OFF"
)
cmake -S . -B build @CmakeArgs
cmake --build build --config RelWithDebInfo -j 4
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "deps/libsamplerate"]
path = deps/libsamplerate
url = https://github.com/libsndfile/libsamplerate.git
70 changes: 67 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,32 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(libobs REQUIRED)
include(cmake/ObsPluginHelpers.cmake)

find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_LIBSAMPLERATE samplerate)
endif()

if(PC_LIBSAMPLERATE_FOUND)
option(USE_ERIKD_LIBSAMPLERATE_DEPS "Use libsamplerate by Erik de Castro Lopo in deps" OFF)
option(USE_ERIKD_LIBSAMPLERATE_SYSTEM "Use libsamplerate by Erik de Castro Lopo in the system" ON)
else()
option(USE_ERIKD_LIBSAMPLERATE_DEPS "Use libsamplerate by Erik de Castro Lopo in deps" ON)
option(USE_ERIKD_LIBSAMPLERATE_SYSTEM "Use libsamplerate by Erik de Castro Lopo in the system" OFF)
endif()

option(USE_FFMPEG_SWRESAMPLE "Use swresample from FFmpeg" OFF)

if(USE_ERIKD_LIBSAMPLERATE_DEPS OR USE_ERIKD_LIBSAMPLERATE_SYSTEM)
set(USE_ERIKD_LIBSAMPLERATE ON)
else()
set(USE_ERIKD_LIBSAMPLERATE OFF)
endif()

if(USE_FFMPEG_SWRESAMPLE)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/finders")
find_package(FFmpeg REQUIRED COMPONENTS avutil swresample)
endif()

configure_file(
src/plugin-macros.h.in
../src/plugin-macros.generated.h
Expand All @@ -36,17 +62,55 @@ configure_file(
../ci/ci_includes.generated.cmd
)

set(PLUGIN_SOURCES
add_library(${CMAKE_PROJECT_NAME} MODULE
src/plugin-main.c
src/async-audio-filter.c
src/resampler.c
)

add_library(${CMAKE_PROJECT_NAME} MODULE ${PLUGIN_SOURCES})

target_link_libraries(${CMAKE_PROJECT_NAME}
OBS::libobs
)

if(USE_FFMPEG_SWRESAMPLE)
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
src/resampler-ffmpeg.c
)
target_link_libraries(${CMAKE_PROJECT_NAME}
FFmpeg::swresample
FFmpeg::avutil
)
endif()

if (USE_ERIKD_LIBSAMPLERATE)
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
src/resampler-erikd.c
)
endif()

if(USE_ERIKD_LIBSAMPLERATE_SYSTEM)
target_include_directories(${CMAKE_PROJECT_NAME}
PRIVATE
${PC_LIBSAMPLERATE_INCLUDE_DIRS}
)
target_link_options(${CMAKE_PROJECT_NAME}
PRIVATE
${PC_LIBSAMPLERATE_LDFLAGS}
)
endif()

if(USE_ERIKD_LIBSAMPLERATE_DEPS)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/libsamplerate/cmake/")
set(BUILD_SHARED_LIBS OFF)
set(LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER OFF)
set(LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER OFF)
set(LIBSAMPLERATE_INSTALL_PKGCONFIG_MODULE OFF)
add_subdirectory(deps/libsamplerate)
target_link_libraries(${CMAKE_PROJECT_NAME}
samplerate
)
endif()

if(OS_WINDOWS)
# Enable Multicore Builds and disable FH4 (to not depend on VCRUNTIME140_1.DLL when building with VS2019)
if (MSVC)
Expand Down
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,40 @@ Recommended setting for each source type is listed below.
## Build and install
### Linux
Install `libsamplerate`. Use `apt` as below on Ubuntu-22.04.
```shell
sudo apt install libsamplerate0 libsamplerate0-dev
```

Use cmake to build on Linux. After checkout, run these commands.
The flags `-D USE_ERIKD_LIBSAMPLERATE_DEPS=OFF -D USE_ERIKD_LIBSAMPLERATE_SYSTEM=ON` are optional
but recommended to ensure `libsamplerate` from the system will be linked.
```shell
mkdir build && cd build
cmake \
-D CMAKE_INSTALL_PREFIX=/usr \
-D USE_ERIKD_LIBSAMPLERATE_DEPS=OFF \
-D USE_ERIKD_LIBSAMPLERATE_SYSTEM=ON \
..
make
sudo make install
```
sed -i 's;${CMAKE_INSTALL_FULL_LIBDIR};/usr/lib;' CMakeLists.txt

If you prefer `libswresample` instead of `libsamplerate`, configure with these flags.
```shell
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
cmake \
-D CMAKE_INSTALL_PREFIX=/usr \
-D USE_ERIKD_LIBSAMPLERATE_DEPS=OFF \
-D USE_ERIKD_LIBSAMPLERATE_SYSTEM=OFF \
-D USE_FFMPEG_SWRESAMPLE=ON \
..
make
sudo make install
```

### macOS
Use cmake to build on Linux. After checkout, run these commands.
Use cmake to build on macOS. After checkout with a submodule, run these commands.
```
mkdir build && cd build
cmake ..
Expand Down
1 change: 1 addition & 0 deletions ci/windows/package-windows.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set /p PackageVersion=<package-version.txt
del package-version.txt

copy ..\LICENSE ..\release\data\obs-plugins\%PluginName%\LICENCE-%PluginName%.txt
copy ..\deps\libsamplerate\COPYING ..\release\data\obs-plugins\%PluginName%\LICENCE-libsamplerate.txt

REM Package ZIP archive
7z a "%PluginName%-%PackageVersion%-obs%1-Windows.zip" "..\release\*"
Expand Down
189 changes: 189 additions & 0 deletions cmake/finders/FindFFmpeg.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# cmake-format: off
#
# This module defines the following variables:
#
# FFMPEG_FOUND - All required components and the core library were found
# FFMPEG_INCLUDE_DIRS - Combined list of all components include dirs
# FFMPEG_LIBRARIES - Combined list of all components libraries
# FFMPEG_VERSION_STRING - Version of the first component requested
#
# For each requested component the following variables are defined:
#
# FFMPEG_<component>_FOUND - The component was found
# FFMPEG_<component>_INCLUDE_DIRS - The components include dirs
# FFMPEG_<component>_LIBRARIES - The components libraries
# FFMPEG_<component>_VERSION_STRING - The components version string
# FFMPEG_<component>_VERSION_MAJOR - The components major version
# FFMPEG_<component>_VERSION_MINOR - The components minor version
# FFMPEG_<component>_VERSION_MICRO - The components micro version
#
# <component> is the uppercase name of the component
# cmake-format: on

find_package(PkgConfig QUIET)

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_lib_suffix 64)
else()
set(_lib_suffix 32)
endif()

function(find_ffmpeg_library component header)
string(TOUPPER "${component}" component_u)
set(FFMPEG_${component_u}_FOUND
FALSE
PARENT_SCOPE)
set(FFmpeg_${component}_FOUND
FALSE
PARENT_SCOPE)

if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_FFMPEG_${component} QUIET lib${component})
endif()

find_path(
FFMPEG_${component}_INCLUDE_DIR
NAMES "lib${component}/${header}" "lib${component}/version.h"
HINTS ENV FFMPEG_PATH ${FFMPEG_PATH} ${CMAKE_SOURCE_DIR}/${FFMPEG_PATH} ${PC_FFMPEG_${component}_INCLUDE_DIRS}
PATHS /usr/include /usr/local/include /opt/local/include /sw/include
PATH_SUFFIXES ffmpeg libav include)

find_library(
FFMPEG_${component}_LIBRARY
NAMES "${component}" "lib${component}"
HINTS ENV FFMPEG_PATH ${FFMPEG_PATH} ${CMAKE_SOURCE_DIR}/${FFMPEG_PATH} ${PC_FFMPEG_${component}_LIBRARY_DIRS}
PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib
PATH_SUFFIXES
lib${_lib_suffix}
lib
libs${_lib_suffix}
libs
bin${_lib_suffix}
bin
../lib${_lib_suffix}
../lib
../libs${_lib_suffix}
../libs
../bin${_lib_suffix}
../bin)

set(FFMPEG_${component_u}_INCLUDE_DIRS
${FFMPEG_${component}_INCLUDE_DIR}
PARENT_SCOPE)
set(FFMPEG_${component_u}_LIBRARIES
${FFMPEG_${component}_LIBRARY}
PARENT_SCOPE)

mark_as_advanced(FFMPEG_${component}_INCLUDE_DIR FFMPEG_${component}_LIBRARY)

if(FFMPEG_${component}_INCLUDE_DIR AND FFMPEG_${component}_LIBRARY)
set(FFMPEG_${component_u}_FOUND
TRUE
PARENT_SCOPE)
set(FFmpeg_${component}_FOUND
TRUE
PARENT_SCOPE)

list(APPEND FFMPEG_INCLUDE_DIRS ${FFMPEG_${component}_INCLUDE_DIR})
list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
set(FFMPEG_INCLUDE_DIRS
"${FFMPEG_INCLUDE_DIRS}"
PARENT_SCOPE)

list(APPEND FFMPEG_LIBRARIES ${FFMPEG_${component}_LIBRARY})
list(REMOVE_DUPLICATES FFMPEG_LIBRARIES)
set(FFMPEG_LIBRARIES
"${FFMPEG_LIBRARIES}"
PARENT_SCOPE)

set(FFMPEG_${component_u}_VERSION_STRING
"unknown"
PARENT_SCOPE)
set(_vfile "${FFMPEG_${component}_INCLUDE_DIR}/lib${component}/version.h")

if(EXISTS "${_vfile}")
file(STRINGS "${_vfile}" _version_parse REGEX "^.*VERSION_(MAJOR|MINOR|MICRO)[ \t]+[0-9]+[ \t]*$")
string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _major "${_version_parse}")
string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _minor "${_version_parse}")
string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _micro "${_version_parse}")

set(FFMPEG_${component_u}_VERSION_MAJOR
"${_major}"
PARENT_SCOPE)
set(FFMPEG_${component_u}_VERSION_MINOR
"${_minor}"
PARENT_SCOPE)
set(FFMPEG_${component_u}_VERSION_MICRO
"${_micro}"
PARENT_SCOPE)

set(FFMPEG_${component_u}_VERSION_STRING
"${_major}.${_minor}.${_micro}"
PARENT_SCOPE)
else()
message(STATUS "Failed parsing FFmpeg ${component} version")
endif()
endif()
endfunction()

set(FFMPEG_INCLUDE_DIRS)
set(FFMPEG_LIBRARIES)

if(NOT FFmpeg_FIND_COMPONENTS)
message(FATAL_ERROR "No FFmpeg components requested")
endif()

list(GET FFmpeg_FIND_COMPONENTS 0 _first_comp)
string(TOUPPER "${_first_comp}" _first_comp)

foreach(component ${FFmpeg_FIND_COMPONENTS})
if(component STREQUAL "avcodec")
find_ffmpeg_library("${component}" "avcodec.h")
elseif(component STREQUAL "avdevice")
find_ffmpeg_library("${component}" "avdevice.h")
elseif(component STREQUAL "avfilter")
find_ffmpeg_library("${component}" "avfilter.h")
elseif(component STREQUAL "avformat")
find_ffmpeg_library("${component}" "avformat.h")
elseif(component STREQUAL "avresample")
find_ffmpeg_library("${component}" "avresample.h")
elseif(component STREQUAL "avutil")
find_ffmpeg_library("${component}" "avutil.h")
elseif(component STREQUAL "postproc")
find_ffmpeg_library("${component}" "postprocess.h")
elseif(component STREQUAL "swresample")
find_ffmpeg_library("${component}" "swresample.h")
elseif(component STREQUAL "swscale")
find_ffmpeg_library("${component}" "swscale.h")
else()
message(FATAL_ERROR "Unknown FFmpeg component requested: ${component}")
endif()
endforeach()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
FFmpeg
FOUND_VAR FFMPEG_FOUND
REQUIRED_VARS FFMPEG_${_first_comp}_LIBRARIES FFMPEG_${_first_comp}_INCLUDE_DIRS
VERSION_VAR FFMPEG_${_first_comp}_VERSION_STRING
HANDLE_COMPONENTS)

if(FFMPEG_FOUND)
foreach(component ${FFmpeg_FIND_COMPONENTS})
if(NOT TARGET FFmpeg::${component})
string(TOUPPER ${component} component_u)
if(FFMPEG_${component_u}_FOUND)
if(IS_ABSOLUTE "${FFMPEG_${component_u}_LIBRARIES}")
add_library(FFmpeg::${component} UNKNOWN IMPORTED)
set_target_properties(FFmpeg::${component} PROPERTIES IMPORTED_LOCATION "${FFMPEG_${component_u}_LIBRARIES}")
else()
add_library(FFmpeg::${component} INTERFACE IMPORTED)
set_target_properties(FFmpeg::${component} PROPERTIES IMPORTED_LIBNAME "${FFMPEG_${component_u}_LIBRARIES}")
endif()

set_target_properties(FFmpeg::${component} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
"${FFMPEG_${component_u}_INCLUDE_DIRS}")
endif()
endif()
endforeach()
endif()
1 change: 1 addition & 0 deletions deps/libsamplerate
Submodule libsamplerate added at c96f5e
Loading

0 comments on commit 83e98eb

Please sign in to comment.