From d5fb35cd83bc99fd731d749b52e9323bc611c368 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Mon, 15 Sep 2014 18:14:01 +0100 Subject: [PATCH] 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. --- player.c | 44 +++++++++++++++++++++++++++++++------------- rtsp.c | 21 ++++++++++++--------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/player.c b/player.c index 8a8bffd6..4d8e8a7d 100644 --- a/player.c +++ b/player.c @@ -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_delaymaximum_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); } diff --git a/rtsp.c b/rtsp.c index 5220d6f2..67968788 100644 --- a/rtsp.c +++ b/rtsp.c @@ -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; }