TT#32983 support transcoding options in redis (re)store

Change-Id: I8552743a5ec48b6d4464e8a2c4acd1c9bf11f02a
changes/10/19110/1
Richard Fuchs 8 years ago
parent 4d859bfd6b
commit 9147d5e438

@ -656,6 +656,17 @@ void payload_type_free(struct rtp_payload_type *p) {
g_slice_free1(sizeof(*p), p);
}
struct call_media *call_media_new(struct call *call) {
struct call_media *med;
med = uid_slice_alloc0(med, &call->medias);
med->call = call;
med->codecs_recv = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
med->codecs_send = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
med->codec_names_recv = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free);
med->codec_names_send = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free);
return med;
}
static struct call_media *__get_media(struct call_monologue *ml, GList **it, const struct stream_params *sp) {
struct call_media *med;
struct call *call;
@ -678,16 +689,11 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con
__C_DBG("allocating new call_media for stream #%u", sp->index);
call = ml->call;
med = uid_slice_alloc0(med, &call->medias);
med = call_media_new(call);
med->monologue = ml;
med->call = ml->call;
med->index = sp->index;
call_str_cpy(ml->call, &med->type, &sp->type);
med->type_id = codec_get_type(&med->type);
med->codecs_recv = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
med->codecs_send = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
med->codec_names_recv = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free);
med->codec_names_send = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free);
g_queue_push_tail(&ml->medias, med);

@ -429,6 +429,7 @@ int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams, co
int call_delete_branch(const str *callid, const str *branch,
const str *fromtag, const str *totag, bencode_item_t *output, int delete_delay);
void call_destroy(struct call *);
struct call_media *call_media_new(struct call *call);
enum call_stream_state call_stream_state_machine(struct packet_stream *);
void call_media_state_machine(struct call_media *m);
void call_media_unkernelize(struct call_media *media);

