]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Does pretty well with flushing. Sometimes misses a flush on a repeat one.
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Fri, 28 May 2021 21:20:11 +0000 (22:20 +0100)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Fri, 28 May 2021 21:20:11 +0000 (22:20 +0100)
player.c
rtp.c
rtsp.c

index efa40c6331e295c805aa1819fcdcb3b32dc091ec..a1bd0f4013a0ab07aa3d8dacfb3ee80e84c45f16 100644 (file)
--- a/player.c
+++ b/player.c
@@ -924,11 +924,12 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
       // if the first_packet_timestamp is zero, don't check
       int flush_needed = 0;
       int drop_request = 0;
-      if ((conn->flush_requested == 1) && (conn->flush_rtp_timestamp == 0)) {
+      if (conn->flush_requested == 1) {
+      if (conn->flush_rtp_timestamp == 0) {
         debug(1, "flush request: flush frame 0 -- flush assumed to be needed.");
         flush_needed = 1;
         drop_request = 1;
-      } else if (conn->flush_rtp_timestamp != 0) {
+      } else {
         if ((conn->ab_synced) && ((conn->ab_write - conn->ab_read) > 0)) {
           abuf_t *firstPacket = conn->audio_buffer + BUFIDX(conn->ab_read);
           abuf_t *lastPacket = conn->audio_buffer + BUFIDX(conn->ab_write - 1);
@@ -992,9 +993,11 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
               "flush request: flush frame %u  -- buffer not synced or empty: synced: %d, ab_read: "
               "%u, ab_write: %u",
               conn->flush_rtp_timestamp, conn->ab_synced, conn->ab_read, conn->ab_write);
+          conn->flush_requested = 0; // remove the request
           // leave flush request pending and don't do a buffer flush, because there isn't one
         }
       }
+    }
       if (flush_needed) {
         debug(2, "flush request: flush done.");
         ab_resync(conn); // no cancellation points
@@ -1974,7 +1977,7 @@ void *player_thread_func(void *arg) {
 #endif
 
   pthread_setcancelstate(oldState, NULL);
-  
+
   double initial_volume = config.airplay_volume; // default
   if (conn->initial_airplay_volume_set) // if we have been given an initial volume
     initial_volume = conn->initial_airplay_volume;
@@ -3046,8 +3049,8 @@ void player_full_flush(rtsp_conn_info *conn) {
       abuf = conn->audio_buffer + BUFIDX(last_seqno_written);
     } while ((abuf->ready == 0) && (last_seqno_written != conn->ab_read));
     if ((abuf != NULL) && (abuf->ready != 0)) {
-      debug(2, "full flush needed");
       rtpTimestamp = abuf->given_timestamp + abuf->length + 1;
+      debug(2, "full flush needed to %u", rtpTimestamp);
       flush_needed = 1;
     } else {
       debug(2, "full flush not needed");
diff --git a/rtp.c b/rtp.c
index 3e1be921a93e5070bd39a6342ca41ea7991d4ee1..465f25b5eccc7e798f600bd710a17626332082c1 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -1213,7 +1213,7 @@ void set_ptp_anchor_info(rtsp_conn_info *conn, uint64_t clock_id, uint32_t rtpti
     debug(2, "Connection %d: Set Anchor Clock: %" PRIx64 ".", conn->connection_number, clock_id);
     conn->anchor_clock_is_new = 1;
   }
-  debug(1,"set anchor info clock: %" PRIx64", rtptime: %u, networktime: %" PRIx64 ".", clock_id, rtptime, networktime);
+  // debug(1,"set anchor info clock: %" PRIx64", rtptime: %u, networktime: %" PRIx64 ".", clock_id, rtptime, networktime);
   conn->anchor_remote_info_is_valid = 1;
   conn->anchor_rtptime = rtptime;
   conn->anchor_time = networktime;
@@ -2033,12 +2033,9 @@ void *rtp_buffered_audio_processor(void *arg) {
   uint8_t *pcm_audio = NULL;  // the S16 output
   unsigned char *data_to_process;
   ssize_t data_remaining;
-  uint32_t seq_no, last_block_flushed_seq_no; // audio packet number
-  uint32_t previous_seq_no = 0;
+  uint32_t seq_no; // audio packet number
+  // uint32_t previous_seq_no = 0;
   int new_buffer_needed;
-
-  uint32_t last_block_flushed_rtp_time;
-
   ssize_t nread;
 
   int finished = 0;
@@ -2058,7 +2055,7 @@ void *rtp_buffered_audio_processor(void *arg) {
     // are we in in flush mode, or just about to leave it?
     debug_mutex_lock(&conn->flush_mutex, 10000, 1); // 10ms is a long time to wait!
     uint32_t flushUntilSeq = conn->ap2_flush_until_sequence_number;
-    uint32_t flushUntilTS = conn->ap2_flush_until_rtp_timestamp;
+    // uint32_t flushUntilTS = conn->ap2_flush_until_rtp_timestamp;
 
     int flush_request_active = 0;
     if (conn->ap2_flush_requested) {
@@ -2076,6 +2073,7 @@ void *rtp_buffered_audio_processor(void *arg) {
     if (flush_request_active) {
       if (flush_requested == 0) {
         // here, a flush has been newly requested
+        /*
         debug(1,"Flush requested:");
         if (conn->ap2_flush_from_valid) {
           debug(1,"  fromTS:          %u", conn->ap2_flush_from_rtp_timestamp);
@@ -2091,44 +2089,17 @@ void *rtp_buffered_audio_processor(void *arg) {
           uint32_t endTS = fib + pcm_buffer_read_point_rtptime;
           debug(1,"  currentTS_End:   %u", endTS); // a frame occupies 4 bytes
           debug(1,"  currentSeq:      %u", seq_no);
-
-        last_block_flushed_rtp_time = pcm_buffer_read_point_rtptime;
-        last_block_flushed_seq_no = seq_no;
-        flush_newly_requested = 1;
+        */
+      flush_newly_requested = 1;
       }
-      // if we have arrived at the nominated flush block
-      // (it must be the case that the block is in the pcm buffer)
-      if ((blocks_read != 0) && (seq_no == flushUntilSeq)) {
-        // we may need to flush the pcm_buffer up to flushUntilTS
-        int32_t flush_difference = flushUntilTS - pcm_buffer_read_point_rtptime;
-        if (flush_difference < 0) {
-          debug(1, "flushUntilTS is before the flushUntilSeq's start TS");
-        } else if (flush_difference > pcm_buffer_occupancy) {
-          debug(1,
-                "flushUntilTS is after the flushUntilSeq's last TS. flushUntilTS = %u, "
-                "pcm_buffer_read_point_rtptime = %u, pcm_buffer_occupancy = %u.",
-                flushUntilTS, pcm_buffer_read_point_rtptime, pcm_buffer_occupancy);
-        } else {
-          // move the buffer contents from flush_difference to pcm_buffer_occupancy
-          // to the front of the pcm_buffer
-          memcpy(pcm_buffer, pcm_buffer + flush_difference * 4,
-                 pcm_buffer_occupancy - flush_difference * 4);
-          pcm_buffer_occupancy = pcm_buffer_occupancy - flush_difference * 4;
-          pcm_buffer_read_point = 0;
-          debug(1, "set pcm_buffer_read_point_rtptime from %u to %u.",
-                pcm_buffer_read_point_rtptime, flushUntilTS);
-          pcm_buffer_read_point_rtptime = flushUntilTS;
-        }
+      // blocks_read to ensure seq_no is valid
+      if ((blocks_read != 0) && (seq_no >= flushUntilSeq)) {
+        // we have reached or overshot the flushUntilSeq block
+        if (flushUntilSeq != seq_no)
+          debug(1,"flushUntilSeq %u reached or overshot at %u.", flushUntilSeq, seq_no);
         conn->ap2_flush_requested = 0;
         flush_request_active = 0;
-      } else {
-        if (seq_no > flushUntilSeq) {
-          debug(1,
-                "we have overshot the flush ending block. flushUntilSeq is %u, this block is: %u.",
-                flushUntilSeq, seq_no);
-          conn->ap2_flush_requested = 0; // but conn->ap2_play_enabled will remain at zero
-          flush_request_active = 0;
-        }
+        flush_newly_requested = 0;
       }
     }
     flush_requested = flush_request_active;
@@ -2138,7 +2109,6 @@ void *rtp_buffered_audio_processor(void *arg) {
 
     // do this outside the flush mutex
     if (flush_newly_requested) {
-      player_full_flush(conn);
       streaming_has_started = 0;
       pcm_buffer_occupancy = 0;
       pcm_buffer_read_point = 0;
@@ -2151,7 +2121,7 @@ void *rtp_buffered_audio_processor(void *arg) {
       get_audio_buffer_size_and_occupancy(&player_buffer_size, &player_buffer_occupancy, conn);
       // debug(1,"player buffer size and occupancy: %u and %u", player_buffer_size,
       // player_buffer_occupancy);
-      double reqested_lead_time = 0.050; //
+      double reqested_lead_time = 0.10; //
       if (player_buffer_occupancy >
           ((reqested_lead_time + 0.1) * 44100.0 / 352)) { // must be greater than the lead time.
         // if there is enough stuff in the player's buffer, sleep for a while and try again
@@ -2179,11 +2149,8 @@ void *rtp_buffered_audio_processor(void *arg) {
               if ((lead_time >= (int64_t)(reqested_lead_time * 1000000000)) ||
                   (streaming_has_started == 1)) {
                 if (streaming_has_started == 0)
-                  debug(1, "Connection %d: buffered audio starting lead time is %f seconds.", conn->connection_number,
+                  debug(3, "Connection %d: buffered audio starting frame: %u, lead time: %f seconds.", conn->connection_number, pcm_buffer_read_point_rtptime,
                         0.000000001 * lead_time);
-                //else
-                //  debug(1, "Connection %d: buffered audio lead time is %f seconds.", conn->connection_number,
-                //        0.000000001 * lead_time);
 
                 streaming_has_started = 1;
                 player_put_packet(0, 0, pcm_buffer_read_point_rtptime,
@@ -2263,7 +2230,9 @@ void *rtp_buffered_audio_processor(void *arg) {
         // uint8_t marker = 0;
         // uint8_t payload_type = 0;
 
+/*
         if ((blocks_read != 0) && (seq_no != previous_seq_no + 1)) {
+
           if (previous_seq_no != 0)
             debug(1, "block discontinuity: from sequence number %u to sequence number %u.",
                   previous_seq_no, seq_no);
@@ -2274,41 +2243,24 @@ void *rtp_buffered_audio_processor(void *arg) {
                   pcm_buffer_read_point_rtptime, previous_seq_no, timestamp, seq_no);
             pcm_buffer_occupancy = 0;
           }
+
           // if still playing, this is a problem -- need to reset the player
           if (play_enabled)
             player_full_flush(conn);
         }
+*/
 
-        previous_seq_no = seq_no;
+        // previous_seq_no = seq_no;
 
         // at this point, we can check if we can to flush this packet -- we won't have
         // to decipher it first
         // debug(1,"seq_no %u, timestamp %u", seq_no, timestamp);
 
-        if ((flush_requested) && (seq_no < flushUntilSeq)) {
-          last_block_flushed_seq_no = seq_no;
-          last_block_flushed_rtp_time = timestamp;
-          debug(1, "flush block %u, rtptime %u", seq_no, timestamp);
-        }
-
         if (((flush_requested) && (seq_no == flushUntilSeq)) || (new_buffer_needed)) {
 
           if ((flush_requested) && (seq_no == flushUntilSeq)) {
-         if (conn->ap2_flush_from_valid != 0)
-            debug(1, "also flush block %u, rtptime %u", seq_no, timestamp);
-            int32_t timestamp_difference = timestamp - flushUntilTS;
-            debug(1,
-                  "end of flush reached. flushUntilSeq = %u, flushUntilTS = %u, last block flushed "
-                  "seq_no = %u, last block flushed rtptime = %u, next block seq_no = %u, next "
-                  "block timestamp = "
-                  "%u, timestamp difference: %d, buffer_size: %u.",
-                  flushUntilSeq, flushUntilTS, last_block_flushed_seq_no,
-                  last_block_flushed_rtp_time, seq_no, timestamp, timestamp_difference,
-                  buffered_audio->buffer_occupancy);
-            debug(2,
-                  "pcm_buffer_read_point_rtptime = %u, pcm_buffer_occupancy = %u, "
-                  "pcm_buffer_read_point = %u",
-                  pcm_buffer_read_point_rtptime, pcm_buffer_occupancy, pcm_buffer_read_point);
+              player_full_flush(conn);
+              debug(1,"Flush completed.");
           }
 
           // if we are here because of a flush request, it must be the case that
@@ -2322,12 +2274,12 @@ void *rtp_buffered_audio_processor(void *arg) {
 
           if (pcm_buffer_occupancy == 0) {
             // they should match and the read point should be zero
-            if ((blocks_read != 0) && (pcm_buffer_read_point_rtptime != timestamp)) {
-              debug(2, "set pcm_buffer_read_point_rtptime from %u to %u.",
-                    pcm_buffer_read_point_rtptime, timestamp);
+           // if ((blocks_read != 0) && (pcm_buffer_read_point_rtptime != timestamp)) {
+            //  debug(2, "set pcm_buffer_read_point_rtptime from %u to %u.",
+            //        pcm_buffer_read_point_rtptime, timestamp);
               pcm_buffer_read_point_rtptime = timestamp;
               pcm_buffer_read_point = 0;
-            }
+            //}
           }
 
           unsigned char nonce[12];
diff --git a/rtsp.c b/rtsp.c
index 24d8ea14b7e49d2dc61e57643e93dc8ef246ac9d..b9b38c25ab84c695e58eb02a423ba8d53362137a 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -1298,7 +1298,7 @@ void handle_get_info(__attribute((unused)) rtsp_conn_info *conn, rtsp_message *r
 void handle_flushbuffered(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
   debug(3, "Connection %d: FLUSHBUFFERED %s :: Content-Length %d", conn->connection_number,
         req->path, req->contentlength);
-  debug_log_rtsp_message(1, "FLUSHBUFFERED request", req);
+  debug_log_rtsp_message(2, "FLUSHBUFFERED request", req);
 
   uint64_t flushFromSeq = 0;
   uint64_t flushFromTS = 0;
@@ -1317,7 +1317,7 @@ void handle_flushbuffered(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
 
   item = plist_dict_get_item(messagePlist, "flushFromTS");
   if (item == NULL) {
-    if (conn->ap2_flush_from_valid != 0)
+    if (flushFromValid != 0)
       debug(1, "flushFromSeq without flushFromTS!");
     else
       debug(2, "Can't find a flushFromTS");