TT#14008 add packet loss tracking for userspace passthrough

Change-Id: Id2ea329333a4236389e2a2b567fba76ffc7cea5f
pull/1388/head
Richard Fuchs 4 years ago
parent 785ed90bba
commit 834eb034af

@ -40,6 +40,7 @@ static struct timerthread codec_timers_thread;
static void rtp_payload_type_copy(struct rtp_payload_type *dst, const struct rtp_payload_type *src);
static void codec_store_add_raw_order(struct codec_store *cs, struct rtp_payload_type *pt);
static void __rtp_payload_type_add_name(GHashTable *, struct rtp_payload_type *pt);
static void codec_calc_lost(struct ssrc_ctx *ssrc, uint16_t seq);
static struct codec_handler codec_handler_stub = {
@ -1329,8 +1330,10 @@ static int handler_func_passthrough(struct codec_handler *h, struct media_packet
if (!handler_silence_block(h, mp))
return 0;
if (mp->rtp)
if (mp->rtp) {
codec_calc_jitter(mp->ssrc_in, ntohl(mp->rtp->timestamp), h->source_pt.clock_rate, &mp->tv);
codec_calc_lost(mp->ssrc_in, ntohs(mp->rtp->seq_num));
}
codec_add_raw_packet(mp, h->source_pt.clock_rate);
return 0;
}
@ -1949,8 +1952,10 @@ static int handler_func_passthrough_ssrc(struct codec_handler *h, struct media_p
if (!handler_silence_block(h, mp))
return 0;
if (mp->rtp)
if (mp->rtp) {
codec_calc_jitter(mp->ssrc_in, ntohl(mp->rtp->timestamp), h->source_pt.clock_rate, &mp->tv);
codec_calc_lost(mp->ssrc_in, ntohs(mp->rtp->seq_num));
}
// substitute out SSRC etc
mp->rtp->ssrc = htonl(mp->ssrc_in->ssrc_map_out);
@ -2830,6 +2835,60 @@ void codec_calc_jitter(struct ssrc_ctx *ssrc, unsigned long ts, unsigned int clo
sec->jitter += d - ((sec->jitter + 8) >> 4);
mutex_unlock(&sec->h.lock);
}
static void codec_calc_lost(struct ssrc_ctx *ssrc, uint16_t seq) {
struct ssrc_entry_call *s = ssrc->parent;
LOCK(&s->h.lock);
// XXX shared code from kernel module
uint32_t last_seq = s->last_seq_tracked;
uint32_t new_seq = last_seq;
// old seq or seq reset?
uint16_t old_seq_trunc = last_seq & 0xffff;
uint16_t seq_diff = seq - old_seq_trunc;
if (seq_diff == 0 || seq_diff >= 0xfeff) // old/dup seq - ignore
;
else if (seq_diff > 0x100) {
// reset seq and loss tracker
new_seq = seq;
s->last_seq_tracked = seq;
s->lost_bits = -1;
}
else {
// seq wrap?
new_seq = (last_seq & 0xffff0000) | seq;
while (new_seq < last_seq) {
new_seq += 0x10000;
if ((new_seq & 0xffff0000) == 0) // ext seq wrapped
break;
}
seq_diff = new_seq - last_seq;
s->last_seq_tracked = new_seq;
// shift loss tracker bit field and count losses
if (seq_diff >= (sizeof(s->lost_bits) * 8)) {
// complete loss
s->packets_lost += sizeof(s->lost_bits) * 8;
s->lost_bits = -1;
}
else {
while (seq_diff) {
// shift out one bit and see if we lost it
if ((s->lost_bits & 0x80000000) == 0)
s->packets_lost++;
s->lost_bits <<= 1;
seq_diff--;
}
}
}
// track this frame as being seen
seq_diff = (new_seq & 0xffff) - seq;
if (seq_diff < (sizeof(s->lost_bits) * 8))
s->lost_bits |= (1 << seq_diff);
}
#ifdef WITH_TRANSCODING

@ -29,6 +29,7 @@ static struct ssrc_entry *create_ssrc_entry_call(void *uptr) {
init_ssrc_ctx(&ent->output_ctx, ent);
//ent->seq_out = ssl_random();
//ent->ts_out = ssl_random();
ent->lost_bits = -1;
return &ent->h;
}
static void add_ssrc_entry(uint32_t ssrc, struct ssrc_entry *ent, struct ssrc_hash *ht) {

@ -110,7 +110,9 @@ struct ssrc_entry_call {
unsigned int last_rtt; // last calculated raw rtt without rtt from opposide side
unsigned int last_rtt_xr; // last rtt for both legs retreived from RTCP-XR BT-7
// input only
// input only - tracking for passthrough handling
uint32_t last_seq_tracked;
uint32_t lost_bits; // sliding bitfield, [0] = ext_seq
uint32_t packets_lost; // RTCP cumulative number of packets lost
uint32_t duplicates;

Loading…
Cancel
Save