|
|
|
@ -11,8 +11,9 @@ |
|
|
|
#include <bcg729/decoder.h> |
|
|
|
#endif |
|
|
|
#include <opus.h> |
|
|
|
#ifdef HAVE_CUDECS |
|
|
|
#include <cudecs/types.h> |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
#include <codec-chain/types.h> |
|
|
|
#include <codec-chain/client.h> |
|
|
|
#endif |
|
|
|
#include "str.h" |
|
|
|
#include "log.h" |
|
|
|
@ -141,47 +142,49 @@ static select_encoder_format_f evs_select_encoder_format; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *cudecs_lib_handle; |
|
|
|
static void *codec_chain_lib_handle; |
|
|
|
|
|
|
|
#ifdef HAVE_CUDECS |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
|
|
|
|
static gpu_init_fn *gpu_init; |
|
|
|
static __typeof__(codec_chain_client_connect) *cc_client_connect; |
|
|
|
|
|
|
|
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 __typeof__(codec_chain_client_pcma2opus_runner_new) *cc_client_pcma2opus_runner_new; |
|
|
|
static __typeof__(codec_chain_client_pcmu2opus_runner_new) *cc_client_pcmu2opus_runner_new; |
|
|
|
static __typeof__(codec_chain_client_opus2pcma_runner_new) *cc_client_opus2pcma_runner_new; |
|
|
|
static __typeof__(codec_chain_client_opus2pcmu_runner_new) *cc_client_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 __typeof__(codec_chain_pcma2opus_runner_do) *cc_pcma2opus_runner_do; |
|
|
|
static __typeof__(codec_chain_pcmu2opus_runner_do) *cc_pcmu2opus_runner_do; |
|
|
|
static __typeof__(codec_chain_opus2pcma_runner_do) *cc_opus2pcma_runner_do; |
|
|
|
static __typeof__(codec_chain_opus2pcmu_runner_do) *cc_opus2pcmu_runner_do; |
|
|
|
|
|
|
|
static gpu_float2opus_new_fn *gpu_float2opus_new; |
|
|
|
static gpu_opus2float_new_fn *gpu_opus2float_new; |
|
|
|
static __typeof__(codec_chain_client_float2opus_new) *cc_client_float2opus_new; |
|
|
|
static __typeof__(codec_chain_client_opus2float_new) *cc_client_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; |
|
|
|
static codec_chain_client *cc_client; |
|
|
|
|
|
|
|
static codec_chain_pcma2opus_runner *pcma2opus_runner; |
|
|
|
static codec_chain_pcmu2opus_runner *pcmu2opus_runner; |
|
|
|
static codec_chain_opus2pcmu_runner *opus2pcmu_runner; |
|
|
|
static codec_chain_opus2pcma_runner *opus2pcma_runner; |
|
|
|
|
|
|
|
struct codec_chain_s { |
|
|
|
union { |
|
|
|
struct { |
|
|
|
gpu_pcmu2opus_runner *runner; |
|
|
|
gpu_float2opus *enc; |
|
|
|
codec_chain_pcmu2opus_runner *runner; |
|
|
|
codec_chain_float2opus *enc; |
|
|
|
} pcmu2opus; |
|
|
|
struct { |
|
|
|
gpu_pcma2opus_runner *runner; |
|
|
|
gpu_float2opus *enc; |
|
|
|
codec_chain_pcma2opus_runner *runner; |
|
|
|
codec_chain_float2opus *enc; |
|
|
|
} pcma2opus; |
|
|
|
struct { |
|
|
|
gpu_opus2pcmu_runner *runner; |
|
|
|
gpu_opus2float *dec; |
|
|
|
codec_chain_opus2pcmu_runner *runner; |
|
|
|
codec_chain_opus2float *dec; |
|
|
|
} opus2pcmu; |
|
|
|
struct { |
|
|
|
gpu_opus2pcma_runner *runner; |
|
|
|
gpu_opus2float *dec; |
|
|
|
codec_chain_opus2pcma_runner *runner; |
|
|
|
codec_chain_opus2float *dec; |
|
|
|
} opus2pcma; |
|
|
|
} u; |
|
|
|
AVPacket *avpkt; |
|
|
|
@ -1224,8 +1227,8 @@ void codeclib_free(void) { |
|
|
|
avformat_network_deinit(); |
|
|
|
if (evs_lib_handle) |
|
|
|
dlclose(evs_lib_handle); |
|
|
|
if (cudecs_lib_handle) |
|
|
|
dlclose(cudecs_lib_handle); |
|
|
|
if (codec_chain_lib_handle) |
|
|
|
dlclose(codec_chain_lib_handle); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1274,22 +1277,32 @@ 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); |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
static void codec_chain_dlsym_resolve(const char *fn) { |
|
|
|
cc_client_connect = dlsym_assert(codec_chain_lib_handle, "codec_chain_client_connect", 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); |
|
|
|
cc_client_pcma2opus_runner_new = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_client_pcma2opus_runner_new", fn); |
|
|
|
cc_client_pcmu2opus_runner_new = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_client_pcmu2opus_runner_new", fn); |
|
|
|
cc_client_opus2pcma_runner_new = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_client_opus2pcma_runner_new", fn); |
|
|
|
cc_client_opus2pcmu_runner_new = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_client_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); |
|
|
|
cc_pcma2opus_runner_do = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_pcma2opus_runner_do", fn); |
|
|
|
cc_pcmu2opus_runner_do = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_pcmu2opus_runner_do", fn); |
|
|
|
cc_opus2pcma_runner_do = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_opus2pcma_runner_do", fn); |
|
|
|
cc_opus2pcmu_runner_do = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_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); |
|
|
|
cc_client_float2opus_new = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_client_float2opus_new", fn); |
|
|
|
cc_client_opus2float_new = dlsym_assert(codec_chain_lib_handle, |
|
|
|
"codec_chain_client_opus2float_new", fn); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
@ -1306,31 +1319,33 @@ void codeclib_init(int print) { |
|
|
|
codecs_ht = g_hash_table_new(str_case_hash, str_case_equal); |
|
|
|
codecs_ht_by_av = g_hash_table_new(g_direct_hash, g_direct_equal); |
|
|
|
|
|
|
|
#ifdef HAVE_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, |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
if (rtpe_common_config_ptr->codec_chain_lib_path) { |
|
|
|
codec_chain_lib_handle = dlopen(rtpe_common_config_ptr->codec_chain_lib_path, RTLD_NOW | RTLD_LOCAL); |
|
|
|
if (!codec_chain_lib_handle) |
|
|
|
die("Failed to load libcodec-chain.so '%s': %s", |
|
|
|
rtpe_common_config_ptr->codec_chain_lib_path, |
|
|
|
dlerror()); |
|
|
|
|
|
|
|
cudecs_dlsym_resolve(rtpe_common_config_ptr->cudecs_lib_path); |
|
|
|
codec_chain_dlsym_resolve(rtpe_common_config_ptr->codec_chain_lib_path); |
|
|
|
|
|
|
|
if (!gpu_init()) |
|
|
|
die("Failed to initialise CUDA codecs"); |
|
|
|
cc_client = cc_client_connect(4); |
|
|
|
if (!cc_client) |
|
|
|
die("Failed to connect to cudecsd"); |
|
|
|
|
|
|
|
pcma2opus_runner = gpu_pcma2opus_runner_new(4, 3000, 160); |
|
|
|
pcma2opus_runner = cc_client_pcma2opus_runner_new(cc_client, 4, 3000, 160); |
|
|
|
if (!pcma2opus_runner) |
|
|
|
die("Failed to initialise GPU pcma2opus"); |
|
|
|
|
|
|
|
pcmu2opus_runner = gpu_pcmu2opus_runner_new(4, 3000, 160); |
|
|
|
pcmu2opus_runner = cc_client_pcmu2opus_runner_new(cc_client, 4, 3000, 160); |
|
|
|
if (!pcmu2opus_runner) |
|
|
|
die("Failed to initialise GPU pcmu2opus"); |
|
|
|
|
|
|
|
opus2pcmu_runner = gpu_opus2pcmu_runner_new(4, 3000, 160); |
|
|
|
opus2pcmu_runner = cc_client_opus2pcmu_runner_new(cc_client, 4, 3000, 160); |
|
|
|
if (!opus2pcmu_runner) |
|
|
|
die("Failed to initialise GPU opus2pcmu"); |
|
|
|
|
|
|
|
opus2pcma_runner = gpu_opus2pcma_runner_new(4, 3000, 160); |
|
|
|
opus2pcma_runner = cc_client_opus2pcma_runner_new(cc_client, 4, 3000, 160); |
|
|
|
if (!opus2pcma_runner) |
|
|
|
die("Failed to initialise GPU opus2pcma"); |
|
|
|
|
|
|
|
@ -4652,9 +4667,9 @@ static int evs_dtx(decoder_t *dec, GQueue *out, int ptime) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CUDECS |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
int codec_chain_pcmu2opus_run(codec_chain_t *c, const str *data, unsigned long ts, AVPacket *pkt) { |
|
|
|
ssize_t ret = gpu_pcmu2opus_runner_do(c->u.pcmu2opus.runner, c->u.pcmu2opus.enc, |
|
|
|
ssize_t ret = cc_pcmu2opus_runner_do(c->u.pcmu2opus.runner, c->u.pcmu2opus.enc, |
|
|
|
(unsigned char *) data->s, data->len, |
|
|
|
pkt->data, pkt->size); |
|
|
|
assert(ret > 0); |
|
|
|
@ -4667,7 +4682,7 @@ int codec_chain_pcmu2opus_run(codec_chain_t *c, const str *data, unsigned long t |
|
|
|
} |
|
|
|
|
|
|
|
int codec_chain_pcma2opus_run(codec_chain_t *c, const str *data, unsigned long ts, AVPacket *pkt) { |
|
|
|
ssize_t ret = gpu_pcma2opus_runner_do(c->u.pcma2opus.runner, c->u.pcma2opus.enc, |
|
|
|
ssize_t ret = cc_pcma2opus_runner_do(c->u.pcma2opus.runner, c->u.pcma2opus.enc, |
|
|
|
(unsigned char *) data->s, data->len, |
|
|
|
pkt->data, pkt->size); |
|
|
|
assert(ret > 0); |
|
|
|
@ -4680,7 +4695,7 @@ int codec_chain_pcma2opus_run(codec_chain_t *c, const str *data, unsigned long t |
|
|
|
} |
|
|
|
|
|
|
|
int codec_chain_opus2pcmu_run(codec_chain_t *c, const str *data, unsigned long ts, AVPacket *pkt) { |
|
|
|
ssize_t ret = gpu_opus2pcmu_runner_do(c->u.opus2pcmu.runner, c->u.opus2pcmu.dec, |
|
|
|
ssize_t ret = cc_opus2pcmu_runner_do(c->u.opus2pcmu.runner, c->u.opus2pcmu.dec, |
|
|
|
(unsigned char *) data->s, data->len, |
|
|
|
pkt->data, pkt->size); |
|
|
|
assert(ret > 0); |
|
|
|
@ -4693,7 +4708,7 @@ int codec_chain_opus2pcmu_run(codec_chain_t *c, const str *data, unsigned long t |
|
|
|
} |
|
|
|
|
|
|
|
int codec_chain_opus2pcma_run(codec_chain_t *c, const str *data, unsigned long ts, AVPacket *pkt) { |
|
|
|
ssize_t ret = gpu_opus2pcma_runner_do(c->u.opus2pcma.runner, c->u.opus2pcma.dec, |
|
|
|
ssize_t ret = cc_opus2pcma_runner_do(c->u.opus2pcma.runner, c->u.opus2pcma.dec, |
|
|
|
(unsigned char *) data->s, data->len, |
|
|
|
pkt->data, pkt->size); |
|
|
|
assert(ret > 0); |
|
|
|
@ -4711,7 +4726,7 @@ int codec_chain_opus2pcma_run(codec_chain_t *c, const str *data, unsigned long t |
|
|
|
codec_chain_t *codec_chain_new(codec_def_t *src, format_t *src_format, codec_def_t *dst, |
|
|
|
format_t *dst_format, int bitrate, int ptime) |
|
|
|
{ |
|
|
|
#ifdef HAVE_CUDECS |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
if (!strcmp(dst->rtpname, "opus") && !strcmp(src->rtpname, "PCMA")) { |
|
|
|
if (src_format->clockrate != 8000) |
|
|
|
return NULL; |
|
|
|
@ -4726,7 +4741,7 @@ codec_chain_t *codec_chain_new(codec_def_t *src, format_t *src_format, codec_def |
|
|
|
return NULL; |
|
|
|
|
|
|
|
codec_chain_t *ret = g_slice_alloc0(sizeof(*ret)); |
|
|
|
ret->u.pcma2opus.enc = gpu_float2opus_new(bitrate); |
|
|
|
ret->u.pcma2opus.enc = cc_client_float2opus_new(cc_client, bitrate); |
|
|
|
ret->u.pcma2opus.runner = pcma2opus_runner; |
|
|
|
ret->avpkt = av_packet_alloc(); |
|
|
|
ret->run = codec_chain_pcma2opus_run; |
|
|
|
@ -4747,7 +4762,7 @@ codec_chain_t *codec_chain_new(codec_def_t *src, format_t *src_format, codec_def |
|
|
|
return NULL; |
|
|
|
|
|
|
|
codec_chain_t *ret = g_slice_alloc0(sizeof(*ret)); |
|
|
|
ret->u.pcmu2opus.enc = gpu_float2opus_new(bitrate); |
|
|
|
ret->u.pcmu2opus.enc = cc_client_float2opus_new(cc_client, bitrate); |
|
|
|
ret->u.pcmu2opus.runner = pcmu2opus_runner; |
|
|
|
ret->avpkt = av_packet_alloc(); |
|
|
|
ret->run = codec_chain_pcmu2opus_run; |
|
|
|
@ -4768,7 +4783,7 @@ codec_chain_t *codec_chain_new(codec_def_t *src, format_t *src_format, codec_def |
|
|
|
return NULL; |
|
|
|
|
|
|
|
codec_chain_t *ret = g_slice_alloc0(sizeof(*ret)); |
|
|
|
ret->u.opus2pcmu.dec = gpu_opus2float_new(); |
|
|
|
ret->u.opus2pcmu.dec = cc_client_opus2float_new(cc_client); |
|
|
|
ret->u.opus2pcmu.runner = opus2pcmu_runner; |
|
|
|
ret->avpkt = av_packet_alloc(); |
|
|
|
ret->run = codec_chain_opus2pcmu_run; |
|
|
|
@ -4789,7 +4804,7 @@ codec_chain_t *codec_chain_new(codec_def_t *src, format_t *src_format, codec_def |
|
|
|
return NULL; |
|
|
|
|
|
|
|
codec_chain_t *ret = g_slice_alloc0(sizeof(*ret)); |
|
|
|
ret->u.opus2pcma.dec = gpu_opus2float_new(); |
|
|
|
ret->u.opus2pcma.dec = cc_client_opus2float_new(cc_client); |
|
|
|
ret->u.opus2pcma.runner = opus2pcma_runner; |
|
|
|
ret->avpkt = av_packet_alloc(); |
|
|
|
ret->run = codec_chain_opus2pcma_run; |
|
|
|
@ -4802,7 +4817,7 @@ codec_chain_t *codec_chain_new(codec_def_t *src, format_t *src_format, codec_def |
|
|
|
} |
|
|
|
|
|
|
|
AVPacket *codec_chain_input_data(codec_chain_t *c, const str *data, unsigned long ts) { |
|
|
|
#ifdef HAVE_CUDECS |
|
|
|
#ifdef HAVE_CODEC_CHAIN |
|
|
|
av_new_packet(c->avpkt, MAX_OPUS_FRAME_SIZE * MAX_OPUS_FRAMES_PER_PACKET + MAX_OPUS_HEADER_SIZE); |
|
|
|
|
|
|
|
int ret = c->run(c, data, ts, c->avpkt); |
|
|
|
|