Still on the trail of that silencing bug -- fixed a silencing bug that could actually have caused it! Flush is a bit cruder, but I can't tell.

This commit is contained in:
Mike Brady
2014-09-15 18:14:01 +01:00
parent f88cc5ad99
commit d5fb35cd83
2 changed files with 43 additions and 22 deletions
+31 -13
View File
@@ -142,14 +142,6 @@ static void ab_resync(void) {
ab_buffering = 1;
}
static inline int ab_buffer_empty(void) {
// this is just for clarity.
if (ab_synced==1)
return 0;
else
return 1;
}
// the sequence number is a 16-bit unsigned number which wraps pretty often
// to work out if one seqno is 'after' another therefore depends whether wrap has occurred
// this function works out the actual ordinate of the seqno, i.e. the distance up from
@@ -293,6 +285,8 @@ 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
if (ORDINATE(seqno)>(BUFFER_FRAMES*7)/8)
debug(1,"An interval of %u frames has opened, with ab_read: %u, ab_write: %u and seqno: %u.",seq_diff(ab_read,seqno),ab_read,ab_write,seqno);
int32_t gap = seq_diff(ab_write,PREDECESSOR(seqno))+1;
if (gap<=0)
debug(1,"Unexpected gap size: %d.",gap);
@@ -313,10 +307,12 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) {
abuf = audio_buffer + BUFIDX(seqno);
} else { // too late.
too_late_packets++;
/*
if (!late_packet_message_sent) {
debug(1, "too-late packet received: %u; ab_read: %u; ab_write: %u.", seqno, ab_read, ab_write);
late_packet_message_sent=1;
}
*/
}
// pthread_mutex_unlock(&ab_mutex);
@@ -395,7 +391,7 @@ static abuf_t *buffer_get_frame(void) {
}
pthread_mutex_unlock(&flush_mutex);
if (!ab_buffer_empty()) {
if (ab_synced) {
dac_delay = 0;
curframe = audio_buffer + BUFIDX(ab_read);
@@ -408,11 +404,17 @@ static abuf_t *buffer_get_frame(void) {
}
if (curframe->ready) {
/*
// This is broken -- it causes infinite loops. It's in the wrong place, and anyway isn't used much.
if ((flush_rtp_timestamp) && (flush_rtp_timestamp>=curframe->timestamp)) {
// debug(1,"Dropping flushed packet %d",curframe->sequence_number);
debug(1,"Dropping flushed packet seqno %u, timestamp %u",curframe->sequence_number,curframe->timestamp);
curframe->ready=0;
if (flush_rtp_timestamp==curframe->timestamp) // if we are finished...
flush_rtp_timestamp=0;
ab_read==SUCCESSOR(ab_read);
} else if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
} 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));
uint32_t reference_timestamp;
@@ -527,6 +529,7 @@ static abuf_t *buffer_get_frame(void) {
// check if t+8, t+16, t+32, t+64, t+128, ... (buffer_start_fill / 2)
// packets have arrived... last-chance resend
if (!ab_buffering) {
for (i = 8; i < (seq_diff(ab_read,ab_write) / 2); i = (i * 2)) {
seq_t next = seq_sum(ab_read,i);
@@ -538,6 +541,7 @@ static abuf_t *buffer_get_frame(void) {
}
}
}
if (!curframe->ready) {
// debug(1, " %d. Supplying a silent frame.", read);
missing_packets++;
@@ -689,6 +693,8 @@ static void *player_thread_func(void *arg) {
int64_t tsum_of_sync_errors,tsum_of_corrections,tsum_of_insertions_and_deletions,tsum_of_drifts;
int64_t previous_sync_error,previous_correction;
int64_t minimum_dac_queue_size = 1000000;
int32_t minimum_buffer_occupancy = BUFFER_FRAMES;
int32_t maximum_buffer_occupancy = 0;
int play_samples;
int64_t current_delay;
@@ -763,6 +769,14 @@ static void *player_thread_func(void *arg) {
}
if (current_delay<minimum_dac_queue_size)
minimum_dac_queue_size=current_delay;
uint32_t bo = seq_diff(ab_read,ab_write);
if (bo<minimum_buffer_occupancy)
minimum_buffer_occupancy=bo;
if (bo>maximum_buffer_occupancy)
maximum_buffer_occupancy=bo;
// this is the actual delay, including the latency we actually want, which will fluctuate a good bit about a potentially rising or falling trend.
int64_t delay = td_in_frames+rt-(nt-current_delay);
@@ -900,8 +914,10 @@ static void *player_thread_func(void *arg) {
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);
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, min and max buffer occupancy %u and %u.", 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_buffer_occupancy,maximum_buffer_occupancy);
minimum_dac_queue_size=1000000; // hack reset
maximum_buffer_occupancy = 0; // can't be less than this
minimum_buffer_occupancy = BUFFER_FRAMES; // can't be more than this
}
}
}
@@ -936,9 +952,11 @@ void player_volume(double f) {
}
void player_flush(uint32_t timestamp) {
// debug(1,"Flush requested up to %u. It seems as if 2147483647 is special.",timestamp);
pthread_mutex_lock(&flush_mutex);
flush_requested=1;
flush_rtp_timestamp=timestamp; // flush all packets up to (and including?) this
if (timestamp!=0x7fffffff)
flush_rtp_timestamp=timestamp; // flush all packets up to (and including?) this
pthread_mutex_unlock(&flush_mutex);
}
+12 -9
View File
@@ -413,18 +413,21 @@ static void handle_flush(rtsp_conn_info *conn,
rtsp_message *req, rtsp_message *resp) {
if (!rtsp_playing())
return;
char * hdr = msg_get_header(req,"RTP-Info");
// debug(1,"FLUSH message received: \"%s\".",hdr);
// get the rtp timestamp
char *p;
uint32_t rtptime=0;
p = strstr(hdr, "rtptime=");
if (p) {
p = strchr(p, '=') + 1;
if (p)
rtptime = atoi(p);
char * hdr = msg_get_header(req,"RTP-Info");
if (hdr) {
// debug(1,"FLUSH message received: \"%s\".",hdr);
// get the rtp timestamp
p = strstr(hdr, "rtptime=");
if (p) {
p = strchr(p, '=') + 1;
if (p)
rtptime = atoi(p);
}
}
// debug(1,"RTSP Flush Requested.");
player_flush(rtptime);
resp->respcode = 200;
}