From b82b31ec2bb55f16d68bb0eeb9e7000f76a36b72 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 21 Sep 2023 12:02:16 -0400 Subject: [PATCH] MT#54294 convert cudecs usage to plugin *) Remove packaging for -gpu packages *) Remove build profile restrictions, except for the build dependency itself *) Remove script to generate dh fragments for -gpu packages *) Convert --cudecs switch to a path argument pointing to the .so *) Don't link against libcudecs during build *) Only include the single types.h header needed for usage as a plugin *) Resolve all symbols during startup after loading the .so Change-Id: Ide99eec2156d5d3be8c40594391cb1603add4b16 --- debian/control | 94 +---------------------------- debian/generate-gpu-dh-fragments.sh | 28 --------- debian/rules | 7 --- lib/auxlib.c | 2 +- lib/auxlib.h | 2 +- lib/codeclib.c | 70 ++++++++++++++++----- lib/cudecs.Makefile | 2 - pkg/deb/generator.sh | 2 - 8 files changed, 60 insertions(+), 147 deletions(-) delete mode 100755 debian/generate-gpu-dh-fragments.sh diff --git a/debian/control b/debian/control index a2f0475ed..9e9b6b763 100644 --- a/debian/control +++ b/debian/control @@ -54,7 +54,6 @@ Testsuite: autopkgtest-pkg-dkms Package: ngcp-rtpengine-daemon Architecture: any -Build-Profiles: Multi-Arch: foreign Recommends: ngcp-rtpengine-perftest, @@ -76,7 +75,7 @@ Description: proxy for RTP and media streams used in NGCP, userspace part Package: ngcp-rtpengine-recording-daemon Architecture: any -Build-Profiles: +Build-Profiles: Multi-Arch: foreign Recommends: ngcp-rtpengine-utils, @@ -102,7 +101,6 @@ Description: IPtables extension module for the kernel-space NGCP media proxy Package: ngcp-rtpengine Architecture: all -Build-Profiles: Multi-Arch: foreign Depends: ngcp-rtpengine-daemon (>= ${source:Version}), @@ -150,7 +148,7 @@ Description: scripts and Perl modules for NGCP rtpengine Package: ngcp-rtpengine-perftest Architecture: any -Build-Profiles: +Build-Profiles: Multi-Arch: foreign Depends: ngcp-rtpengine-perftest-data (= ${source:Version}), @@ -172,91 +170,3 @@ Description: helper tool to test rtpengine transcoding performance - data files base and produces performance and load statistics. . These are data files needed for the binary package. - -Package: ngcp-rtpengine-daemon-gpu -Architecture: any -Build-Profiles: -Multi-Arch: foreign -Conflicts: - ngcp-rtpengine-daemon, -Provides: - ngcp-rtpengine-daemon, -Recommends: - ngcp-rtpengine-perftest-gpu, - ngcp-rtpengine-recording-daemon-gpu, - ngcp-rtpengine-utils, -Suggests: - ngcp-system-tools, -Pre-Depends: - adduser, - ${misc:Pre-Depends}, -Depends: - iptables, - sysvinit-utils (>= 3.05-4~) | lsb-base (>= 3.0-6), - ${misc:Depends}, - ${shlibs:Depends}, -Description: proxy for RTP and media streams incl GPU transcoding, userspace part - This daemon handles the first stages of proxying media streams and talks to - the kernel part of the proxy for eventual high-performance packet forwarding. - This build includes support for GPU transcoding. - -Package: ngcp-rtpengine-recording-daemon-gpu -Architecture: any -Multi-Arch: foreign -Build-Profiles: -Conflicts: - ngcp-rtpengine-recording-daemon, -Provides: - ngcp-rtpengine-recording-daemon, -Recommends: - ngcp-rtpengine-utils, -Suggests: - ngcp-system-tools, -Depends: - nfs-common, - ngcp-rtpengine-daemon-gpu, - sysvinit-utils (>= 3.05-4~) | lsb-base (>= 3.0-6), - ${misc:Depends}, - ${shlibs:Depends}, -Description: recording daemon for RTP and media streams incl GPU transcodnig - This daemon handles the call recording (media intercept) component of rtpengine. - This build includes support for GPU transcoding. - -Package: ngcp-rtpengine-gpu -Architecture: all -Build-Profiles: -Multi-Arch: foreign -Conflicts: - ngcp-rtpengine, -Provides: - ngcp-rtpengine, -Depends: - ngcp-rtpengine-daemon-gpu (>= ${source:Version}), - ngcp-rtpengine-iptables (>= ${source:Version}), - ngcp-rtpengine-kernel-dkms (>= ${source:Version}), - ngcp-rtpengine-perftest-gpu (>= ${source:Version}), - ngcp-rtpengine-recording-daemon-gpu (>= ${source:Version}), - ngcp-rtpengine-utils (>= ${source:Version}), - ${misc:Depends}, -Description: NGCP RTP/media proxy incl GPU transcoding - meta package - This is a meta package for easy installation of all four parts of the NGCP - media proxy. It will install the user-space daemon, the kernel-space IPtables - module, the IPtables extension module and utility scripts. - This build includes support for GPU transcoding. - -Package: ngcp-rtpengine-perftest-gpu -Architecture: any -Multi-Arch: foreign -Build-Profiles: -Conflicts: - ngcp-rtpengine-perftest, -Provides: - ngcp-rtpengine-perftest, -Depends: - ngcp-rtpengine-perftest-data (= ${source:Version}), - ${misc:Depends}, - ${shlibs:Depends}, -Description: helper tool to test rtpengine transcoding performance incl GPU transcoding - This interactive tool simulates transcoding scenarios using the rtpengine code - base and produces performance and load statistics. - This build includes support for GPU transcoding. diff --git a/debian/generate-gpu-dh-fragments.sh b/debian/generate-gpu-dh-fragments.sh deleted file mode 100755 index 0bbe7ea81..000000000 --- a/debian/generate-gpu-dh-fragments.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -for pkg in ngcp-rtpengine-daemon ngcp-rtpengine-recording-daemon ngcp-rtpengine-perftest; do - for file in "$pkg".*; do - if test -f "$file"; then - suffix=${file#"$pkg".} - cp -v "$pkg"."$suffix" "$pkg"-gpu."$suffix" - fi - done - for file in "$pkg"@.*; do - if test -f "$file"; then - suffix=${file#"$pkg"@.} - cp -v "$pkg"@."$suffix" "$pkg"-gpu@."$suffix" - fi - done - if test -f "$pkg"-gpu.links; then - rm -vf "$pkg"-gpu.links.tmp - while read -r line; do - # rewrite link from original 'rtpengine-daemon.service -> ngcp-rtpengine-daemon.service' - # ... to 'rtpengine-daemon-gpu.service -> ngcp-rtpengine-daemon-gpu.service' - echo "$line" | sed 's/\(@\?\)\.service/-gpu\1.service/g' >> "$pkg"-gpu.links.tmp - # add link 'rtpengine-daemon.service -> ngcp-rtpengine-daemon-gpu.service' - echo "$line" | sed 's/\(@\?\)\.service/-gpu\1.service/' >> "$pkg"-gpu.links.tmp - # add link 'ngcp-rtpengine-daemon.service -> ngcp-rtpengine-daemon-gpu.service' - echo "$line" | sed 's/\(@\?\)\.service/-gpu\1.service/; s,system/rtpengine,system/ngcp-rtpengine,' >> "$pkg"-gpu.links.tmp - done < "$pkg"-gpu.links - mv -v "$pkg"-gpu.links.tmp "$pkg"-gpu.links - fi -done diff --git a/debian/rules b/debian/rules index 3a15e0b8d..2b169749d 100755 --- a/debian/rules +++ b/debian/rules @@ -28,9 +28,6 @@ export FIXTURES_PATH = /usr/share/rtpengine-perftest execute_before_dh_auto_configure: (cd debian && sh generate-systemd-templates.sh) -ifneq (,$(filter $(DEB_BUILD_PROFILES),pkg.ngcp-rtpengine.cudecs)) - (cd debian && ./generate-gpu-dh-fragments.sh) -endif execute_before_dh_auto_install-indep: # markdown README @@ -38,11 +35,7 @@ execute_before_dh_auto_install-indep: gzip -9 < README.md > debian/README.md.gz execute_after_dh_installsystemd: -ifneq (,$(filter $(DEB_BUILD_PROFILES),pkg.ngcp-rtpengine.cudecs)) - dh_installsystemd -pngcp-rtpengine-recording-daemon-gpu --name=ngcp-rtpengine-recording-nfs-mount -else dh_installsystemd -pngcp-rtpengine-recording-daemon --name=ngcp-rtpengine-recording-nfs-mount -endif override_dh_dkms: dh_dkms -p$(DEB_SOURCE)-kernel-dkms -V $(DEB_VERSION_UPSTREAM) diff --git a/lib/auxlib.c b/lib/auxlib.c index 07f07aa29..61b1f964a 100644 --- a/lib/auxlib.c +++ b/lib/auxlib.c @@ -216,7 +216,7 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char { "poller-size", 0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->poller_size, "Max poller items per iteration", "INT" }, { "evs-lib-path", 0,0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->evs_lib_path, "Location of .so for 3GPP EVS codec", "FILE" }, #ifdef HAVE_CUDECS - { "cudecs", 0,0, G_OPTION_ARG_NONE, &rtpe_common_config_ptr->cudecs, "Enable usage of CUDA codecs", NULL }, + { "cudecs-lib-path", 0,0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->cudecs_lib_path,"Location of .so for CUDA codecs", "FILE" }, #endif { NULL, } }; diff --git a/lib/auxlib.h b/lib/auxlib.h index ab685ecf5..a1dc03552 100644 --- a/lib/auxlib.h +++ b/lib/auxlib.h @@ -36,7 +36,7 @@ struct rtpengine_common_config { int poller_size; int max_log_line_length; char *evs_lib_path; - int cudecs; + char *cudecs_lib_path; }; extern struct rtpengine_common_config *rtpe_common_config_ptr; diff --git a/lib/codeclib.c b/lib/codeclib.c index ef3260894..923049b29 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -12,9 +12,7 @@ #endif #include #ifdef HAVE_CUDECS -#include -#include -#include +#include #endif #include "str.h" #include "log.h" @@ -143,8 +141,31 @@ static select_encoder_format_f evs_select_encoder_format; -struct codec_chain_s { +static void *cudecs_lib_handle; + #ifdef HAVE_CUDECS + +static gpu_init_fn *gpu_init; + +static gpu_pcma2opus_runner_new_fn *gpu_pcma2opus_runner_new; +static gpu_pcmu2opus_runner_new_fn *gpu_pcmu2opus_runner_new; +static gpu_opus2pcma_runner_new_fn *gpu_opus2pcma_runner_new; +static gpu_opus2pcmu_runner_new_fn *gpu_opus2pcmu_runner_new; + +static gpu_pcma2opus_runner_do_fn *gpu_pcma2opus_runner_do; +static gpu_pcmu2opus_runner_do_fn *gpu_pcmu2opus_runner_do; +static gpu_opus2pcma_runner_do_fn *gpu_opus2pcma_runner_do; +static gpu_opus2pcmu_runner_do_fn *gpu_opus2pcmu_runner_do; + +static gpu_float2opus_new_fn *gpu_float2opus_new; +static gpu_opus2float_new_fn *gpu_opus2float_new; + +static gpu_pcma2opus_runner *pcma2opus_runner; +static gpu_pcmu2opus_runner *pcmu2opus_runner; +static gpu_opus2pcmu_runner *opus2pcmu_runner; +static gpu_opus2pcma_runner *opus2pcma_runner; + +struct codec_chain_s { union { struct { gpu_pcmu2opus_runner *runner; @@ -165,8 +186,8 @@ struct codec_chain_s { } u; AVPacket *avpkt; int (*run)(codec_chain_t *c, const str *data, unsigned long ts, AVPacket *); -#endif }; +#endif @@ -271,14 +292,6 @@ static const codec_type_t codec_type_bcg729 = { #endif -#ifdef HAVE_CUDECS -static gpu_pcma2opus_runner *pcma2opus_runner; -static gpu_pcmu2opus_runner *pcmu2opus_runner; -static gpu_opus2pcmu_runner *opus2pcmu_runner; -static gpu_opus2pcma_runner *opus2pcma_runner; -#endif - - static struct codec_def_s __codec_defs[] = { { @@ -1211,6 +1224,8 @@ void codeclib_free(void) { avformat_network_deinit(); if (evs_lib_handle) dlclose(evs_lib_handle); + if (cudecs_lib_handle) + dlclose(cudecs_lib_handle); } @@ -1259,6 +1274,26 @@ static void *dlsym_assert(void *handle, const char *sym, const char *fn) { } +#ifdef HAVE_CUDECS +static void cudecs_dlsym_resolve(const char *fn) { + gpu_init = dlsym_assert(cudecs_lib_handle, "gpu_init", fn); + + gpu_pcma2opus_runner_new = dlsym_assert(cudecs_lib_handle, "gpu_pcma2opus_runner_new", fn); + gpu_pcmu2opus_runner_new = dlsym_assert(cudecs_lib_handle, "gpu_pcmu2opus_runner_new", fn); + gpu_opus2pcma_runner_new = dlsym_assert(cudecs_lib_handle, "gpu_opus2pcma_runner_new", fn); + gpu_opus2pcmu_runner_new = dlsym_assert(cudecs_lib_handle, "gpu_opus2pcmu_runner_new", fn); + + gpu_pcma2opus_runner_do = dlsym_assert(cudecs_lib_handle, "gpu_pcma2opus_runner_do", fn); + gpu_pcmu2opus_runner_do = dlsym_assert(cudecs_lib_handle, "gpu_pcmu2opus_runner_do", fn); + gpu_opus2pcma_runner_do = dlsym_assert(cudecs_lib_handle, "gpu_opus2pcma_runner_do", fn); + gpu_opus2pcmu_runner_do = dlsym_assert(cudecs_lib_handle, "gpu_opus2pcmu_runner_do", fn); + + gpu_float2opus_new = dlsym_assert(cudecs_lib_handle, "gpu_float2opus_new", fn); + gpu_opus2float_new = dlsym_assert(cudecs_lib_handle, "gpu_opus2float_new", fn); +} +#endif + + void codeclib_init(int print) { #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); @@ -1272,7 +1307,14 @@ void codeclib_init(int print) { codecs_ht_by_av = g_hash_table_new(g_direct_hash, g_direct_equal); #ifdef HAVE_CUDECS - if (rtpe_common_config_ptr->cudecs) { + if (rtpe_common_config_ptr->cudecs_lib_path) { + cudecs_lib_handle = dlopen(rtpe_common_config_ptr->cudecs_lib_path, RTLD_NOW | RTLD_LOCAL); + if (!cudecs_lib_handle) + die("Failed to load CUDA codecs .so '%s': %s", rtpe_common_config_ptr->cudecs_lib_path, + dlerror()); + + cudecs_dlsym_resolve(rtpe_common_config_ptr->cudecs_lib_path); + if (!gpu_init()) die("Failed to initialise CUDA codecs"); diff --git a/lib/cudecs.Makefile b/lib/cudecs.Makefile index 5d021e691..5e9c08608 100644 --- a/lib/cudecs.Makefile +++ b/lib/cudecs.Makefile @@ -1,9 +1,7 @@ ifneq (,$(filter pkg.ngcp-rtpengine.cudecs,${DEB_BUILD_PROFILES})) ifneq (,$(wildcard $(CUDECS_HOME)/usr/include/cudecs/g711opus.h)) CFLAGS+= -DHAVE_CUDECS -I$(CUDECS_HOME)/usr/include -LDLIBS+= -L$(CUDECS_HOME)/usr/lib -lcudecs else ifneq (,$(wildcard /usr/include/cudecs/g711opus.h)) CFLAGS+= -DHAVE_CUDECS -LDLIBS+= -lcudecs endif endif diff --git a/pkg/deb/generator.sh b/pkg/deb/generator.sh index 26272a4cf..ba5cd3ccd 100755 --- a/pkg/deb/generator.sh +++ b/pkg/deb/generator.sh @@ -32,13 +32,11 @@ done < <(find debian -name '*links') echo "- Remove NGCP packages from control" sed -i -e '/ngcp-system-tools/d' debian/control sed -i -e '/ngcp-libcudecs/d' debian/control -sed -i -n -e '/-gpu/ q; p' debian/control echo "- Set package-specific homepage" sed -i -e 's,^Homepage:.*,Homepage: https://rtpengine.com/,' debian/control echo "- Add Conflicts with NGCP packages" -# TODO: prevent duplicate "Conflicts" when -gpu packages are left in place while read -r line ; do sed -i "/${line}$/ a Conflicts: ngcp-${line#Package: }" debian/control done < <(awk '/Package:/' debian/control)