|
|
|
@ -36,6 +36,7 @@ static void __ssrc_handler_free(struct codec_ssrc_handler *p); |
|
|
|
static void __transcode_packet_free(struct transcode_packet *); |
|
|
|
|
|
|
|
static struct rtp_payload_type *__rtp_payload_type_copy(const struct rtp_payload_type *pt); |
|
|
|
static void __rtp_payload_type_dup(struct call *call, struct rtp_payload_type *pt); |
|
|
|
static void __rtp_payload_type_add_name(GHashTable *, struct rtp_payload_type *pt); |
|
|
|
|
|
|
|
|
|
|
|
@ -83,8 +84,9 @@ static void __make_transcoder(struct codec_handler *handler, struct rtp_payload_ |
|
|
|
handler->ssrc_hash = create_ssrc_hash_full(__ssrc_handler_new, (ssrc_free_func_t) __ssrc_handler_free, |
|
|
|
handler); |
|
|
|
|
|
|
|
ilog(LOG_DEBUG, "Created transcode context for '" STR_FORMAT "' -> '" STR_FORMAT "'", |
|
|
|
STR_FMT(&source->encoding), STR_FMT(&dest->encoding)); |
|
|
|
ilog(LOG_DEBUG, "Created transcode context for " STR_FORMAT "/%u/%i -> " STR_FORMAT "/%u/%i", |
|
|
|
STR_FMT(&source->encoding), source->clock_rate, source->channels, |
|
|
|
STR_FMT(&dest->encoding), dest->clock_rate, dest->channels); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
@ -304,6 +306,12 @@ static void __transcode_packet_free(struct transcode_packet *p) { |
|
|
|
|
|
|
|
static struct ssrc_entry *__ssrc_handler_new(void *p) { |
|
|
|
struct codec_handler *h = p; |
|
|
|
|
|
|
|
ilog(LOG_DEBUG, "Creating SSRC handler to transcode from %s/%u/%i to %s/%u/%i", |
|
|
|
h->source_pt.codec_def->rtpname, h->source_pt.clock_rate, |
|
|
|
h->source_pt.channels, h->dest_pt.codec_def->rtpname, h->dest_pt.clock_rate, |
|
|
|
h->dest_pt.channels); |
|
|
|
|
|
|
|
struct codec_ssrc_handler *ch = g_slice_alloc0(sizeof(*ch)); |
|
|
|
ch->handler = h; |
|
|
|
mutex_init(&ch->lock); |
|
|
|
@ -441,13 +449,45 @@ void codec_packet_free(void *pp) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct rtp_payload_type *codec_make_payload_type(const str *codec) { |
|
|
|
static struct rtp_payload_type *codec_make_dynamic_payload_type(const codec_def_t *dec, struct call *call) { |
|
|
|
if (dec->default_channels <= 0 || dec->default_clockrate < 0) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
struct rtp_payload_type *ret = g_slice_alloc0(sizeof(*ret)); |
|
|
|
ret->payload_type = -1; |
|
|
|
str_init(&ret->encoding, (char *) dec->rtpname); |
|
|
|
ret->clock_rate = dec->default_clockrate; |
|
|
|
ret->channels = dec->default_channels; |
|
|
|
|
|
|
|
char full_encoding[64]; |
|
|
|
char params[32] = ""; |
|
|
|
|
|
|
|
if (ret->channels > 1) { |
|
|
|
snprintf(full_encoding, sizeof(full_encoding), "%s/%u/%i", dec->rtpname, ret->clock_rate, |
|
|
|
ret->channels); |
|
|
|
snprintf(params, sizeof(params), "%i", ret->channels); |
|
|
|
} |
|
|
|
else |
|
|
|
snprintf(full_encoding, sizeof(full_encoding), "%s/%u", dec->rtpname, ret->clock_rate); |
|
|
|
|
|
|
|
str_init(&ret->encoding_with_params, full_encoding); |
|
|
|
str_init(&ret->encoding_parameters, params); |
|
|
|
ret->format_parameters = STR_EMPTY; |
|
|
|
ret->codec_def = dec; |
|
|
|
|
|
|
|
__rtp_payload_type_dup(call, ret); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// XXX allow specifying codec params (e.g. "transcode=opus/16000/1") |
|
|
|
static struct rtp_payload_type *codec_make_payload_type(const str *codec, struct call *call) { |
|
|
|
const codec_def_t *dec = codec_find(codec); |
|
|
|
if (!dec) |
|
|
|
return NULL; |
|
|
|
const struct rtp_payload_type *rfc_pt = rtp_get_rfc_codec(codec); |
|
|
|
if (!rfc_pt) |
|
|
|
return NULL; // XXX amend for other codecs |
|
|
|
return codec_make_dynamic_payload_type(dec, call); |
|
|
|
|
|
|
|
struct rtp_payload_type *ret = __rtp_payload_type_copy(rfc_pt); |
|
|
|
ret->codec_def = dec; |
|
|
|
@ -457,7 +497,7 @@ static struct rtp_payload_type *codec_make_payload_type(const str *codec) { |
|
|
|
|
|
|
|
|
|
|
|
static struct rtp_payload_type *codec_add_payload_type(const str *codec, struct call_media *media) { |
|
|
|
struct rtp_payload_type *pt = codec_make_payload_type(codec); |
|
|
|
struct rtp_payload_type *pt = codec_make_payload_type(codec, media->call); |
|
|
|
if (!pt) { |
|
|
|
ilog(LOG_WARN, "Codec '" STR_FORMAT "' requested for transcoding is not supported", |
|
|
|
STR_FMT(codec)); |
|
|
|
|