|
|
|
|
@ -1222,7 +1222,10 @@ static void mos_xr_voip_metrics(struct rtcp_process_ctx *ctx, const struct xr_rb
|
|
|
|
|
|
|
|
|
|
static void transcode_common(struct rtcp_process_ctx *ctx, struct rtcp_packet *common) {
|
|
|
|
|
assert(ctx->scratch_common_ssrc == ctx->mp->ssrc_in->parent->h.ssrc);
|
|
|
|
|
// forward SSRC mapping
|
|
|
|
|
common->ssrc = htonl(ctx->mp->ssrc_in->ssrc_map_out);
|
|
|
|
|
ilog(LOG_DEBUG, "Substituting RTCP header SSRC from %x to %x",
|
|
|
|
|
ctx->scratch_common_ssrc, ctx->mp->ssrc_in->ssrc_map_out);
|
|
|
|
|
}
|
|
|
|
|
static void transcode_rr(struct rtcp_process_ctx *ctx, struct report_block *rr) {
|
|
|
|
|
assert(ctx->scratch.rr.from == ctx->mp->ssrc_in->parent->h.ssrc);
|
|
|
|
|
@ -1231,32 +1234,47 @@ static void transcode_rr(struct rtcp_process_ctx *ctx, struct report_block *rr)
|
|
|
|
|
struct ssrc_ctx *map_ctx = get_ssrc_ctx(ctx->scratch.rr.ssrc, ctx->mp->call->ssrc_hash,
|
|
|
|
|
SSRC_DIR_OUTPUT);
|
|
|
|
|
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,
|
|
|
|
|
SSRC_DIR_INPUT);
|
|
|
|
|
|
|
|
|
|
// substitute our own values
|
|
|
|
|
|
|
|
|
|
unsigned int packets = atomic64_get(&input_ctx->packets);
|
|
|
|
|
unsigned int lost = atomic64_get(&input_ctx->packets_lost);
|
|
|
|
|
unsigned int dupes = atomic64_get(&input_ctx->duplicates);
|
|
|
|
|
unsigned int tot_lost = lost - dupes; // can be negative/rollover
|
|
|
|
|
|
|
|
|
|
ilog(LOG_DEBUG, "Substituting RTCP RR SSRC from %x to %x: %u packets, %u lost, %u duplicates",
|
|
|
|
|
ctx->scratch.rr.ssrc, map_ctx->ssrc_map_out,
|
|
|
|
|
packets, lost, dupes);
|
|
|
|
|
|
|
|
|
|
if (G_UNLIKELY(tot_lost > 0xffffff))
|
|
|
|
|
memset(rr->number_lost, 0xff, sizeof(rr->number_lost));
|
|
|
|
|
else {
|
|
|
|
|
rr->number_lost[0] = (tot_lost & 0xff0000) >> 16;
|
|
|
|
|
rr->number_lost[1] = (tot_lost & 0x00ff00) >> 8;
|
|
|
|
|
rr->number_lost[2] = (tot_lost & 0x0000ff) >> 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int exp_packets = packets + lost;
|
|
|
|
|
|
|
|
|
|
if (dupes > lost || exp_packets == 0) // negative
|
|
|
|
|
rr->fraction_lost = 0;
|
|
|
|
|
else
|
|
|
|
|
rr->fraction_lost = tot_lost * 256 / (packets + lost);
|
|
|
|
|
|
|
|
|
|
// ilog(LOG_DEBUG, "transcode_rr: from ssrc %x about %x "
|
|
|
|
|
// "ssrc_in %x ssrc_in-map %x ssrc_out %x ssrc_out-map %x "
|
|
|
|
|
// "map_ctx %x map_ctx-map %x",
|
|
|
|
|
// ctx->scratch.rr.from,
|
|
|
|
|
// ctx->scratch.rr.ssrc,
|
|
|
|
|
// ctx->mp->ssrc_in->parent->h.ssrc,
|
|
|
|
|
// ctx->mp->ssrc_in->ssrc_map_out,
|
|
|
|
|
// ctx->mp->ssrc_out->parent->h.ssrc,
|
|
|
|
|
// ctx->mp->ssrc_out->ssrc_map_out,
|
|
|
|
|
// map_ctx->parent->h.ssrc,
|
|
|
|
|
// map_ctx->ssrc_map_out);
|
|
|
|
|
|
|
|
|
|
// translate ctx->scratch.rr.from to ctx->mp->ssrc_in->ssrc_map_out - done by transcode_common
|
|
|
|
|
rr->high_seq_received = htonl(atomic64_get(&input_ctx->last_seq));
|
|
|
|
|
// XXX jitter, last SR
|
|
|
|
|
}
|
|
|
|
|
static void transcode_sr(struct rtcp_process_ctx *ctx, struct sender_report_packet *sr) {
|
|
|
|
|
assert(ctx->scratch.sr.ssrc == ctx->mp->ssrc_in->parent->h.ssrc);
|
|
|
|
|
|
|
|
|
|
// ilog(LOG_DEBUG, "transcode_sr: ssrc %x ssrc_in %x ssrc_in-map %x ssrc_out %x ssrc_out-map %x",
|
|
|
|
|
// ctx->scratch.sr.ssrc,
|
|
|
|
|
// ctx->mp->ssrc_in->parent->h.ssrc,
|
|
|
|
|
// ctx->mp->ssrc_in->ssrc_map_out,
|
|
|
|
|
// ctx->mp->ssrc_out->parent->h.ssrc,
|
|
|
|
|
// ctx->mp->ssrc_out->ssrc_map_out);
|
|
|
|
|
//
|
|
|
|
|
// translate ctx->scratch.sr.ssrc to ctx->mp->ssrc_in->ssrc_map_out - done by transcode_common
|
|
|
|
|
// substitute our own values
|
|
|
|
|
sr->octet_count = htonl(atomic64_get(&ctx->mp->ssrc_out->octets));
|
|
|
|
|
sr->packet_count = htonl(atomic64_get(&ctx->mp->ssrc_out->packets));
|
|
|
|
|
sr->timestamp = htonl(atomic64_get(&ctx->mp->ssrc_out->last_ts));
|
|
|
|
|
// XXX NTP timestamp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|