]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Skip some invalid AAC packets, don't decode outdated frames, wait for timing informat...
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Mon, 6 Dec 2021 18:13:20 +0000 (18:13 +0000)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Mon, 6 Dec 2021 18:13:20 +0000 (18:13 +0000)
rtp.c

diff --git a/rtp.c b/rtp.c
index 5b79ff4b970da813385612643eff80cccb7f91ff..d3bf06c4223ea63e1c655faafc68c09190101d57 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -1310,7 +1310,7 @@ int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
         // if the master clock and the anchor clock are the same
         // wait at least this time before using the new master clock
         // note that mastershipo may be backdated
-        if (duration_of_mastership < 1500000000) {
+        if (duration_of_mastership < 100000000) {
           debug(3, "master not old enough yet: %f ms", 0.000001 * duration_of_mastership);
           response = clock_not_ready;
         } else if ((duration_of_mastership > 5000000000) ||
@@ -1400,6 +1400,7 @@ int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
         }
       }
     } else {
+      // debug(1, "anchor_remote_info_is_valid not valid");
       response = clock_no_anchor_info; // no anchor information
     }
   }
@@ -2253,7 +2254,14 @@ void *rtp_buffered_audio_processor(void *arg) {
   int streaming_has_started = 0;
   int play_enabled = 0;
   uint32_t flush_from_timestamp;
-  double requested_lead_time = 0.3; // normal lead time minimum
+  double requested_lead_time = 0.0; // normal lead time minimum -- maybe  it should be about 0.1
+  
+  // wait until our timing information is valid
+  
+  // debug(1,"rtp_buffered_audio_processor ready.");
+  while (have_ptp_timing_information(conn) == 0)
+    usleep(1000);
+  
   reset_buffer(conn);               // in case there is any garbage in the player
   // int not_first_time_out = 0;
 
@@ -2519,28 +2527,42 @@ void *rtp_buffered_audio_processor(void *arg) {
         // to decipher it first
         // debug(1,"seq_no %u, timestamp %u", seq_no, timestamp);
 
+        uint64_t local_should_be_time = 0;
+        int have_time_information = frame_to_local_time(timestamp, &local_should_be_time, conn);
+        int64_t local_lead_time = 0;
+        int64_t requested_lead_time_ns = (int64_t)(requested_lead_time * 1000000000);
+        requested_lead_time_ns = (int64_t)(-300000000);
+        int outdated = 0;        
+        if (have_time_information == 0) {
+          local_lead_time = local_should_be_time - get_absolute_time_in_ns();
+          outdated = (local_lead_time < requested_lead_time_ns);
+          // if (outdated != 0)
+            // debug(1,"Frame is outdated %d if lead_time %" PRId64 " is less than requested lead time %" PRId64 " ns.", outdated, local_lead_time, requested_lead_time_ns);
+        } else {
+          debug(1,"Timing information not valid");
+          // outdated = 1;
+        }
+        
+
         if ((flush_requested) && (seq_no >= flushUntilSeq)) {
-          uint64_t should_be_time;
-          if ((frame_to_local_time(timestamp, &should_be_time, conn) == 0) && (play_enabled)) {
+          if ((have_time_information == 0) && (play_enabled)) {
             // play enabled will be off when this is a full flush and the anchor information is not
             // valid
-            int64_t lead_time = should_be_time - get_absolute_time_in_ns();
-            debug(1,
+            debug(2,
                   "flush completed to seq: %u, flushUntilTS; %u with rtptime: %u, lead time: "
                   "0x%" PRIx64 " nanoseconds, i.e. %f sec.",
-                  seq_no, flushUntilTS, timestamp, lead_time, lead_time * 0.000000001);
+                  seq_no, flushUntilTS, timestamp, local_lead_time, local_lead_time * 0.000000001);
           } else {
             debug(2, "flush completed to seq: %u with rtptime: %u.", seq_no, timestamp);
           }
         }
-
-        if (((flush_requested != 0) && (seq_no == flushUntilSeq)) ||
-            ((flush_requested == 0) && (new_buffer_needed))) {
-
+        
           // if we are here because of a flush request, it must be the case that
           // flushing the pcm buffer wasn't enough, as the request would have been turned off by now
           // so we better indicate that the pcm buffer is empty and its contents invalid
-          if (flush_requested) {
+          
+          // also, if the incomgin frame is outdated, set pcm_buffer_occupancy to 0;
+          if ((flush_requested) || (outdated)){
             pcm_buffer_occupancy = 0;
           }
 
@@ -2556,6 +2578,11 @@ void *rtp_buffered_audio_processor(void *arg) {
             //}
           }
 
+
+        if (((flush_requested != 0) && (seq_no == flushUntilSeq)) ||
+            ((flush_requested == 0) && (new_buffer_needed))) {
+
+
           unsigned char nonce[12];
           memset(nonce, 0, sizeof(nonce));
           memcpy(nonce + 4, packet + nread - 8,
@@ -2596,6 +2623,7 @@ void *rtp_buffered_audio_processor(void *arg) {
             data_remaining = aac_packet_length;
             int ret = 0;
             // there can be more than one av packet (? terminology) in a block
+            int frame_within_block = 0;
             while (data_remaining > 0) {
               if (decoded_frame == NULL) {
                 decoded_frame = av_frame_alloc();
@@ -2608,14 +2636,20 @@ void *rtp_buffered_audio_processor(void *arg) {
                 if (ret < 0) {
                   debug(1, "error while parsing deciphered audio packet.");
                 } else {
+                  frame_within_block++;
                   data_to_process += ret;
                   data_remaining -= ret;
                   // debug(1, "frame found");
                   // now pass each packet to be decoded
                   if (pkt->size) {
+                    //if (0) {
+                    if (pkt->size <= 7) { // no idea about this...
+                      debug(1,"malformed AAC packet skipped.");
+                    } else {
                     ret = avcodec_send_packet(codec_context, pkt);
+                    
                     if (ret < 0) {
-                      debug(1, "error sending  packet to decoder");
+                      debug(1, "error sending frame %d of size %d to decoder, blocks_read: %u, blocks_read_since_flush: %u.", frame_within_block, pkt->size, blocks_read, blocks_read_since_flush);
                     } else {
                       while (ret >= 0) {
                         ret = avcodec_receive_frame(codec_context, decoded_frame);
@@ -2672,6 +2706,7 @@ void *rtp_buffered_audio_processor(void *arg) {
                       }
                     }
                   }
+                  }
                 }
                 if (decoded_frame == NULL)
                   debug(1, "decoded_frame is NULL");