MT#56447 change ml->medias to GPtrArray

Using a pointer array instead of a linked lists allows us to directly
reference a media section by index number, without having to spool into
the linked list.

No functional changes.

Change-Id: I8b0e93f0c2e9addbcb4c938894118ed4a6aec768
pull/1642/head
Richard Fuchs 2 years ago
parent 889941416a
commit 5822cb889d

@ -851,27 +851,14 @@ struct call_media *call_media_new(struct call *call) {
return med;
}
static struct call_media *__get_media(struct call_monologue *ml, GList **it, const struct stream_params *sp,
const struct sdp_ng_flags *flags, int index)
static struct call_media *__get_media(struct call_monologue *ml, const struct stream_params *sp,
const struct sdp_ng_flags *flags, unsigned int index)
{
struct call_media *med;
struct call *call;
// is this a repeated call with *it set but for a different ml?
if (*it) {
med = (*it)->data;
if (med->monologue != ml)
*it = NULL;
}
/* iterator points to last seen element, or NULL if uninitialized */
if (!*it)
*it = ml->medias.head;
else
*it = (*it)->next;
// check for trickle ICE SDP fragment
if (flags && flags->fragment && sp->media_id.s) {
if (flags && flags->fragment && sp->media_id.len) {
// in this case, the media sections are out of order and the media ID
// string is used to determine which media section to operate on. this
// info must be present and valid.
@ -883,18 +870,19 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con
STR_FMT(&sp->media_id));
}
unsigned int want_index = sp->index;
if (index != -1)
want_index = index;
unsigned int want_index = index;
if (want_index == 0)
want_index = sp->index;
assert(want_index > 0);
unsigned int arr_index = want_index - 1;
/* possible incremental update, hunt for correct media struct */
while (*it) {
med = (*it)->data;
if (med->index == want_index) {
__C_DBG("found existing call_media for stream #%u", want_index);
return med;
}
*it = (*it)->next;
// check if we have an existing media struct. resize array if needed
if (arr_index >= ml->medias->len)
g_ptr_array_set_size(ml->medias, want_index);
if (ml->medias->pdata[arr_index]) {
__C_DBG("found existing call_media for stream #%u", want_index);
return ml->medias->pdata[arr_index];
}
__C_DBG("allocating new call_media for stream #%u", want_index);
@ -905,9 +893,7 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con
call_str_cpy(ml->call, &med->type, &sp->type);
med->type_id = sp->type_id;
g_queue_push_tail(&ml->medias, med);
*it = ml->medias.tail;
ml->medias->pdata[arr_index] = med;
return med;
}
@ -2772,26 +2758,12 @@ static void __update_init_subscribers(struct call_monologue *ml, GQueue *streams
{
GList *sl = streams ? streams->head : NULL;
// create media iterators for all subscribers
GList *sub_medias[ml->subscribers.length];
struct sink_attrs attrs[ml->subscribers.length];
unsigned int num_subs = 0;
for (GList *l = ml->subscribers.head; l; l = l->next) {
struct call_subscription *cs = l->data;
struct call_monologue *sub_ml = cs->monologue;
sub_medias[num_subs] = sub_ml->medias.head;
// skip into correct media section for multi-ml subscriptions
for (unsigned int offset = cs->media_offset; offset && sub_medias[num_subs]; offset--)
sub_medias[num_subs] = sub_medias[num_subs]->next;
attrs[num_subs] = cs->attrs;
num_subs++;
}
// keep num_subs as shortcut to ml->subscribers.length
recording_setup_monologue(ml);
for (GList *l = ml->medias.head; l; l = l->next) {
struct call_media *media = l->data;
for (unsigned int j = 0; j < ml->medias->len; j++) {
struct call_media *media = ml->medias->pdata[j];
if (!media)
continue;
struct stream_params *sp = NULL;
if (sl) {
@ -2803,14 +2775,17 @@ static void __update_init_subscribers(struct call_monologue *ml, GQueue *streams
// update all subscribers
__reset_streams(media);
for (unsigned int i = 0; i < num_subs; i++) {
if (!sub_medias[i])
continue;
struct call_media *sub_media = sub_medias[i]->data;
sub_medias[i] = sub_medias[i]->next;
if (__init_streams(media, sub_media, sp, flags, &attrs[i]))
for (GList *l = ml->subscribers.head; l; l = l->next) {
struct call_subscription *cs = l->data;
struct call_monologue *sub_ml = cs->monologue;
unsigned int sub_media_idx = j + cs->media_offset;
if (sub_media_idx >= sub_ml->medias->len)
continue;
struct call_media *sub_media = sub_ml->medias->pdata[sub_media_idx];
if (!sub_media)
continue;
if (__init_streams(media, sub_media, sp, flags, &cs->attrs))
ilog(LOG_WARN, "Error initialising streams");
}
@ -3039,8 +3014,6 @@ unsigned int proto_num_ports(unsigned int sp_ports, struct call_media *media, st
int monologue_offer_answer(struct call_monologue *dialogue[2], GQueue *streams,
struct sdp_ng_flags *flags)
{
struct stream_params *sp;
GList *media_iter, *ml_media, *other_ml_media;
struct call_media *media, *other_media;
struct endpoint_map *em;
struct call_monologue *other_ml = dialogue[0];
@ -3058,18 +3031,17 @@ int monologue_offer_answer(struct call_monologue *dialogue[2], GQueue *streams,
__C_DBG("this="STR_FORMAT" other="STR_FORMAT, STR_FMT(&monologue->tag), STR_FMT(&other_ml->tag));
ml_media = other_ml_media = NULL;
set_transcoding_flag(monologue, other_ml, false);
for (media_iter = streams->head; media_iter; media_iter = media_iter->next) {
sp = media_iter->data;
for (GList *sp_iter = streams->head; sp_iter; sp_iter = sp_iter->next) {
struct stream_params *sp = sp_iter->data;
__C_DBG("processing media stream #%u", sp->index);
assert(sp->index > 0);
/* first, check for existence of call_media struct on both sides of
* the dialogue */
media = __get_media(monologue, &ml_media, sp, flags, -1);
other_media = __get_media(other_ml, &other_ml_media, sp, flags, -1);
media = __get_media(monologue, sp, flags, 0);
other_media = __get_media(other_ml, sp, flags, 0);
/* OTHER is the side which has sent the message. SDP parameters in
* "sp" are as advertised by OTHER side. The message will be sent to
* THIS side. Parameters sent to THIS side may be overridden by
@ -3320,11 +3292,9 @@ struct call_subscription *call_get_call_subscription(GHashTable *ht, struct call
int monologue_publish(struct call_monologue *ml, GQueue *streams, struct sdp_ng_flags *flags) {
__call_monologue_init_from_flags(ml, flags);
GList *media_iter = NULL;
for (GList *l = streams->head; l; l = l->next) {
struct stream_params *sp = l->data;
struct call_media *media = __get_media(ml, &media_iter, sp, flags, -1);
struct call_media *media = __get_media(ml, sp, flags, 0);
__media_init_from_flags(media, NULL, sp, flags);
@ -3381,15 +3351,15 @@ int monologue_publish(struct call_monologue *ml, GQueue *streams, struct sdp_ng_
/* called with call->master_lock held in W */
static int monologue_subscribe_request1(struct call_monologue *src_ml, struct call_monologue *dst_ml,
struct sdp_ng_flags *flags, GList **src_media_it, GList **dst_media_it, unsigned int *index)
struct sdp_ng_flags *flags, unsigned int *index)
{
unsigned int idx_diff = 0, rev_idx_diff = 0;
for (GList *l = src_ml->last_in_sdp_streams.head; l; l = l->next) {
struct stream_params *sp = l->data;
struct call_media *dst_media = __get_media(dst_ml, dst_media_it, sp, flags, (*index)++);
struct call_media *src_media = __get_media(src_ml, src_media_it, sp, flags, -1);
struct call_media *dst_media = __get_media(dst_ml, sp, flags, (*index)++);
struct call_media *src_media = __get_media(src_ml, sp, flags, 0);
// track media index difference if one ml is subscribed to multiple other mls
if (idx_diff == 0 && dst_media->index > src_media->index)
@ -3457,16 +3427,13 @@ int monologue_subscribe_request(const GQueue *srcs, struct call_monologue *dst_m
__call_monologue_init_from_flags(dst_ml, flags);
GList *dst_media_it = NULL;
GList *src_media_it = NULL;
unsigned int index = 1; // running counter for output/dst medias
for (GList *sl = srcs->head; sl; sl = sl->next) {
struct call_subscription *cs = sl->data;
struct call_monologue *src_ml = cs->monologue;
int ret = monologue_subscribe_request1(src_ml, dst_ml, flags, &src_media_it, &dst_media_it,
&index);
int ret = monologue_subscribe_request1(src_ml, dst_ml, flags, &index);
if (ret)
return -1;
}
@ -3475,8 +3442,6 @@ int monologue_subscribe_request(const GQueue *srcs, struct call_monologue *dst_m
/* called with call->master_lock held in W */
int monologue_subscribe_answer(struct call_monologue *dst_ml, struct sdp_ng_flags *flags, GQueue *streams) {
GList *dst_media_it = NULL;
GList *src_media_it = NULL;
GList *src_ml_it = dst_ml->subscriptions.head;
unsigned int index = 1; // running counter for input/src medias
@ -3485,21 +3450,23 @@ int monologue_subscribe_answer(struct call_monologue *dst_ml, struct sdp_ng_flag
for (GList *l = streams->head; l; l = l->next) {
struct stream_params *sp = l->data;
struct call_subscription *cs = src_ml_it->data;
struct call_monologue *src_ml = cs->monologue;
// grab the matching source ml:
// we need to move to the next one when we've reached the last media of
// the current source ml
if (src_media_it && !src_media_it->next) {
if (index > src_ml->medias->len) {
src_ml_it = src_ml_it->next;
index = 1; // starts over at 1
cs = src_ml_it->data;
src_ml = cs->monologue;
}
if (!src_ml_it)
return -1;
struct call_subscription *cs = src_ml_it->data;
struct call_monologue *src_ml = cs->monologue;
struct call_media *dst_media = __get_media(dst_ml, &dst_media_it, sp, flags, -1);
struct call_media *src_media = __get_media(src_ml, &src_media_it, sp, flags, index++);
struct call_media *dst_media = __get_media(dst_ml, sp, flags, 0);
struct call_media *src_media = __get_media(src_ml, sp, flags, index++);
if (__media_init_from_flags(dst_media, NULL, sp, flags) == 1)
continue;
@ -3762,8 +3729,10 @@ void call_destroy(struct call *c) {
STR_FMT_M(&csm->tag));
}
for (k = ml->medias.head; k; k = k->next) {
md = k->data;
for (unsigned int m = 0; m < ml->medias->len; m++) {
md = ml->medias->pdata[m];
if (!md)
continue;
// stats output only - no cleanups
@ -3951,7 +3920,7 @@ static void __call_free(void *p) {
while (c->monologues.head) {
m = g_queue_pop_head(&c->monologues);
g_queue_clear(&m->medias);
g_ptr_array_free(m->medias, true);
g_hash_table_destroy(m->associated_tags);
g_hash_table_destroy(m->media_ids);
free_ssrc_hash(&m->ssrc_hash);
@ -4154,12 +4123,12 @@ struct call_monologue *__monologue_create(struct call *call) {
ret->call = call;
ret->created = rtpe_now.tv_sec;
ret->associated_tags = g_hash_table_new(g_direct_hash, g_direct_equal);
ret->medias = g_ptr_array_new();
ret->media_ids = g_hash_table_new(str_hash, str_equal);
ret->ssrc_hash = create_ssrc_hash_call();
ret->subscribers_ht = g_hash_table_new(g_direct_hash, g_direct_equal);
ret->subscriptions_ht = g_hash_table_new(g_direct_hash, g_direct_equal);
g_queue_init(&ret->medias);
gettimeofday(&ret->started, NULL);
return ret;
@ -4203,18 +4172,16 @@ static void __unconfirm_sinks(GQueue *q) {
}
/* must be called with call->master_lock held in W */
void __monologue_unkernelize(struct call_monologue *monologue) {
GList *l, *m;
struct call_media *media;
struct packet_stream *stream;
if (!monologue)
return;
for (l = monologue->medias.head; l; l = l->next) {
media = l->data;
for (unsigned int i = 0; i < monologue->medias->len; i++) {
struct call_media *media = monologue->medias->pdata[i];
if (!media)
continue;
for (m = media->streams.head; m; m = m->next) {
stream = m->data;
for (GList *m = media->streams.head; m; m = m->next) {
struct packet_stream *stream = m->data;
__stream_unconfirm(stream);
__unconfirm_sinks(&stream->rtp_sinks);
__unconfirm_sinks(&stream->rtcp_sinks);
@ -4280,8 +4247,10 @@ void monologue_destroy(struct call_monologue *monologue) {
g_hash_table_remove(call->viabranches, &monologue->viabranch);
// close sockets
for (GList *l = monologue->medias.head; l; l = l->next) {
struct call_media *m = l->data;
for (unsigned int i = 0; i < monologue->medias->len; i++) {
struct call_media *m = monologue->medias->pdata[i];
if (!m)
continue;
for (GList *k = m->streams.head; k; k = k->next) {
struct packet_stream *ps = k->data;
if (ps->selected_sfd && ps->selected_sfd->socket.local.port)
@ -4603,6 +4572,8 @@ int call_get_mono_dialogue(struct call_monologue *dialogue[2], struct call *call
static void media_stop(struct call_media *m) {
if (!m)
return;
t38_gateway_stop(m->t38_gateway);
audio_player_stop(m);
codec_handlers_stop(&m->codec_handlers_store);
@ -4614,8 +4585,8 @@ static void __monologue_stop(struct call_monologue *ml) {
}
static void monologue_stop(struct call_monologue *ml) {
__monologue_stop(ml);
for (GList *l = ml->medias.head; l; l = l->next)
media_stop(l->data);
for (unsigned int i = 0; i < ml->medias->len; i++)
media_stop(ml->medias->pdata[i]);
}

@ -72,10 +72,9 @@ static int call_stream_address_gstring(GString *o, struct packet_stream *ps, enu
return ret;
}
static str *streams_print(GQueue *s, int start, int end, const char *prefix, enum stream_address_format format) {
static str *streams_print(GPtrArray *s, int start, int end, const char *prefix, enum stream_address_format format) {
GString *o;
int i, af, port;
GList *l;
struct call_media *media;
struct packet_stream *ps;
@ -84,18 +83,14 @@ static str *streams_print(GQueue *s, int start, int end, const char *prefix, enu
g_string_append_printf(o, "%s ", prefix);
for (i = start; i <= end; i++) {
for (l = s->head; l; l = l->next) {
media = l->data;
if (media->index == i)
goto found;
if (s->len <= i || (media = s->pdata[i - 1]) == NULL) {
ilog(LOG_WARNING, "Requested media index %i not found", i);
break;
}
ilog(LOG_WARNING, "Requested media index %i not found", i);
goto out;
found:
if (!media->streams.head) {
ilog(LOG_WARNING, "Media has no streams");
goto out;
break;
}
ps = media->streams.head->data;
@ -112,7 +107,6 @@ found:
}
out:
g_string_append(o, "\n");
return g_string_free_str(o);
@ -222,7 +216,7 @@ static str *call_update_lookup_udp(char **out, enum call_opmode opmode, const ch
if (i)
goto unlock_fail;
ret = streams_print(&dialogue[1]->medias,
ret = streams_print(dialogue[1]->medias,
sp.index, sp.index, out[RE_UDP_COOKIE], SAF_UDP);
rwlock_unlock_w(&c->master_lock);
@ -364,7 +358,7 @@ static str *call_request_lookup_tcp(char **out, enum call_opmode opmode) {
if (monologue_offer_answer(dialogue, &s, NULL))
goto out2;
ret = streams_print(&dialogue[1]->medias, 1, s.length, NULL, SAF_TCP);
ret = streams_print(dialogue[1]->medias, 1, s.length, NULL, SAF_TCP);
out2:
call_unlock_release_update(&c);
@ -2416,7 +2410,6 @@ static void ng_stats_monologue(bencode_item_t *dict, const struct call_monologue
struct call_stats *totals, bencode_item_t *ssrc)
{
bencode_item_t *sub, *medias = NULL;
GList *l;
struct call_media *m;
if (!ml)
@ -2458,8 +2451,10 @@ static void ng_stats_monologue(bencode_item_t *dict, const struct call_monologue
medias = bencode_dictionary_add_list(sub, "medias");
stats:
for (l = ml->medias.head; l; l = l->next) {
m = l->data;
for (unsigned int i = 0; i < ml->medias->len; i++) {
m = ml->medias->pdata[i];
if (!m)
continue;
ng_stats_media(medias, m, totals);
}
}
@ -2745,8 +2740,10 @@ static const char *media_block_match1(struct call *call, struct call_monologue *
// walk our structures to find a matching stream
for (GList *l = call->monologues.head; l; l = l->next) {
*monologue = l->data;
for (GList *k = (*monologue)->medias.head; k; k = k->next) {
struct call_media *media = k->data;
for (unsigned int k = 0; k < (*monologue)->medias->len; k++) {
struct call_media *media = (*monologue)->medias->pdata[k];
if (!media)
continue;
if (!media->streams.head)
continue;
struct packet_stream *ps = media->streams.head->data;
@ -2921,8 +2918,10 @@ const char *call_stop_forwarding_ng(bencode_item_t *input, bencode_item_t *outpu
static void call_monologue_set_block_mode(struct call_monologue *ml, struct sdp_ng_flags *flags) {
if (flags->delay_buffer >= 0) {
for (GList *l = ml->medias.head; l; l = l->next) {
struct call_media *media = l->data;
for (unsigned int i = 0; i < ml->medias->len; i++) {
struct call_media *media = ml->medias->pdata[i];
if (!media)
continue;
media->buffer_delay = flags->delay_buffer;
}
}
@ -3018,8 +3017,10 @@ const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output)
monologue->block_dtmf = BLOCK_DTMF_OFF;
if (is_dtmf_replace_mode(prev_mode) || flags.delay_buffer >= 0) {
if (flags.delay_buffer >= 0) {
for (GList *l = monologue->medias.head; l; l = l->next) {
struct call_media *media = l->data;
for (unsigned int i = 0; i < monologue->medias->len; i++) {
struct call_media *media = monologue->medias->pdata[i];
if (!media)
continue;
media->buffer_delay = flags.delay_buffer;
}
}
@ -3040,8 +3041,10 @@ const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output)
monologue->block_dtmf = BLOCK_DTMF_OFF;
}
if (flags.delay_buffer >= 0) {
for (GList *k = monologue->medias.head; k; k = k->next) {
struct call_media *media = k->data;
for (unsigned int i = 0; i < monologue->medias->len; i++) {
struct call_media *media = monologue->medias->pdata[i];
if (!media)
continue;
media->buffer_delay = flags.delay_buffer;
}
}
@ -3344,8 +3347,10 @@ const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
// find a usable output media
struct call_media *media;
for (GList *l = monologue->medias.head; l; l = l->next) {
media = l->data;
for (unsigned int i = 0; i < monologue->medias->len; i++) {
media = monologue->medias->pdata[i];
if (!media)
continue;
if (media->type_id != MT_AUDIO)
continue;
goto found;
@ -3359,8 +3364,10 @@ found:
struct call_subscription *cs = k->data;
struct call_monologue *dialogue = cs->monologue;
struct call_media *sink = NULL;
for (GList *m = dialogue->medias.head; m; m = m->next) {
sink = m->data;
for (unsigned int i = 0; i < dialogue->medias->len; i++) {
sink = dialogue->medias->pdata[i];
if (!sink)
continue;
if (sink->type_id != MT_AUDIO)
continue;
goto found_sink;
@ -3531,8 +3538,10 @@ const char *call_subscribe_request_ng(bencode_item_t *input, bencode_item_t *out
if (source_ml->label.len)
bencode_dictionary_add_str(tag_label, "label", &source_ml->label);
bencode_item_t *medias = bencode_dictionary_add_list(tag_label, "medias");
for (GList *k = source_ml->medias.head; k; k = k->next) {
struct call_media *media = k->data;
for (unsigned int i = 0; i < source_ml->medias->len; i++) {
struct call_media *media = source_ml->medias->pdata[i];
if (!media)
continue;
bencode_item_t *med_ent = bencode_list_add_dictionary(medias);
bencode_dictionary_add_integer(med_ent, "index", media->index);
bencode_dictionary_add_str(med_ent, "type", &media->type);

@ -90,8 +90,10 @@ void cdr_update_entry(struct call* c) {
}
}
for (k = ml->medias.head; k; k = k->next) {
md = k->data;
for (unsigned int i = 0; i < ml->medias->len; i++) {
md = ml->medias->pdata[i];
if (!md)
continue;
rtp_pt = __rtp_stats_codec(md);

@ -671,8 +671,10 @@ static void cli_list_tag_info(struct cli_writer *cw, struct call_monologue *ml)
STR_FMT_M(&csm->tag));
}
for (GList *k = ml->medias.head; k; k = k->next) {
md = k->data;
for (unsigned int k = 0; k < ml->medias->len; k++) {
md = ml->medias->pdata[k];
if (!md)
continue;
const struct rtp_payload_type *rtp_pt = __rtp_stats_codec(md);
@ -1586,8 +1588,10 @@ static void cli_incoming_tag_delay(str *instr, struct cli_writer *cw) {
cw->cw_printf(cw, "Setting delay to %i\n", delay);
for (GList *l = cw->ml->medias.head; l; l = l->next) {
struct call_media *m = l->data;
for (unsigned int k = 0; k < cw->ml->medias->len; k++) {
struct call_media *m = cw->ml->medias->pdata[k];
if (!m)
continue;
m->buffer_delay = delay;
}
codec_update_all_handlers(cw->ml);

@ -3996,14 +3996,14 @@ void codec_update_all_handlers(struct call_monologue *ml) {
struct call_monologue *sink = cs->monologue;
// iterate both simultaneously
GList *source_media_it = ml->medias.head;
GList *sink_media_it = sink->medias.head;
while (source_media_it && sink_media_it) {
struct call_media *source_media = source_media_it->data;
struct call_media *sink_media = sink_media_it->data;
for (unsigned int i = 0; i < ml->medias->len && i < sink->medias->len; i++) {
struct call_media *source_media = ml->medias->pdata[i];
if (!source_media)
continue;
struct call_media *sink_media = sink->medias->pdata[i];
if (!sink_media)
continue;
codec_handlers_update(source_media, sink_media, NULL, NULL);
source_media_it = source_media_it->next;
sink_media_it = sink_media_it->next;
}
}
@ -4015,14 +4015,15 @@ void codec_update_all_source_handlers(struct call_monologue *ml, const struct sd
struct call_monologue *source = cs->monologue;
// iterate both simultaneously
GList *source_media_it = source->medias.head;
GList *sink_media_it = ml->medias.head;
while (source_media_it && sink_media_it) {
struct call_media *source_media = source_media_it->data;
struct call_media *sink_media = sink_media_it->data;
for (unsigned int i = 0; i < source->medias->len && i < ml->medias->len; i++) {
struct call_media *source_media = source->medias->pdata[i];
if (!source_media)
continue;
struct call_media *sink_media = ml->medias->pdata[i];
if (!sink_media)
continue;
codec_handlers_update(source_media, sink_media, flags, NULL);
source_media_it = source_media_it->next;
sink_media_it = sink_media_it->next;
}
}

@ -307,8 +307,10 @@ static void janus_add_publisher_details(JsonBuilder *builder, struct call_monolo
const char *a_codec = NULL, *v_codec = NULL;
for (GList *l = ml->medias.head; l; l = l->next) {
struct call_media *media = l->data;
for (unsigned int i = 0; i < ml->medias->len; i++) {
struct call_media *media = ml->medias->pdata[i];
if (!media)
continue;
const char *codec = NULL;
for (GList *k = media->codecs.codec_prefs.head; k; k = k->next) {
@ -877,8 +879,10 @@ static const char *janus_videoroom_configure(struct websocket_message *wm, struc
json_builder_add_string_value(builder, "ok");
// apply audio/video bool flags
for (GList *l = ml->medias.head; l; l = l->next) {
struct call_media *media = l->data;
for (unsigned int i = 0; i < ml->medias->len; i++) {
struct call_media *media = ml->medias->pdata[i];
if (!media)
continue;
if (media->type_id == MT_AUDIO) {
if (has_audio == 0)
@ -1555,8 +1559,8 @@ const char *janus_trickle(JsonReader *reader, struct janus_session *session, uin
str sdp_mid_str = STR_CONST_INIT_LEN((char *) sdp_mid, strlen(sdp_mid));
media = g_hash_table_lookup(ml->media_ids, &sdp_mid_str);
}
if (!media && sdp_m_line >= 0)
media = g_queue_peek_nth(&ml->medias, sdp_m_line);
if (!media && sdp_m_line >= 0 && ml->medias->len > sdp_m_line)
media = ml->medias->pdata[sdp_m_line];
*retcode = 466;
if (!media)

@ -887,8 +887,8 @@ static const struct rtp_payload_type *media_player_play_init(struct media_player
// find call media suitable for playback
struct call_media *media;
for (GList *l = mp->ml->medias.head; l; l = l->next) {
media = l->data;
for (unsigned int i = 0; i < mp->ml->medias->len; i++) {
media = mp->ml->medias->pdata[i];
if (media->type_id != MT_AUDIO)
continue;
if (!MEDIA_ISSET(media, SEND))

@ -2907,8 +2907,10 @@ out:
for (GList *l = phc->mp.media->monologue->subscriptions.head; l; l = l->next) {
struct call_subscription *cs = l->data;
struct call_monologue *sub = cs->monologue;
for (GList *k = sub->medias.head; k; k = k->next) {
struct call_media *sub_media = k->data;
for (unsigned int k = 0; k < sub->medias->len; k++) {
struct call_media *sub_media = sub->medias->pdata[k];
if (!sub_media)
continue;
for (GList *m = sub_media->streams.head; m; m = m->next) {
struct packet_stream *sub_ps = m->data;
__unkernelize(sub_ps);

@ -446,8 +446,10 @@ static void mqtt_full_call(struct call *call, JsonBuilder *json) {
json_builder_set_member_name(json, "medias");
json_builder_begin_array(json);
for (GList *k = ml->medias.head; k; k = k->next) {
struct call_media *media = k->data;
for (unsigned int k = 0; k < ml->medias->len; k++) {
struct call_media *media = ml->medias->pdata[k];
if (!media)
continue;
json_builder_begin_object(json);
mqtt_media_stats(media, json);
json_builder_end_object(json);

@ -34,6 +34,14 @@
#include "main.h"
#include "codec.h"
typedef union {
GQueue *q;
GPtrArray *pa;
void *v;
} callback_arg_t;
struct redis *rtpe_redis;
struct redis *rtpe_redis_write;
struct redis *rtpe_redis_write_disabled;
@ -1198,9 +1206,9 @@ static void *redis_list_get_ptr(struct redis_list *list, struct redis_hash *rh,
return redis_list_get_idx_ptr(list, idx);
}
static int json_build_list_cb(GQueue *q, struct call *c, const char *key,
static int json_build_list_cb(callback_arg_t q, struct call *c, const char *key,
unsigned int idx, struct redis_list *list,
int (*cb)(str *, GQueue *, struct redis_list *, void *), void *ptr, JsonReader *root_reader)
int (*cb)(str *, callback_arg_t, struct redis_list *, void *), void *ptr, JsonReader *root_reader)
{
char key_concatted[256];
@ -1233,17 +1241,34 @@ static int json_build_list_cb(GQueue *q, struct call *c, const char *key,
return 0;
}
static int rbl_cb_simple(str *s, GQueue *q, struct redis_list *list, void *ptr) {
static int rbl_cb_simple(str *s, callback_arg_t qp, struct redis_list *list, void *ptr) {
GQueue *q = qp.q;
int j;
j = str_to_i(s, 0);
g_queue_push_tail(q, redis_list_get_idx_ptr(list, (unsigned) j));
return 0;
}
static int rbpa_cb_simple(str *s, callback_arg_t pap, struct redis_list *list, void *ptr) {
GPtrArray *pa = pap.pa;
int j;
j = str_to_i(s, 0);
if (pa->len <= j)
g_ptr_array_set_size(pa, j + 1);
pa->pdata[j] = redis_list_get_idx_ptr(list, (unsigned) j);
return 0;
}
static int json_build_list(GQueue *q, struct call *c, const char *key,
unsigned int idx, struct redis_list *list, JsonReader *root_reader)
{
return json_build_list_cb(q, c, key, idx, list, rbl_cb_simple, NULL, root_reader);
return json_build_list_cb((callback_arg_t) q, c, key, idx, list, rbl_cb_simple, NULL, root_reader);
}
static int json_build_ptra(GPtrArray *q, struct call *c, const char *key,
unsigned int idx, struct redis_list *list, JsonReader *root_reader)
{
return json_build_list_cb((callback_arg_t) q, c, key, idx, list, rbpa_cb_simple, NULL, root_reader);
}
static int json_get_list_hash(struct redis_list *out,
@ -1500,7 +1525,7 @@ static int redis_tags(struct call *c, struct redis_list *tags, JsonReader *root_
return 0;
}
static struct rtp_payload_type *rbl_cb_plts_g(str *s, GQueue *q, struct redis_list *list, void *ptr) {
static struct rtp_payload_type *rbl_cb_plts_g(str *s, struct redis_list *list, void *ptr) {
str ptype;
struct call_media *med = ptr;
@ -1515,9 +1540,9 @@ static struct rtp_payload_type *rbl_cb_plts_g(str *s, GQueue *q, struct redis_li
return pt;
}
static int rbl_cb_plts_r(str *s, GQueue *q, struct redis_list *list, void *ptr) {
static int rbl_cb_plts_r(str *s, callback_arg_t dummy, struct redis_list *list, void *ptr) {
struct call_media *med = ptr;
codec_store_add_raw(&med->codecs, rbl_cb_plts_g(s, q, list, ptr));
codec_store_add_raw(&med->codecs, rbl_cb_plts_g(s, list, ptr));
return 0;
}
static int json_medias(struct call *c, struct redis_list *medias, JsonReader *root_reader) {
@ -1567,7 +1592,7 @@ static int json_medias(struct call *c, struct redis_list *medias, JsonReader *ro
if (redis_hash_get_sdes_params(&med->sdes_out, rh, "sdes_out") < 0)
return -1;
json_build_list_cb(NULL, c, "payload_types", i, NULL, rbl_cb_plts_r, med, root_reader);
json_build_list_cb((callback_arg_t) NULL, c, "payload_types", i, NULL, rbl_cb_plts_r, med, root_reader);
/* XXX dtls */
medias->ptrs[i] = med;
@ -1628,7 +1653,7 @@ static int redis_link_sfds(struct redis_list *sfds, struct redis_list *streams)
return 0;
}
static int rbl_subs_cb(str *s, GQueue *q, struct redis_list *list, void *ptr) {
static int rbl_subs_cb(str *s, callback_arg_t dummy, struct redis_list *list, void *ptr) {
str token;
if (str_token_sep(&token, s, '/'))
@ -1677,7 +1702,7 @@ static int json_link_tags(struct call *c, struct redis_list *tags, struct redis_
for (i = 0; i < tags->len; i++) {
ml = tags->ptrs[i];
if (!json_build_list_cb(NULL, c, "subscriptions", i, tags, rbl_subs_cb, ml, root_reader)) {
if (!json_build_list_cb((callback_arg_t) NULL, c, "subscriptions", i, tags, rbl_subs_cb, ml, root_reader)) {
// new format, ok
;
}
@ -1721,7 +1746,7 @@ static int json_link_tags(struct call *c, struct redis_list *tags, struct redis_
}
g_queue_clear(&q);
if (json_build_list(&ml->medias, c, "medias", i, medias, root_reader))
if (json_build_ptra(ml->medias, c, "medias", i, medias, root_reader))
return -1;
}
@ -1811,11 +1836,8 @@ static int json_link_streams(struct call *c, struct redis_list *streams,
static int json_link_medias(struct call *c, struct redis_list *medias,
struct redis_list *streams, struct redis_list *maps, struct redis_list *tags, JsonReader *root_reader)
{
unsigned int i;
struct call_media *med;
for (i = 0; i < medias->len; i++) {
med = medias->ptrs[i];
for (unsigned int i = 0; i < medias->len; i++) {
struct call_media *med = medias->ptrs[i];
med->monologue = redis_list_get_ptr(tags, &medias->rh[i], "tag");
if (!med->monologue)
@ -1833,8 +1855,10 @@ static int json_link_medias(struct call *c, struct redis_list *medias,
for (GList *sub = ml->subscriptions.head; sub; sub = sub->next) {
struct call_subscription *cs = sub->data;
struct call_monologue *other_ml = cs->monologue;
for (GList *l = other_ml->medias.head; l; l = l->next) {
struct call_media *other_m = l->data;
for (unsigned int j = 0; j < other_ml->medias->len; j++) {
struct call_media *other_m = other_ml->medias->pdata[j];
if (!other_m)
continue;
other_m->monologue = other_ml;
if (other_m->index == med->index) {
codec_handlers_update(med, other_m, NULL, NULL);
@ -1846,7 +1870,8 @@ static int json_link_medias(struct call *c, struct redis_list *medias,
return 0;
}
static int rbl_cb_intf_sfds(str *s, GQueue *q, struct redis_list *list, void *ptr) {
static int rbl_cb_intf_sfds(str *s, callback_arg_t qp, struct redis_list *list, void *ptr) {
GQueue *q = qp.q;
int i;
struct intf_list *il;
struct endpoint_map *em;
@ -1884,7 +1909,7 @@ static int json_link_maps(struct call *c, struct redis_list *maps,
for (i = 0; i < maps->len; i++) {
em = maps->ptrs[i];
if (json_build_list_cb(&em->intf_sfds, c, "map_sfds", em->unique_id, sfds,
if (json_build_list_cb((callback_arg_t) &em->intf_sfds, c, "map_sfds", em->unique_id, sfds,
rbl_cb_intf_sfds, em, root_reader))
return -1;
}
@ -2501,8 +2526,10 @@ char* redis_encode_json(struct call *c) {
snprintf(tmp, sizeof(tmp), "medias-%u", ml->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);
for (k = ml->medias.head; k; k = k->next) {
media = k->data;
for (unsigned int j = 0; j < ml->medias->len; j++) {
media = ml->medias->pdata[j];
if (!media)
continue;
JSON_ADD_STRING("%u", media->unique_id);
}
json_builder_end_array(builder);

@ -3132,28 +3132,26 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
{
struct sdp_session *session;
struct sdp_media *sdp_media;
GList *l, *k, *m, *rtp_ps_link;
int media_index, sess_conn;
GList *l, *k, *rtp_ps_link;
int sess_conn;
struct call_media *call_media;
struct packet_stream *ps;
const char *err = NULL;
m = monologue->medias.head;
media_index = 1;
unsigned int media_index = 0;
struct sdp_manipulations_common *sdp_manipulations = flags->sdp_manipulations;
for (l = sessions->head; l; l = l->next) {
session = l->data;
err = "no matching session media";
if (!m)
goto error;
// look for first usable (non-rejected, non-empty) packet stream
// from any media to determine session-level attributes, if any
ps = NULL;
for (GList *mc = m; mc; mc = mc->next) {
call_media = mc->data;
for (unsigned int ix = media_index; ix < monologue->medias->len; ix++) {
call_media = monologue->medias->pdata[ix];
if (!call_media)
continue;
if (!call_media->streams.head)
continue;
ps = call_media->streams.head->data;
@ -3255,11 +3253,8 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
}
err = "no matching media";
if (!m)
goto error;
call_media = m->data;
err = "media index mismatched";
if (call_media->index != media_index)
call_media = monologue->medias->pdata[media_index];
if (!call_media)
goto error;
err = "no matching media stream";
rtp_ps_link = call_media->streams.head;
@ -3323,7 +3318,6 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
sdp_manipulations_add(chop, sdp_manipulations, sdp_media->media_type_id);
media_index++;
m = m->next;
}
}
@ -3350,11 +3344,11 @@ int sdp_create(str *out, struct call_monologue *monologue, struct sdp_ng_flags *
GString *s = NULL;
err = "Need at least one media";
if (!monologue->medias.length)
if (!monologue->medias->len)
goto err;
// grab first components
struct call_media *media = monologue->medias.head->data;
struct call_media *media = monologue->medias->pdata[0];
err = "No media stream";
if (!media->streams.length)
goto err;
@ -3378,8 +3372,11 @@ int sdp_create(str *out, struct call_monologue *monologue, struct sdp_ng_flags *
g_string_append_printf(s, "s=%s\r\n", rtpe_config.software_id);
g_string_append(s, "t=0 0\r\n");
for (GList *l = monologue->medias.head; l; l = l->next) {
media = l->data;
for (unsigned int i = 0; i < monologue->medias->len; i++) {
media = monologue->medias->pdata[i];
err = "Empty media stream";
if (!media)
continue;
err = "Zero length media stream";
if (!media->streams.length)
goto err;

@ -119,7 +119,7 @@ void statistics_update_foreignown_inc(struct call* c) {
void statistics_update_oneway(struct call* c) {
struct call_monologue *ml;
struct call_media *md;
GList *k, *o;
GList *o;
GList *l;
if (IS_OWN_CALL(c)) {
@ -131,8 +131,10 @@ void statistics_update_oneway(struct call* c) {
ml = l->data;
// --- go through partner ml and search the RTP
for (k = ml->medias.head; k; k = k->next) {
md = k->data;
for (unsigned int i = 0; i < ml->medias->len; i++) {
md = ml->medias->pdata[i];
if (!md)
continue;
for (o = md->streams.head; o; o = o->next) {
ps = o->data;

@ -505,7 +505,7 @@ struct call_monologue {
GHashTable *subscriptions_ht; /* for quick lookup */
GQueue subscribers; /* who is subscribed to me (sinks) */
GHashTable *subscribers_ht; /* for quick lookup */
GQueue medias;
GPtrArray *medias;
GHashTable *media_ids;
struct media_player *player;
unsigned long long sdp_session_id;

Loading…
Cancel
Save