@ -693,7 +693,7 @@ static int handler_func_transcode(struct codec_handler *h, struct call_media *me
static struct rtp_payload_type *codec_make_dynamic_payload_type(const codec_def_t *dec, struct call_media *media,
int clockrate, int channels, int bitrate)
int clockrate, int channels, int bitrate, int ptime)
{
if (dec->default_channels <= 0 || dec->default_clockrate < 0)
return NULL;
@ -704,7 +704,7 @@ static struct rtp_payload_type *codec_make_dynamic_payload_type(const codec_def_
ret->clock_rate = clockrate ? : dec->default_clockrate;
ret->channels = channels ? : dec->default_channels;
ret->bitrate = bitrate;
ret->ptime = media->ptime ? : dec->default_ptime;
ret->ptime = ptime ? : (media->ptime ? : dec->default_ptime);
if (dec->init)
dec->init(ret);
@ -732,18 +732,20 @@ static struct rtp_payload_type *codec_make_dynamic_payload_type(const codec_def_
// special return value `(void *) 0x1` to signal type mismatch
static struct rtp_payload_type *codec_make_payload_type(const str *codec_str, struct call_media *media) {
struct rtp_payload_type *codec_make_payload_type(const str *codec_str, struct call_media *media) {
str codec_fmt = *codec_str;
str codec, parms, chans, opts;
str codec, parms, chans, opts, extra_opts;
if (str_token_sep(&codec, &codec_fmt, '/'))
return NULL;
str_token_sep(&parms, &codec_fmt, '/');
str_token_sep(&chans, &codec_fmt, '/');
str_token_sep(&opts, &codec_fmt, '/');
str_token_sep(&extra_opts, &codec_fmt, '/');
int clockrate = str_to_i(&parms, 0);
int channels = str_to_i(&chans, 0);
int bitrate = str_to_i(&opts, 0);
int ptime = str_to_i(&extra_opts, 0);
if (clockrate && !channels)
channels = 1;
@ -768,10 +770,11 @@ static struct rtp_payload_type *codec_make_payload_type(const str *codec_str, st
{
struct rtp_payload_type *ret = __rtp_payload_type_copy(rfc_pt);
ret->codec_def = dec;
ret->ptime = ptime;
return ret;
}
}
return codec_make_dynamic_payload_type(dec, media, clockrate, channels, bitrate);
return codec_make_dynamic_payload_type(dec, media, clockrate, channels, bitrate, ptime);
}
@ -835,28 +838,38 @@ static void __rtp_payload_type_add_name(GHashTable *ht, struct rtp_payload_type
g_queue_push_tail(q, GUINT_TO_POINTER(pt->payload_type));
}
// consumes 'pt'
static void __rtp_payload_type_add_recv(struct call_media *media,
void __rtp_payload_type_add_recv(struct call_media *media,
struct rtp_payload_type *pt)
{
if (!pt)
return;
g_hash_table_insert(media->codecs_recv, &pt->payload_type, pt);
__rtp_payload_type_add_name(media->codec_names_recv, pt);
g_queue_push_tail(&media->codecs_prefs_recv, pt);
}
// duplicates 'pt'
static void __rtp_payload_type_add_send(struct call_media *other_media,
// consumes 'pt'
void __rtp_payload_type_add_send(struct call_media *other_media,
struct rtp_payload_type *pt)
{
pt = __rtp_payload_type_copy(pt);
if (!pt)
return;
g_hash_table_insert(other_media->codecs_send, &pt->payload_type, pt);
__rtp_payload_type_add_name(other_media->codec_names_send, pt);
g_queue_push_tail(&other_media->codecs_prefs_send, pt);
}
// duplicates 'pt'
void __rtp_payload_type_add_send_dup(struct call_media *other_media,
struct rtp_payload_type *pt)
{
pt = __rtp_payload_type_copy(pt);
__rtp_payload_type_add_send(other_media, pt);
}
// consumes 'pt'
static void __rtp_payload_type_add(struct call_media *media, struct call_media *other_media,
struct rtp_payload_type *pt)
{
__rtp_payload_type_add_recv(media, pt);
__rtp_payload_type_add_send(other_media, pt);
__rtp_payload_type_add_send_dup(other_media, pt);
}
static void __payload_queue_free(void *qq) {

@ -43,6 +43,14 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_
GQueue *types, GHashTable *strip,
const GQueue *offer, const GQueue *transcode);
// special return value `(void *) 0x1` to signal type mismatch
struct rtp_payload_type *codec_make_payload_type(const str *codec_str, struct call_media *media);
// used by redis
void __rtp_payload_type_add_recv(struct call_media *media, struct rtp_payload_type *pt);
void __rtp_payload_type_add_send(struct call_media *other_media, struct rtp_payload_type *pt);
#ifdef WITH_TRANSCODING

@ -31,6 +31,7 @@
#include "str.h"
#include "ssrc.h"
#include "main.h"
#include "codec.h"
struct redis *rtpe_redis;
struct redis *rtpe_redis_write;
@ -1200,34 +1201,29 @@ static int redis_tags(struct call *c, struct redis_list *tags) {
return 0;
}
static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) {
struct rtp_payload_type *pt;
str ptype, enc, clock, enc_parms, fmt_parms;
static struct rtp_payload_type *rbl_cb_plts_g(str *s, GQueue *q, struct redis_list *list, void *ptr) {
str ptype;
struct call_media *med = ptr;
struct call *call = med->call;
if (str_token(&ptype, s, '/'))
return -1;
if (str_token(&enc, s, '/'))
return -1;
if (str_token(&clock, s, '/'))
return -1;
if (str_token(&enc_parms, s, '/')) {
enc_parms = *s;
fmt_parms = STR_EMPTY;
}
else
fmt_parms = *s;
// from call.c
// XXX remove all the duplicate code
pt = g_slice_alloc0(sizeof(*pt));
pt->payload_type = str_to_ui(&ptype, 0);
call_str_cpy(call, &pt->encoding, &enc);
pt->clock_rate = str_to_ui(&clock, 0);
call_str_cpy(call, &pt->encoding_parameters, &enc_parms);
call_str_cpy(call, &pt->format_parameters, &fmt_parms);
g_hash_table_replace(med->codecs_recv, &pt->payload_type, pt);
return NULL;
struct rtp_payload_type *pt = codec_make_payload_type(s, med);
if (!pt || pt == (void *) 0x1)
return NULL;
pt->payload_type = str_to_i(&ptype, 0);
return pt;
}
static int rbl_cb_plts_r(str *s, GQueue *q, struct redis_list *list, void *ptr) {
struct call_media *med = ptr;
__rtp_payload_type_add_recv(med, rbl_cb_plts_g(s, q, list, ptr));
return 0;
}
static int rbl_cb_plts_s(str *s, GQueue *q, struct redis_list *list, void *ptr) {
struct call_media *med = ptr;
__rtp_payload_type_add_send(med, rbl_cb_plts_g(s, q, list, ptr));
return 0;
}
static int json_medias(struct call *c, struct redis_list *medias, JsonReader *root_reader) {
@ -1240,10 +1236,7 @@ static int json_medias(struct call *c, struct redis_list *medias, JsonReader *ro
rh = &medias->rh[i];
/* from call.c:__get_media() */
med = uid_slice_alloc0(med, &c->medias);
med->call = c;
med->codecs_recv = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
(GDestroyNotify) payload_type_free);
med = call_media_new(c);
if (redis_hash_get_unsigned(&med->index, rh, "index"))
return -1;
@ -1278,7 +1271,8 @@ static int json_medias(struct call *c, struct redis_list *medias, JsonReader *ro
if (redis_hash_get_crypto_params(&med->sdes_out.params, rh, "sdes_out") < 0)
return -1;
json_build_list_cb(NULL, c, "payload_types", i, NULL, rbl_cb_plts, med, root_reader);
json_build_list_cb(NULL, c, "payload_types", i, NULL, rbl_cb_plts_r, med, root_reader);
json_build_list_cb(NULL, c, "payload_types_send", i, NULL, rbl_cb_plts_s, med, root_reader);
/* XXX dtls */
medias->ptrs[i] = med;
@ -1409,6 +1403,17 @@ static int json_link_medias(struct call *c, struct redis_list *medias,
return -1;
if (json_build_list(&med->endpoint_maps, c, "maps", &c->callid, i, maps, root_reader))
return -1;
// find the pair media
struct call_monologue *ml = med->monologue;
struct call_monologue *other_ml = ml->active_dialogue;
for (GList *l = other_ml->medias.head; l; l = l->next) {
struct call_media *other_m = l->data;
if (other_m->index == med->index) {
codec_handlers_update(med, other_m);
break;
}
}
}
return 0;
}
@ -1971,6 +1976,7 @@ char* redis_encode_json(struct call *c) {
JSON_SET_SIMPLE("sdes_in_tag","%u",media->sdes_in.tag);
JSON_SET_SIMPLE("sdes_out_tag","%u",media->sdes_out.tag);
JSON_SET_SIMPLE_STR("logical_intf",&media->logical_intf->name);
JSON_SET_SIMPLE("ptime","%i",media->ptime);
JSON_SET_SIMPLE("media_flags","%u",media->media_flags);
json_update_crypto_params(builder, "media", media->unique_id, "sdes_in",
@ -1978,9 +1984,6 @@ char* redis_encode_json(struct call *c) {
json_update_crypto_params(builder, "media", media->unique_id, "sdes_out",
&media->sdes_out.params);
json_update_dtls_fingerprint(builder, "media", media->unique_id, &media->fingerprint);
// streams and maps- and payload_types- was here before
}
json_builder_end_object (builder);
@ -2009,20 +2012,29 @@ char* redis_encode_json(struct call *c) {
}
json_builder_end_array (builder);
k = g_hash_table_get_values(media->codecs_recv);
snprintf(tmp, sizeof(tmp), "payload_types-%u", media->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);
for (m = k; m; m = m->next) {
for (m = media->codecs_prefs_recv.head; m; m = m->next) {
pt = m->data;
JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT "/" STR_FORMAT,
JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT "/" STR_FORMAT "/%i/%i",
pt->payload_type, STR_FMT(&pt->encoding),
pt->clock_rate, STR_FMT(&pt->encoding_parameters),
STR_FMT(&pt->format_parameters));
STR_FMT(&pt->format_parameters), pt->bitrate, pt->ptime);
}
json_builder_end_array (builder);
g_list_free(k);
snprintf(tmp, sizeof(tmp), "payload_types_send-%u", media->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);
for (m = media->codecs_prefs_send.head; m; m = m->next) {
pt = m->data;
JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT "/" STR_FORMAT "/%i/%i",
pt->payload_type, STR_FMT(&pt->encoding),
pt->clock_rate, STR_FMT(&pt->encoding_parameters),
STR_FMT(&pt->format_parameters), pt->bitrate, pt->ptime);
}
json_builder_end_array (builder);
}
for (l = c->endpoint_maps.head; l; l = l->next) {

Loading…
Cancel
Save