TT#121752 associate SSRC hash to monologue instead of entire call

This solves problems when the same SSRC is looped through the same call
multiple times in different mono/dialogues, with different parameters.

Change-Id: I1d033cb1f012574d82b5bcbfffe11eb5f983cfd8
pull/1295/head
Richard Fuchs 4 years ago
parent 7cb49bcc79
commit 256b9917ec

@ -2715,36 +2715,37 @@ void call_destroy(struct call *c) {
statistics_update_totals(ps);
}
}
}
k = g_hash_table_get_values(c->ssrc_hash->ht);
for (l = k; l; l = l->next) {
struct ssrc_entry_call *se = l->data;
k = g_hash_table_get_values(ml->ssrc_hash->ht);
for (l = k; l; l = l->next) {
struct ssrc_entry_call *se = l->data;
// stats output only - no cleanups
// stats output only - no cleanups
if (!se->stats_blocks.length || !se->lowest_mos || !se->highest_mos)
continue;
int mos_samples = (se->stats_blocks.length - se->no_mos_count);
if (mos_samples < 1) mos_samples = 1;
ilog(LOG_INFO, "--- SSRC %s%" PRIx32 "%s", FMT_M(se->h.ssrc));
ilog(LOG_INFO, "------ Average MOS %" PRIu64 ".%" PRIu64 ", "
"lowest MOS %" PRIu64 ".%" PRIu64 " (at %u:%02u), "
"highest MOS %" PRIu64 ".%" PRIu64 " (at %u:%02u) lost:%d",
se->average_mos.mos / mos_samples / 10,
se->average_mos.mos / mos_samples % 10,
se->lowest_mos->mos / 10,
se->lowest_mos->mos % 10,
(unsigned int) (timeval_diff(&se->lowest_mos->reported, &c->created) / 1000000) / 60,
(unsigned int) (timeval_diff(&se->lowest_mos->reported, &c->created) / 1000000) % 60,
se->highest_mos->mos / 10,
se->highest_mos->mos % 10,
(unsigned int) (timeval_diff(&se->highest_mos->reported, &c->created) / 1000000) / 60,
(unsigned int) (timeval_diff(&se->highest_mos->reported, &c->created) / 1000000) % 60,
se->packets_lost);
}
g_list_free(k);
}
if (!se->stats_blocks.length || !se->lowest_mos || !se->highest_mos)
continue;
int mos_samples = (se->stats_blocks.length - se->no_mos_count);
if (mos_samples < 1) mos_samples = 1;
ilog(LOG_INFO, "--- SSRC %s%" PRIx32 "%s", FMT_M(se->h.ssrc));
ilog(LOG_INFO, "------ Average MOS %" PRIu64 ".%" PRIu64 ", "
"lowest MOS %" PRIu64 ".%" PRIu64 " (at %u:%02u), "
"highest MOS %" PRIu64 ".%" PRIu64 " (at %u:%02u) lost:%d",
se->average_mos.mos / mos_samples / 10,
se->average_mos.mos / mos_samples % 10,
se->lowest_mos->mos / 10,
se->lowest_mos->mos % 10,
(unsigned int) (timeval_diff(&se->lowest_mos->reported, &c->created) / 1000000) / 60,
(unsigned int) (timeval_diff(&se->lowest_mos->reported, &c->created) / 1000000) % 60,
se->highest_mos->mos / 10,
se->highest_mos->mos % 10,
(unsigned int) (timeval_diff(&se->highest_mos->reported, &c->created) / 1000000) / 60,
(unsigned int) (timeval_diff(&se->highest_mos->reported, &c->created) / 1000000) % 60,
se->packets_lost);
}
g_list_free(k);
no_stats_output:
// cleanups
@ -2827,6 +2828,7 @@ static void __call_free(void *p) {
g_hash_table_destroy(m->media_ids);
if (m->last_sdp)
g_string_free(m->last_sdp, TRUE);
free_ssrc_hash(&m->ssrc_hash);
g_slice_free1(sizeof(*m), m);
}
@ -2845,7 +2847,6 @@ static void __call_free(void *p) {
g_hash_table_destroy(c->tags);
g_hash_table_destroy(c->viabranches);
g_hash_table_destroy(c->labels);
free_ssrc_hash(&c->ssrc_hash);
while (c->streams.head) {
ps = g_queue_pop_head(&c->streams);
@ -2879,7 +2880,6 @@ static struct call *call_create(const str *callid) {
c->created = rtpe_now;
c->dtls_cert = dtls_cert();
c->tos = rtpe_config.default_tos;
c->ssrc_hash = create_ssrc_hash_call();
for (int i = 0; i < NUM_CALL_ITERATORS; i++)
mutex_init(&c->iterator[i].lock);
@ -2991,6 +2991,7 @@ struct call_monologue *__monologue_create(struct call *call) {
ret->other_tags = g_hash_table_new(str_hash, str_equal);
ret->branches = g_hash_table_new(str_hash, str_equal);
ret->media_ids = g_hash_table_new(str_hash, str_equal);
ret->ssrc_hash = create_ssrc_hash_call();
g_queue_init(&ret->medias);
gettimeofday(&ret->started, NULL);

@ -57,6 +57,7 @@ static GHashTable *sdp_fragments;
INLINE int call_ng_flags_prefix(struct sdp_ng_flags *out, str *s_ori, const char *prefix,
void (*cb)(struct sdp_ng_flags *, str *, void *), void *ptr);
static void call_ng_flags_str_ht(struct sdp_ng_flags *out, str *s, void *htp);
static void ng_stats_ssrc(bencode_item_t *dict, struct ssrc_hash *ht);
static int call_stream_address_gstring(GString *o, struct packet_stream *ps, enum stream_address_format format) {
@ -1719,6 +1720,7 @@ static void ng_stats_monologue(bencode_item_t *dict, const struct call_monologue
bencode_dictionary_add_integer(sub, "created", ml->created);
if (ml->active_dialogue)
bencode_dictionary_add_str(sub, "in dialogue with", &ml->active_dialogue->tag);
ng_stats_ssrc(bencode_dictionary_add_dictionary(sub, "SSRC"), ml->ssrc_hash);
medias = bencode_dictionary_add_list(sub, "medias");
@ -1821,7 +1823,6 @@ void ng_call_stats(struct call *call, const str *fromtag, const str *totag, benc
bencode_dictionary_add_integer(output, "created", call->created.tv_sec);
bencode_dictionary_add_integer(output, "created_us", call->created.tv_usec);
bencode_dictionary_add_integer(output, "last signal", call->last_signal);
ng_stats_ssrc(bencode_dictionary_add_dictionary(output, "SSRC"), call->ssrc_hash);
tags = bencode_dictionary_add_dictionary(output, "tags");

@ -235,7 +235,11 @@ static const char *dtmf_inject_pcm(struct call_media *media, struct call_monolog
{
struct call *call = monologue->call;
struct ssrc_ctx *ssrc_out = get_ssrc_ctx(ssrc_in->ssrc_map_out, call->ssrc_hash, SSRC_DIR_OUTPUT,
if (!media->monologue || !media->monologue->active_dialogue)
return "No dialogue association";
struct ssrc_ctx *ssrc_out = get_ssrc_ctx(ssrc_in->ssrc_map_out,
media->monologue->active_dialogue->ssrc_hash, SSRC_DIR_OUTPUT,
monologue);
if (!ssrc_out)
return "No output SSRC context present"; // XXX generate stream

@ -111,7 +111,7 @@ struct media_player *media_player_new(struct call_monologue *ml) {
uint32_t ssrc = 0;
while (ssrc == 0)
ssrc = ssl_random();
struct ssrc_ctx *ssrc_ctx = get_ssrc_ctx(ssrc, ml->call->ssrc_hash, SSRC_DIR_OUTPUT, ml);
struct ssrc_ctx *ssrc_ctx = get_ssrc_ctx(ssrc, ml->ssrc_hash, SSRC_DIR_OUTPUT, ml);
ssrc_ctx->next_rtcp = rtpe_now;
struct media_player *mp = obj_alloc0("media_player", sizeof(*mp), __media_player_free);

@ -1453,10 +1453,18 @@ noop:
// check and update SSRC pointers
static void __stream_ssrc(struct packet_stream *in_srtp, struct packet_stream *out_srtp, uint32_t ssrc_bs,
struct ssrc_ctx **ssrc_in_p, struct ssrc_ctx **ssrc_out_p, struct ssrc_hash *ssrc_hash, struct packet_handler_ctx *phc)
struct packet_handler_ctx *phc)
{
uint32_t in_ssrc = ntohl(ssrc_bs);
uint32_t out_ssrc;
struct ssrc_ctx **ssrc_in_p = &phc->mp.ssrc_in;
struct ssrc_ctx **ssrc_out_p = &phc->mp.ssrc_out;
if (!phc->mp.media || !phc->mp.media_out)
return;
struct ssrc_hash *ssrc_hash_in = phc->mp.media->monologue->ssrc_hash;
struct ssrc_hash *ssrc_hash_out = phc->mp.media_out->monologue->ssrc_hash;
// input direction
mutex_lock(&in_srtp->in_lock);
@ -1468,7 +1476,7 @@ static void __stream_ssrc(struct packet_stream *in_srtp, struct packet_stream *o
ssrc_ctx_put(ssrc_in_p);
ssrc_ctx_put(&in_srtp->ssrc_in);
(*ssrc_in_p) = in_srtp->ssrc_in =
get_ssrc_ctx(in_ssrc, ssrc_hash, SSRC_DIR_INPUT, in_srtp->media->monologue);
get_ssrc_ctx(in_ssrc, ssrc_hash_in, SSRC_DIR_INPUT, in_srtp->media->monologue);
ssrc_ctx_hold(in_srtp->ssrc_in);
phc->unkernelize = 1;
@ -1493,7 +1501,7 @@ static void __stream_ssrc(struct packet_stream *in_srtp, struct packet_stream *o
ssrc_ctx_put(ssrc_out_p);
ssrc_ctx_put(&out_srtp->ssrc_out);
(*ssrc_out_p) = out_srtp->ssrc_out =
get_ssrc_ctx(out_ssrc, ssrc_hash, SSRC_DIR_OUTPUT, out_srtp->media->monologue);
get_ssrc_ctx(out_ssrc, ssrc_hash_out, SSRC_DIR_OUTPUT, out_srtp->media->monologue);
ssrc_ctx_hold(out_srtp->ssrc_out);
// coverity[missing_lock : FALSE]
@ -1618,8 +1626,7 @@ static void media_packet_rtp(struct packet_handler_ctx *phc)
rtp_padding(phc->mp.rtp, &phc->mp.payload);
if (G_LIKELY(phc->out_srtp != NULL))
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtp->ssrc, &phc->mp.ssrc_in,
&phc->mp.ssrc_out, phc->mp.call->ssrc_hash, phc);
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtp->ssrc, phc);
// check the payload type
// XXX redundant between SSRC handling and codec_handler stuff -> combine
@ -1647,8 +1654,7 @@ static void media_packet_rtp(struct packet_handler_ctx *phc)
}
else if (phc->rtcp && !rtcp_payload(&phc->mp.rtcp, NULL, &phc->s)) {
if (G_LIKELY(phc->out_srtp != NULL))
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtcp->ssrc, &phc->mp.ssrc_in,
&phc->mp.ssrc_out, phc->mp.call->ssrc_hash, phc);
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtcp->ssrc, phc);
}
}

@ -78,6 +78,7 @@ static int redisCommandNR(redisContext *r, const char *fmt, ...)
static int redis_check_conn(struct redis *r);
static void json_restore_call(struct redis *r, const str *id, int foreign);
static int redis_connect(struct redis *r, int wait);
static int json_build_ssrc(struct call_monologue *ml, JsonReader *root_reader);
static void redis_pipe(struct redis *r, const char *fmt, ...) {
va_list ap;
@ -1392,7 +1393,7 @@ static int redis_streams(struct call *c, struct redis_list *streams) {
return 0;
}
static int redis_tags(struct call *c, struct redis_list *tags) {
static int redis_tags(struct call *c, struct redis_list *tags, JsonReader *root_reader) {
unsigned int i;
int ii;
struct redis_hash *rh;
@ -1420,6 +1421,9 @@ static int redis_tags(struct call *c, struct redis_list *tags) {
if (!redis_hash_get_int(&ii, rh, "block_media"))
ml->block_media = ii ? 1 : 0;
if (json_build_ssrc(ml, root_reader))
return -1;
tags->ptrs[i] = ml;
}
@ -1705,16 +1709,21 @@ static int json_link_maps(struct call *c, struct redis_list *maps,
return 0;
}
static int json_build_ssrc(struct call *c, JsonReader *root_reader) {
if (!json_reader_read_member(root_reader, "ssrc_table"))
return -1;
static int json_build_ssrc(struct call_monologue *ml, JsonReader *root_reader) {
char tmp[2048];
snprintf(tmp, sizeof(tmp), "ssrc_table-%u", ml->unique_id);
if (!json_reader_read_member(root_reader, "ssrc_table")) {
// non-fatal for backwards compatibility
json_reader_end_member(root_reader);
return 0;
}
int nmemb = json_reader_count_elements(root_reader);
for (int jidx=0; jidx < nmemb; ++jidx) {
if (!json_reader_read_element(root_reader, jidx))
return -1;
uint32_t ssrc = json_reader_get_ll(root_reader, "ssrc");
struct ssrc_entry_call *se = get_ssrc(ssrc, c->ssrc_hash);
struct ssrc_entry_call *se = get_ssrc(ssrc, ml->ssrc_hash);
se->input_ctx.srtp_index = json_reader_get_ll(root_reader, "in_srtp_index");
se->input_ctx.srtcp_index = json_reader_get_ll(root_reader, "in_srtcp_index");
payload_tracker_add(&se->input_ctx.tracker, json_reader_get_ll(root_reader, "in_payload_type"));
@ -1826,7 +1835,7 @@ static void json_restore_call(struct redis *r, const str *callid, int foreign) {
if (redis_streams(c, &streams))
goto err8;
err = "failed to create tags";
if (redis_tags(c, &tags))
if (redis_tags(c, &tags, root_reader))
goto err8;
err = "failed to create medias";
if (json_medias(c, &medias, root_reader))
@ -1850,9 +1859,6 @@ static void json_restore_call(struct redis *r, const str *callid, int foreign) {
err = "failed to link maps";
if (json_link_maps(c, &maps, &sfds, root_reader))
goto err8;
err = "failed to restore SSRC table";
if (json_build_ssrc(c, root_reader))
goto err8;
// presence of this key determines whether we were recording at all
if (!redis_hash_get_str(&s, &call, "recording_meta_prefix")) {
@ -2277,6 +2283,33 @@ char* redis_encode_json(struct call *c) {
JSON_ADD_STRING("%u",media->unique_id);
}
json_builder_end_array (builder);
// SSRC table dump
rwlock_lock_r(&ml->ssrc_hash->lock);
k = g_hash_table_get_values(ml->ssrc_hash->ht);
snprintf(tmp, sizeof(tmp), "ssrc_table-%u", ml->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);
for (m = k; m; m = m->next) {
struct ssrc_entry_call *se = m->data;
json_builder_begin_object (builder);
JSON_SET_SIMPLE("ssrc","%" PRIu32, se->h.ssrc);
// XXX use function for in/out
JSON_SET_SIMPLE("in_srtp_index","%" PRIu64, se->input_ctx.srtp_index);
JSON_SET_SIMPLE("in_srtcp_index","%" PRIu64, se->input_ctx.srtcp_index);
JSON_SET_SIMPLE("in_payload_type","%i", se->input_ctx.tracker.most[0]);
JSON_SET_SIMPLE("out_srtp_index","%" PRIu64, se->output_ctx.srtp_index);
JSON_SET_SIMPLE("out_srtcp_index","%" PRIu64, se->output_ctx.srtcp_index);
JSON_SET_SIMPLE("out_payload_type","%i", se->output_ctx.tracker.most[0]);
// XXX add rest of info
json_builder_end_object (builder);
}
json_builder_end_array (builder);
g_list_free(k);
rwlock_unlock_r(&ml->ssrc_hash->lock);
}
@ -2396,31 +2429,6 @@ char* redis_encode_json(struct call *c) {
json_builder_end_array (builder);
}
// SSRC table dump
rwlock_lock_r(&c->ssrc_hash->lock);
k = g_hash_table_get_values(c->ssrc_hash->ht);
json_builder_set_member_name(builder, "ssrc_table");
json_builder_begin_array (builder);
for (m = k; m; m = m->next) {
struct ssrc_entry_call *se = m->data;
json_builder_begin_object (builder);
JSON_SET_SIMPLE("ssrc","%" PRIu32, se->h.ssrc);
// XXX use function for in/out
JSON_SET_SIMPLE("in_srtp_index","%" PRIu64, se->input_ctx.srtp_index);
JSON_SET_SIMPLE("in_srtcp_index","%" PRIu64, se->input_ctx.srtcp_index);
JSON_SET_SIMPLE("in_payload_type","%i", se->input_ctx.tracker.most[0]);
JSON_SET_SIMPLE("out_srtp_index","%" PRIu64, se->output_ctx.srtp_index);
JSON_SET_SIMPLE("out_srtcp_index","%" PRIu64, se->output_ctx.srtcp_index);
JSON_SET_SIMPLE("out_payload_type","%i", se->output_ctx.tracker.most[0]);
// XXX add rest of info
json_builder_end_object (builder);
}
json_builder_end_array (builder);
g_list_free(k);
rwlock_unlock_r(&c->ssrc_hash->lock);
}
json_builder_end_object (builder);

@ -1306,14 +1306,17 @@ static void transcode_rr(struct rtcp_process_ctx *ctx, struct report_block *rr)
return;
if (ctx->scratch.rr.from != ctx->mp->ssrc_in->parent->h.ssrc)
return;
if (!ctx->mp->media || !ctx->mp->media_out)
return;
// reverse SSRC mapping
struct ssrc_ctx *map_ctx = get_ssrc_ctx(ctx->scratch.rr.ssrc, ctx->mp->call->ssrc_hash,
struct ssrc_ctx *map_ctx = get_ssrc_ctx(ctx->scratch.rr.ssrc, ctx->mp->media->monologue->ssrc_hash,
SSRC_DIR_OUTPUT, ctx->mp->media->monologue);
rr->ssrc = htonl(map_ctx->ssrc_map_out);
// for reception stats
struct ssrc_ctx *input_ctx = get_ssrc_ctx(map_ctx->ssrc_map_out, ctx->mp->call->ssrc_hash,
struct ssrc_ctx *input_ctx = get_ssrc_ctx(map_ctx->ssrc_map_out,
ctx->mp->media_out->monologue->ssrc_hash,
SSRC_DIR_INPUT, NULL);
// substitute our own values
@ -1552,8 +1555,6 @@ void rtcp_receiver_reports(GQueue *out, struct ssrc_hash *hash, struct call_mono
// call must be locked in R
void rtcp_send_report(struct call_media *media, struct ssrc_ctx *ssrc_out) {
struct call *call = media->call;
// figure out where to send it
struct packet_stream *ps = media->streams.head->data;
if (MEDIA_ISSET(media, RTCP_MUX))
@ -1578,7 +1579,7 @@ void rtcp_send_report(struct call_media *media, struct ssrc_ctx *ssrc_out) {
log_info_stream_fd(ps->selected_sfd);
GQueue rrs = G_QUEUE_INIT;
rtcp_receiver_reports(&rrs, call->ssrc_hash, ps->media->monologue);
rtcp_receiver_reports(&rrs, media->monologue->ssrc_hash, ps->media->monologue);
ilogs(rtcp, LOG_DEBUG, "Generating and sending RTCP SR for %x and up to %i source(s)",
ssrc_out->parent->h.ssrc, rrs.length);

@ -227,7 +227,6 @@ static void *__do_time_report_item(struct call_media *m, size_t struct_size, siz
const struct timeval *tv, uint32_t ssrc, uint32_t ntp_msw, uint32_t ntp_lsw,
GDestroyNotify free_func, struct ssrc_entry **e_p)
{
struct call *c = m->call;
struct ssrc_entry *e;
struct ssrc_time_item *sti;
@ -236,7 +235,7 @@ static void *__do_time_report_item(struct call_media *m, size_t struct_size, siz
sti->ntp_middle_bits = ntp_msw << 16 | ntp_lsw >> 16;
sti->ntp_ts = ntp_ts_to_double(ntp_msw, ntp_lsw);
e = get_ssrc(ssrc, c->ssrc_hash);
e = get_ssrc(ssrc, m->monologue->ssrc_hash);
if (G_UNLIKELY(!e)) {
free_func(sti);
return NULL;
@ -254,7 +253,7 @@ static void *__do_time_report_item(struct call_media *m, size_t struct_size, siz
return sti;
}
static long long __calc_rtt(struct call *c, uint32_t ssrc, uint32_t ntp_middle_bits,
static long long __calc_rtt(struct call_monologue *ml, uint32_t ssrc, uint32_t ntp_middle_bits,
uint32_t delay, size_t reports_queue_offset, const struct timeval *tv, int *pt_p)
{
if (pt_p)
@ -263,7 +262,7 @@ static long long __calc_rtt(struct call *c, uint32_t ssrc, uint32_t ntp_middle_b
if (!ntp_middle_bits || !delay)
return 0;
struct ssrc_entry_call *e = get_ssrc(ssrc, c->ssrc_hash);
struct ssrc_entry_call *e = get_ssrc(ssrc, ml->ssrc_hash);
if (G_UNLIKELY(!e))
return 0;
@ -329,18 +328,16 @@ void ssrc_sender_report(struct call_media *m, const struct ssrc_sender_report *s
void ssrc_receiver_report(struct call_media *m, const struct ssrc_receiver_report *rr,
const struct timeval *tv)
{
struct call *c = m->call;
ilog(LOG_DEBUG, "RR from %s%x%s about %s%x%s: FL %u TL %u HSR %u J %u LSR %u DLSR %u",
FMT_M(rr->from), FMT_M(rr->ssrc), rr->fraction_lost, rr->packets_lost,
rr->high_seq_received, rr->jitter, rr->lsr, rr->dlsr);
int pt;
long long rtt = __calc_rtt(c, rr->ssrc, rr->lsr, rr->dlsr,
long long rtt = __calc_rtt(m->monologue->active_dialogue, rr->ssrc, rr->lsr, rr->dlsr,
G_STRUCT_OFFSET(struct ssrc_entry_call, sender_reports), tv, &pt);
struct ssrc_entry_call *other_e = get_ssrc(rr->from, c->ssrc_hash);
struct ssrc_entry_call *other_e = get_ssrc(rr->from, m->monologue->ssrc_hash);
if (G_UNLIKELY(!other_e))
goto out_nl;
@ -443,7 +440,7 @@ void ssrc_receiver_dlrr(struct call_media *m, const struct ssrc_xr_dlrr *dlrr,
FMT_M(dlrr->from), FMT_M(dlrr->ssrc),
dlrr->lrr, dlrr->dlrr);
__calc_rtt(m->call, dlrr->ssrc, dlrr->lrr, dlrr->dlrr,
__calc_rtt(m->monologue->active_dialogue, dlrr->ssrc, dlrr->lrr, dlrr->dlrr,
G_STRUCT_OFFSET(struct ssrc_entry_call, rr_time_reports), tv, NULL);
}
@ -460,8 +457,7 @@ void ssrc_voip_metrics(struct call_media *m, const struct ssrc_xr_voip_metrics *
vm->ext_r_factor, vm->mos_lq, vm->mos_cq, vm->rx_config, vm->jb_nom,
vm->jb_max, vm->jb_abs_max);
struct call *c = m->call;
struct ssrc_entry_call *e = get_ssrc(vm->ssrc, c->ssrc_hash);
struct ssrc_entry_call *e = get_ssrc(vm->ssrc, m->monologue->ssrc_hash);
if (!e)
return;
e->last_rtt_xr = vm->rnd_trip_delay;

@ -397,6 +397,7 @@ struct call_monologue {
GString *last_sdp;
char *sdp_username;
char *sdp_session_name;
struct ssrc_hash *ssrc_hash;
unsigned int block_dtmf:1;
unsigned int block_media:1;
@ -452,7 +453,6 @@ struct call {
GQueue stream_fds;
GQueue endpoint_maps;
struct dtls_cert *dtls_cert; /* for outgoing */
struct ssrc_hash *ssrc_hash;
struct mqtt_timer *mqtt_timer;
str callid;

@ -80,20 +80,21 @@ static void __start(const char *file, int line) {
ssrc_A = 1234;
ssrc_B = 2345;
ZERO(call);
call.ssrc_hash = create_ssrc_hash_call();
call.tags = g_hash_table_new(g_str_hash, g_str_equal);
str_init(&call.callid, "test-call");
bencode_buffer_init(&call.buffer);
media_A = call_media_new(&call); // originator
media_B = call_media_new(&call); // output destination
ml_A = (struct call_monologue) {0,};
ml_A = (struct call_monologue) { .ssrc_hash = create_ssrc_hash_call(), 0, };
str_init(&ml_A.tag, "tag_A");
media_A->monologue = &ml_A;
media_A->protocol = &transport_protocols[PROTO_RTP_AVP];
ml_B = (struct call_monologue) {0,};
ml_B = (struct call_monologue) { .ssrc_hash = create_ssrc_hash_call(), 0, };
str_init(&ml_B.tag, "tag_B");
media_B->monologue = &ml_B;
media_B->protocol = &transport_protocols[PROTO_RTP_AVP];
ml_A.active_dialogue = &ml_B;
ml_B.active_dialogue = &ml_A;
__init();
}
@ -229,12 +230,12 @@ static void __packet_seq_ts(const char *file, int line, struct call_media *media
struct media_packet mp = {
.call = &call,
.media = media,
.ssrc_in = get_ssrc_ctx(ssrc, call.ssrc_hash, SSRC_DIR_INPUT, NULL),
.ssrc_in = get_ssrc_ctx(ssrc, media->monologue->ssrc_hash, SSRC_DIR_INPUT, NULL),
};
// from __stream_ssrc()
if (!MEDIA_ISSET(media, TRANSCODE))
mp.ssrc_in->ssrc_map_out = ntohl(ssrc);
mp.ssrc_out = get_ssrc_ctx(mp.ssrc_in->ssrc_map_out, call.ssrc_hash, SSRC_DIR_OUTPUT, NULL);
mp.ssrc_out = get_ssrc_ctx(mp.ssrc_in->ssrc_map_out, media->monologue->active_dialogue->ssrc_hash, SSRC_DIR_OUTPUT, NULL);
payload_tracker_add(&mp.ssrc_in->tracker, pt_in & 0x7f);
int packet_len = sizeof(struct rtp_header) + pl.len;
@ -345,7 +346,6 @@ static void end(void) {
call_media_free(&media_B);
bencode_buffer_free(&call.buffer);
g_hash_table_destroy(call.tags);
free_ssrc_hash(&call.ssrc_hash);
g_queue_clear(&call.medias);
__cleanup();
printf("\n");

Loading…
Cancel
Save