TT#31403 keep track of stats required for RTCP translation/output

Change-Id: Ib7ff1643c90423ffec95b378b4e9fca0000ee4ae
changes/15/18915/5
Richard Fuchs 8 years ago
parent 613f7afdb6
commit 6988b2361e

@ -499,11 +499,12 @@ static int __packet_encoded(encoder_t *enc, void *u1, void *u2) {
ilog(LOG_DEBUG, "Received packet of %i bytes from packetizer", inout.len);
// reconstruct RTP header
unsigned int ts = enc->avpkt.pts + ch->ts_out;
ZERO(*rh);
rh->v_p_x_cc = 0x80;
rh->m_pt = ch->handler->dest_pt.payload_type;
rh->seq_num = htons(ch->seq_out++);
rh->timestamp = htonl(enc->avpkt.pts + ch->ts_out);
rh->timestamp = htonl(ts);
rh->ssrc = htonl(mp->ssrc_in->ssrc_map_out);
// add to output queue
@ -515,6 +516,7 @@ static int __packet_encoded(encoder_t *enc, void *u1, void *u2) {
atomic64_inc(&mp->ssrc_out->packets);
atomic64_add(&mp->ssrc_out->octets, inout.len);
atomic64_set(&mp->ssrc_out->last_ts, ts);
if (ret == 0) {
// no more to go
@ -573,18 +575,19 @@ static int handler_func_transcode(struct codec_handler *h, struct call_media *me
mutex_unlock(&ch->lock);
__transcode_packet_free(packet);
ilog(LOG_DEBUG, "Ignoring duplicate RTP packet");
atomic64_inc(&mp->ssrc_in->duplicates);
return 0;
}
// got a new packet, run decoder
while (1) {
unsigned int lost;
packet = packet_sequencer_next_packet(&ch->sequencer, &lost);
packet = packet_sequencer_next_packet(&ch->sequencer);
if (G_UNLIKELY(!packet))
break;
atomic64_add(&mp->ssrc_in->packets_lost, lost);
atomic64_set(&mp->ssrc_in->packets_lost, ch->sequencer.lost_count);
atomic64_set(&mp->ssrc_in->last_seq, ch->sequencer.ext_seq);
ilog(LOG_DEBUG, "Decoding RTP packet: seq %u, TS %lu",
packet->p.seq, packet->ts);

@ -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
}

@ -44,9 +44,13 @@ struct ssrc_ctx {
// for transcoding
u_int32_t ssrc_map_out;
// RTCP stats
atomic64 packets,
octets,
packets_lost;
packets_lost,
duplicates,
last_seq, // XXX dup with srtp_index?
last_ts;
};
struct ssrc_stats_block {

@ -631,7 +631,7 @@ static int packet_tree_search(const void *testseq_p, const void *ts_p) {
return -1;
}
// caller must take care of locking
void *packet_sequencer_next_packet(packet_sequencer_t *ps, unsigned int *lost) {
void *packet_sequencer_next_packet(packet_sequencer_t *ps) {
// see if we have a packet with the correct seq nr in the queue
seq_packet_t *packet = g_tree_lookup(ps->packets, GINT_TO_POINTER(ps->seq));
if (G_LIKELY(packet != NULL)) {
@ -679,12 +679,17 @@ void *packet_sequencer_next_packet(packet_sequencer_t *ps, unsigned int *lost) {
dbg("lost multiple packets - returning packet with next highest seq %i", packet->seq);
out:
if (lost) {
u_int16_t l = packet->seq - ps->seq;
*lost = l;
}
;
u_int16_t l = packet->seq - ps->seq;
ps->lost_count += l;
g_tree_steal(ps->packets, GINT_TO_POINTER(packet->seq));
ps->seq = (packet->seq + 1) & 0xffff;
if (packet->seq < ps->ext_seq)
ps->roc++;
ps->ext_seq = ps->roc << 16 | packet->seq;
return packet;
}

@ -111,7 +111,10 @@ struct seq_packet_s {
};
struct packet_sequencer_s {
GTree *packets;
int seq;
unsigned int lost_count;
int seq; // next expected
unsigned int ext_seq; // last received
int roc; // rollover counter XXX duplicate with SRTP encryption context
};
@ -142,7 +145,7 @@ int encoder_input_fifo(encoder_t *enc, AVFrame *frame,
void packet_sequencer_init(packet_sequencer_t *ps, GDestroyNotify);
void packet_sequencer_destroy(packet_sequencer_t *ps);
void *packet_sequencer_next_packet(packet_sequencer_t *ps, unsigned int *);
void *packet_sequencer_next_packet(packet_sequencer_t *ps);
int packet_sequencer_insert(packet_sequencer_t *ps, seq_packet_t *);

@ -105,7 +105,7 @@ static void packet_decode(ssrc_t *ssrc, packet_t *packet) {
static void ssrc_run(ssrc_t *ssrc) {
while (1) {
// see if we have a packet with the correct seq nr in the queue
packet_t *packet = packet_sequencer_next_packet(&ssrc->sequencer, NULL);
packet_t *packet = packet_sequencer_next_packet(&ssrc->sequencer);
if (G_UNLIKELY(packet == NULL))
break;

Loading…
Cancel
Save