From 0623b6b9def43d1f0270e016e136c7b7874c9694 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 9 Apr 2025 14:49:48 -0400 Subject: [PATCH] MT#61625 tie codec-chain into transcode-config Change-Id: Ida6e51b8b4ef3cefe738ccd1678ec86763e93711 --- daemon/codec.c | 13 ++++++ daemon/main.c | 9 ++++ etc/rtpengine.conf | 9 ++-- include/codec.h | 6 ++- lib/codeclib.c | 110 ++++++++++++++++++++++++++++----------------- lib/codeclib.h | 4 ++ 6 files changed, 104 insertions(+), 47 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index fde7becf3..7c8819aef 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -6396,6 +6396,19 @@ void codecs_init(void) { if (t_hash_table_lookup(rtpe_transcode_config, &tcc->i)) die("Duplicate entry in transcode config '%s'", tcc->name); t_hash_table_insert(rtpe_transcode_config, &tcc->i, tcc); + + if (tcc->codec_chain) + cc_init_chain( + tcc->i.src.codec_def, + &(format_t) { + .channels = tcc->i.src.channels, + .clockrate = tcc->i.src.clock_rate, + }, + tcc->i.dst.codec_def, + &(format_t) { + .channels = tcc->i.dst.channels, + .clockrate = tcc->i.dst.clock_rate, + }); } #endif } diff --git a/daemon/main.c b/daemon/main.c index 34957625a..d51a7401e 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -439,6 +439,9 @@ static void do_transcode_config(const char *name, charp_ht ht, struct transcode_ die("Failed to parse source codec '%s' in transcode config '%s'", src, name); char *tfm = t_hash_table_lookup(ht, "transform"); +#ifdef HAVE_CODEC_CHAIN + char *cc = t_hash_table_lookup(ht, "codec-chain"); +#endif if (tfm) { if (!endpoint_parse_any_getaddrinfo_full(&tc->transform, tfm)) die("Failed to parse transform endpoint '%s' in transcode config '%s'", tfm, name); @@ -450,6 +453,12 @@ static void do_transcode_config(const char *name, charp_ht ht, struct transcode_ tc->remote_interface = STR(iface); return; } +#ifdef HAVE_CODEC_CHAIN + else if (cc) { + // assume value is true + tc->codec_chain = true; + } +#endif else die("Transcode config '%s' has no verdict", name); } diff --git a/etc/rtpengine.conf b/etc/rtpengine.conf index 5b4ecf53e..ca607c4a2 100644 --- a/etc/rtpengine.conf +++ b/etc/rtpengine.conf @@ -63,8 +63,8 @@ port-max = 39999 # idle-scheduling = idle # idle-priority = 10 -recording-dir = /var/spool/rtpengine -recording-method = proc +#recording-dir = /var/spool/rtpengine +#recording-method = proc # recording-format = raw # redis = 127.0.0.1:6379/5 @@ -184,18 +184,19 @@ transcode-config = transcode [transcode-1] source = opus destination = PCMA -transform = localhost:2228 # local-interface = ... # remote-interface = ... # address-family = ... +codec-chain = true [transcode-2] source = PCMA destination = opus -transform = localhost:2228 +#transform = localhost:2228 # local-interface = ... # remote-interface = ... # address-family = ... +codec-chain = true # signalling templates (see key `templates` above) [templates] diff --git a/include/codec.h b/include/codec.h index fd1912c20..08e2f4ee7 100644 --- a/include/codec.h +++ b/include/codec.h @@ -116,11 +116,13 @@ struct transcode_config { struct codec_pipeline_index i; // parsed - // verdict + // transform verdict endpoint_t transform; str local_interface; str remote_interface; - //const sockfamily_t *address_family; + + // codec-chain verdict + bool codec_chain:1; }; typedef union { diff --git a/lib/codeclib.c b/lib/codeclib.c index c079c2665..98886a40d 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -166,8 +166,10 @@ static __typeof__(*codec_chain_defs) *cc_defs; static codec_chain_client *cc_client; -static codec_chain_runner *cc_runners[CODEC_CHAIN_ID_MAX]; -static codec_chain_async_runner *cc_async_runners[CODEC_CHAIN_ID_MAX]; +static union { + codec_chain_runner *sync; + codec_chain_async_runner *async; +} cc_runners[CODEC_CHAIN_ID_MAX]; typedef enum { @@ -1365,33 +1367,6 @@ static void cc_dlsym_resolve(const char *fn) { "codec_chain_defs", fn); } -static void cc_create_runners(void) { - for (codec_chain_id id = 1; id < CODEC_CHAIN_ID_MAX; id++) { - cc_runners[id] = cc_client_runner_new(cc_client, id, - 10000, - rtpe_common_config_ptr->codec_chain_runners, - rtpe_common_config_ptr->codec_chain_concurrency); - if (cc_runners[id]) - ilog(LOG_DEBUG, "Created chain runner for %s", cc_defs[id].name); - else - ilog(LOG_WARN, "Failed to create chain runner for %s", cc_defs[id].name); - } -} - -static void cc_create_async_runners(void) { - for (codec_chain_id id = 1; id < CODEC_CHAIN_ID_MAX; id++) { - cc_async_runners[id] = cc_client_async_runner_new(cc_client, id, - rtpe_common_config_ptr->codec_chain_async, - 10000, - rtpe_common_config_ptr->codec_chain_runners, - rtpe_common_config_ptr->codec_chain_concurrency); - if (cc_async_runners[id]) - ilog(LOG_DEBUG, "Created async chain runner for %s", cc_defs[id].name); - else - ilog(LOG_WARN, "Failed to create async chain runner for %s", cc_defs[id].name); - } -} - static codec_cc_t *codec_cc_new_dummy(codec_def_t *src, format_t *src_format, codec_def_t *dst, format_t *dst_format, int bitrate, int ptime, @@ -1421,25 +1396,78 @@ static void cc_init(void) { if (!cc_client) die("Failed to connect to cudecsd"); - if (!rtpe_common_config_ptr->codec_chain_async) { - cc_create_runners(); + if (!rtpe_common_config_ptr->codec_chain_async) codec_cc_new = codec_cc_new_sync; - } - else { - cc_create_async_runners(); + else codec_cc_new = codec_cc_new_async; - } ilog(LOG_DEBUG, "CUDA codecs initialised"); } +void cc_init_chain(codec_def_t *src, format_t *src_format, codec_def_t *dst, + format_t *dst_format) +{ + codec_chain_id id = cc_get( + (codec_chain_params) { + .name = src->rtpname, + .clock_rate = src_format->clockrate, + .channels = src_format->channels, + .ptime = 20, // XXX + }, + (codec_chain_params) { + .name = dst->rtpname, + .clock_rate = dst_format->clockrate, + .channels = dst_format->channels, + .ptime = 20, // XXX + } + ); + if (id == 0) { + ilog(LOG_WARN, "Codec chain %s -> %s not supported by library", + src->rtpname, dst->rtpname); + return; + } + if (id >= CODEC_CHAIN_ID_MAX) { + ilog(LOG_WARN, "Codec chain %s -> %s requires rebuild", + src->rtpname, dst->rtpname); + return; + } + + if (rtpe_common_config_ptr->codec_chain_async) { + if (cc_runners[id].async) + return; + cc_runners[id].async = cc_client_async_runner_new(cc_client, id, + rtpe_common_config_ptr->codec_chain_async, + 10000, + rtpe_common_config_ptr->codec_chain_runners, + rtpe_common_config_ptr->codec_chain_concurrency); + if (cc_runners[id].async) + ilog(LOG_DEBUG, "Created async chain runner for %s", cc_defs[id].name); + else + ilog(LOG_WARN, "Failed to create async chain runner for %s", cc_defs[id].name); + } + else { + if (cc_runners[id].sync) + return; + cc_runners[id].sync = cc_client_runner_new(cc_client, id, + 10000, + rtpe_common_config_ptr->codec_chain_runners, + rtpe_common_config_ptr->codec_chain_concurrency); + if (cc_runners[id].sync) + ilog(LOG_DEBUG, "Created chain runner for %s", cc_defs[id].name); + else + ilog(LOG_WARN, "Failed to create chain runner for %s", cc_defs[id].name); + } +} + static void cc_cleanup(void) { if (!cc_lib_handle) return; for (codec_chain_id id = 1; id < CODEC_CHAIN_ID_MAX; id++) { - cc_client_runner_free(cc_client, &cc_runners[id]); - cc_client_async_runner_free(cc_client, &cc_async_runners[id]); + if (!rtpe_common_config_ptr->codec_chain_async) + cc_client_runner_free(cc_client, &cc_runners[id].sync); + else + cc_client_async_runner_free(cc_client, &cc_runners[id].async); } } @@ -5047,7 +5075,7 @@ static codec_cc_t *codec_cc_new_sync(codec_def_t *src, format_t *src_format, cod return NULL; if (id >= CODEC_CHAIN_ID_MAX) return NULL; - if (!cc_runners[id]) + if (!cc_runners[id].sync) return NULL; codec_cc_t *ret = g_new0(codec_cc_t, 1); @@ -5063,7 +5091,7 @@ static codec_cc_t *codec_cc_new_sync(codec_def_t *src, format_t *src_format, cod ret->codec = cc_client_codec_new(cc_client, id, args); ret->clear = cc_clear; ret->clear_arg = ret->codec; - ret->runner = cc_runners[id]; + ret->runner = cc_runners[id].sync; ret->avpkt = av_packet_alloc(); ret->run = cc_run; @@ -5093,7 +5121,7 @@ static codec_cc_t *codec_cc_new_async(codec_def_t *src, format_t *src_format, co return NULL; if (id >= CODEC_CHAIN_ID_MAX) return NULL; - if (!cc_async_runners[id]) + if (!cc_runners[id].async) return NULL; codec_cc_t *ret = g_new0(codec_cc_t, 1); @@ -5109,7 +5137,7 @@ static codec_cc_t *codec_cc_new_async(codec_def_t *src, format_t *src_format, co ret->codec = cc_client_codec_new(cc_client, id, args); ret->clear = cc_clear; ret->clear_arg = ret->codec; - ret->async_runner = cc_async_runners[id]; + ret->async_runner = cc_runners[id].async; ret->run = cc_run_async; ret->avpkt_async = av_packet_alloc(); av_new_packet(ret->avpkt_async, 2048); diff --git a/lib/codeclib.h b/lib/codeclib.h index ed3c713d0..aacbaa248 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -454,6 +454,8 @@ extern codec_cc_t *(*codec_cc_new)(codec_def_t *src, format_t *src_format, codec format_t *dst_format, int bitrate, int ptime, void *(*init_async)(void *, void *, void *), void (*async_callback)(AVPacket *, void *)); +void cc_init_chain(codec_def_t *src, format_t *src_format, codec_def_t *dst, + format_t *dst_format); void codec_cc_stop(codec_cc_t *); void codec_cc_free(codec_cc_t **); @@ -463,6 +465,8 @@ INLINE codec_cc_t *codec_cc_new(codec_def_t *src, format_t *src_format, codec_de format_t *dst_format, int bitrate, int ptime, void *(*init_async)(void *, void *, void *), void (*async_callback)(AVPacket *, void *)) { return NULL; } +INLINE void cc_init_chain(codec_def_t *src, format_t *src_format, codec_def_t *dst, + format_t *dst_format) { } INLINE void codec_cc_stop(codec_cc_t *c) { } INLINE void codec_cc_free(codec_cc_t **c) { }