Add seq_t PREDECSSOR and seq_sum functions, use them in place of add and subtract. Make play loop record plays and stats even when given silent frames.

This commit is contained in:
Mike Brady
2014-09-08 13:28:26 +01:00
parent 0b90bb646c
commit 0462ead319
+36 -25
View File
@@ -162,6 +162,13 @@ static inline seq_t SUCCESSOR(seq_t x) {
return p;
}
static inline seq_t PREDECESSOR(seq_t x) {
uint32_t p = (x & 0xffff)+0x10000;
p-=1;
p = p & 0xffff;
return p;
}
static inline uint32_t ORDINATE(seq_t x) {
uint32_t p = x & 0xffff;
uint32_t q = ab_read & 0x0ffff;
@@ -182,6 +189,13 @@ static inline int seq_order(seq_t a, seq_t b) {
return d > 0;
}
static inline seq_t seq_sum(seq_t a, seq_t b) {
uint32_t p = a & 0xffff;
uint32_t q = b & 0x0ffff;
uint32_t r = (a+b) & 0xffff;
return r;
}
static void alac_decode(short *dest, uint8_t *buf, int len) {
unsigned char packet[MAX_PACKET];
unsigned char packetp[MAX_PACKET];
@@ -276,7 +290,7 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) {
abuf = audio_buffer + BUFIDX(seqno);
ab_write = SUCCESSOR(seqno);
} else if (seq_order(ab_write, seqno)) { // newer than expected
rtp_request_resend(ab_write+1, seqno-1);
rtp_request_resend(SUCCESSOR(ab_write), PREDECESSOR(seqno));
resend_requests++;
abuf = audio_buffer + BUFIDX(seqno);
ab_write = SUCCESSOR(seqno);
@@ -335,7 +349,6 @@ static abuf_t *buffer_get_frame(void) {
int16_t buf_fill;
uint64_t local_time_now;
// struct timespec tn;
seq_t read, next;
abuf_t *abuf = 0;
int i;
abuf_t *curframe;
@@ -384,7 +397,7 @@ static abuf_t *buffer_get_frame(void) {
if ((flush_rtp_timestamp) && (flush_rtp_timestamp>=curframe->timestamp)) {
// debug(1,"Dropping flushed packet %d",curframe->sequence_number);
curframe->ready=0;
ab_read++;
ab_read==SUCCESSOR(ab_read);
} else if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
if (first_packet_timestamp==0) { // if this is the very first packet
// debug(1,"First frame seen, time %u, with %d frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
@@ -495,15 +508,15 @@ static abuf_t *buffer_get_frame(void) {
return 0;
}
read = ab_read;
ab_read++;
seq_t read = ab_read;
ab_read=SUCCESSOR(ab_read);
// check if t+16, t+32, t+64, t+128, ... (buffer_start_fill / 2)
// packets have arrived... last-chance resend
if (!ab_buffering) {
for (i = 16; i < (seq_diff(ab_read,ab_write) / 2); i = (i * 2)) {
next = ab_read + i;
seq_t next = seq_sum(ab_read,i);
abuf = audio_buffer + BUFIDX(next);
if (!abuf->ready) {
rtp_request_resend(next, next);
@@ -691,6 +704,7 @@ static void *player_thread_func(void *arg) {
if (inframe) {
inbuf = inframe->data;
if (inbuf) {
play_number++;
// if it's a supplied silent frame, let us know...
if (inframe->timestamp==0) {
// debug(1,"Player has a supplied silent frame.");
@@ -815,8 +829,6 @@ static void *player_thread_func(void *arg) {
sync_error_out_of_bounds = 0;
}
play_number++;
// debug(1,"Sync error %lld frames. Amount to stuff %d." ,sync_error,amount_to_stuff);
// new stats calculation. We want a running average of sync error, drift, adjustment, number of additions+subtractions
@@ -858,25 +870,24 @@ static void *player_thread_func(void *arg) {
// check sequencing
if (last_seqno_read==-1)
last_seqno_read=inframe->sequence_number;
else {
last_seqno_read = (last_seqno_read+1)&0xffff;
if (inframe->sequence_number!=last_seqno_read)
debug(1,"Player: packets out of sequence: expected: %d, got %d.",last_seqno_read,inframe->sequence_number);
last_seqno_read=inframe->sequence_number; // reset warning...
}
if (play_number%print_interval==0) {
// we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm)
double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics;
double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics;
double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics;
double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics;
// if ((play_number/print_interval)%20==0)
debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size);
minimum_dac_queue_size=1000000; // hack reset
last_seqno_read=inframe->sequence_number;
else {
last_seqno_read = (last_seqno_read+1)&0xffff;
if (inframe->sequence_number!=last_seqno_read)
debug(1,"Player: packets out of sequence: expected: %d, got %d.",last_seqno_read,inframe->sequence_number);
last_seqno_read=inframe->sequence_number; // reset warning...
}
}
if (play_number%print_interval==0) {
// we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm)
double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics;
double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics;
double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics;
double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics;
// if ((play_number/print_interval)%20==0)
debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size);
minimum_dac_queue_size=1000000; // hack reset
}
}
}
}