]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Seems to work for higher rates
authorMike Brady <mikebrady@eircom.net>
Fri, 19 Oct 2018 21:14:23 +0000 (22:14 +0100)
committerMike Brady <mikebrady@eircom.net>
Fri, 19 Oct 2018 21:14:23 +0000 (22:14 +0100)
player.c
player.h
rtp.c
rtp.h

index a96fc845966b52ae654b27ddcc64f7c7d89278fe..7c055a5cc0288da63a70716adf205651a3f4fc86 100644 (file)
--- a/player.c
+++ b/player.c
 // static abuf_t audio_buffer[BUFFER_FRAMES];
 #define BUFIDX(seqno) ((seq_t)(seqno) % BUFFER_FRAMES)
 
-uint32_t rtp_frame_offset(uint32_t base, uint32_t frame_in_question) {
-       if (base <= frame_in_question)
-               return frame_in_question - base;
+uint32_t rtp_frame_offset(uint32_t from, uint32_t to) {
+       if (from <= to)
+               return to - from;
        else
-               return UINT32_MAX - base + frame_in_question + 1;
+               return UINT32_MAX - from + to + 1;
 }
 
 void do_flush(uint32_t timestamp, rtsp_conn_info *conn);
@@ -944,8 +944,8 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
 
               uint64_t should_be_time;
               frame_to_local_time(
-                  conn->first_packet_timestamp + conn->latency * conn->output_sample_ratio +
-                      (int64_t)(config.audio_backend_latency_offset * config.output_rate),
+                  conn->first_packet_timestamp + conn->latency +
+                      (uint32_t)(config.audio_backend_latency_offset * conn->input_rate), // this will go modulo 2^32
                   &should_be_time, conn);
 
               conn->first_packet_time_to_play = should_be_time;
@@ -965,8 +965,8 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
 
             uint64_t should_be_time;
             frame_to_local_time(
-                conn->first_packet_timestamp + conn->latency * conn->output_sample_ratio +
-                    (int64_t)(config.audio_backend_latency_offset * config.output_rate),
+                conn->first_packet_timestamp + conn->latency +
+                    (uint32_t)(config.audio_backend_latency_offset * conn->input_rate), // this should go modulo 2^32
                 &should_be_time, conn);
 
             conn->first_packet_time_to_play = should_be_time;
@@ -1163,9 +1163,9 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
 
         uint64_t time_to_play;
         frame_to_local_time(
-            (curframe->given_timestamp + conn->latency) * conn->output_sample_ratio +
-                (int64_t)(config.audio_backend_latency_offset * config.output_rate) -
-                config.audio_backend_buffer_desired_length * config.output_rate,
+            curframe->given_timestamp + conn->latency +
+                (uint32_t)(config.audio_backend_latency_offset * conn->input_rate) -
+                (uint32_t)(config.audio_backend_buffer_desired_length * conn->input_rate), // this will go modulo 2^32
             &time_to_play, conn);
 
         if (local_time_now >= time_to_play) {
@@ -1908,7 +1908,6 @@ void *player_thread_func(void *arg) {
           uint64_t reference_timestamp_time, remote_reference_timestamp_time;
           get_reference_timestamp_stuff(&reference_timestamp, &reference_timestamp_time,
                                         &remote_reference_timestamp_time, conn); // types okay
-          reference_timestamp *= conn->output_sample_ratio;
           int64_t rt, nt;
           rt = reference_timestamp; // uint32_t to int64_t
           nt = inframe->given_timestamp;  // uint32_t to int64_t
@@ -2000,8 +1999,9 @@ void *player_thread_func(void *arg) {
 
           if (resp >= 0) {
 
-            int64_t should_be_frame;
-            local_time_to_frame(local_time_now, &should_be_frame, conn);
+            uint32_t should_be_frame_32;
+            local_time_to_frame(local_time_now, &should_be_frame_32, conn);
+            int64_t should_be_frame = ((int64_t)should_be_frame_32) * conn->output_sample_ratio;
 
             // int64_t absolute_difference_in_frames = td_in_frames + rt - should_be_frame;
             // if (absolute_difference_in_frames < 0)
@@ -2041,11 +2041,11 @@ void *player_thread_func(void *arg) {
                 (config.resyncthreshold > 0.0) &&
                 (abs_sync_error > config.resyncthreshold * config.output_rate)) {
               if (abs_sync_error > 3 * config.output_rate) {
-                warn("Very large sync error: %" PRId64 " frames, with delay: %" PRId64
-                     ", td_in_frames: %" PRId64 ", rt: %" PRId64 ", nt: %" PRId64
-                     ", current_delay: %" PRId64 ", seqno: %u, given timestamp: %" PRIu32 ".",
-                     sync_error, delay, td_in_frames, rt, nt, current_delay,
-                     inframe->sequence_number, inframe->given_timestamp);
+              
+                warn("Very large sync error: %" PRId64 " frames, with should_be_frame: %" PRId64
+                     ",  nt: %" PRId64
+                     ", current_delay: %" PRId64 ", given timestamp %" PRIX32 ", reference timestamp %" PRIX32 ", should_be_frame %" PRIX32 ".",
+                     sync_error, should_be_frame, nt, current_delay, inframe->given_timestamp, reference_timestamp, should_be_frame_32);
               }
               sync_error_out_of_bounds++;
             } else {
index 6c10d34d025edd708b7592bdd06a7717412d041d..43d93c052970b606909f15a50131252d040bb093 100644 (file)
--- a/player.h
+++ b/player.h
@@ -242,6 +242,8 @@ typedef struct {
   void *dapo_private_storage;  // this is used for compatibility, if dacp stuff isn't enabled.
 } rtsp_conn_info;
 
+uint32_t rtp_frame_offset(uint32_t from, uint32_t to);
+
 int player_play(rtsp_conn_info *conn);
 int player_stop(rtsp_conn_info *conn);
 
diff --git a/rtp.c b/rtp.c
index 4cd96aba755ab56bac450cb581d1d7e53a274ee8..599d5a489c6cccafc71fbd4236b9e3842e556499 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -1034,13 +1034,14 @@ int have_timestamp_timing_information(rtsp_conn_info *conn) {
 // right...
 const int use_nominal_rate = 0; // specify whether to use the nominal input rate, usually 44100 fps
 
-int sanitised_source_rate_information(int64_t *frames, uint64_t *time, rtsp_conn_info *conn) {
+int sanitised_source_rate_information(uint32_t *frames, uint64_t *time, rtsp_conn_info *conn) {
   int result = 1;
   *frames = conn->input_rate;
   *time = (uint64_t)(0x100000000); // one second in fp form
   if ((conn->packet_stream_established) && (conn->initial_reference_time) &&
       (conn->initial_reference_timestamp)) {
-    int64_t local_frames = conn->reference_timestamp - conn->initial_reference_timestamp;
+//    uint32_t local_frames = conn->reference_timestamp - conn->initial_reference_timestamp;
+    uint32_t local_frames = rtp_frame_offset(conn->initial_reference_timestamp, conn->reference_timestamp);
     uint64_t local_time = conn->remote_reference_timestamp_time - conn->initial_reference_time;
     if ((local_frames == 0) || (local_time == 0) || (use_nominal_rate)) {
       result = 1;
@@ -1060,39 +1061,34 @@ int sanitised_source_rate_information(int64_t *frames, uint64_t *time, rtsp_conn
   return result;
 }
 
-// we assume here that the timestamp is a timestamp calculated at the output rate, which could be an
-// integer multiple of the input rate
+// the timestamp is a timestamp calculated at the input rate
 // the reference timestamps are denominated in terms of the input rate
 
-int frame_to_local_time(int64_t timestamp, uint64_t *time, rtsp_conn_info *conn) {
+int frame_to_local_time(uint32_t timestamp, uint64_t *time, rtsp_conn_info *conn) {
   debug_mutex_lock(&conn->reference_time_mutex, 1000, 1);
   int result = 0;
   uint64_t time_difference;
-  int64_t frame_difference;
+  uint32_t frame_difference;
   result = sanitised_source_rate_information(&frame_difference, &time_difference, conn);
 
-  int64_t timestamp_interval =
-      timestamp -
-      conn->reference_timestamp *
-          conn->output_sample_ratio; // we could be dealing with multiples of 44100 (nominally)
-  // debug(1, "Timestamp interval: %" PRId64 " frames with reference timestamp %" PRId64
-  // ".",timestamp_interval,conn->reference_timestamp);
   uint64_t timestamp_interval_time;
   uint64_t remote_time_of_timestamp;
-  if (timestamp_interval >= 0) {
+  uint32_t timestamp_interval = rtp_frame_offset(conn->reference_timestamp,timestamp);
+  if (timestamp_interval <= 44100*10) { // i.e. timestamp was really after the reference timestamp
     timestamp_interval_time =
         (timestamp_interval * time_difference) /
-        (frame_difference * conn->output_sample_ratio); // this is the nominal time, based on the
+        (frame_difference);                             // this is the nominal time, based on the
                                                         // fps specified between current and
                                                         // previous sync frame.
     remote_time_of_timestamp = conn->remote_reference_timestamp_time +
                                timestamp_interval_time; // based on the reference timestamp time
                                                         // plus the time interval calculated based
                                                         // on the specified fps.
-  } else {
+  } else { // i.e. timestamp was actually after the reference timestamp
+    timestamp_interval = rtp_frame_offset(timestamp,conn->reference_timestamp); // fix the calculation
     timestamp_interval_time =
-        ((-timestamp_interval) * time_difference) /
-        (frame_difference * conn->output_sample_ratio); // this is the nominal time, based on the
+        (timestamp_interval * time_difference) /
+        (frame_difference);                             // this is the nominal time, based on the
                                                         // fps specified between current and
                                                         // previous sync frame.
     remote_time_of_timestamp = conn->remote_reference_timestamp_time -
@@ -1105,12 +1101,12 @@ int frame_to_local_time(int64_t timestamp, uint64_t *time, rtsp_conn_info *conn)
   return result;
 }
 
-int local_time_to_frame(uint64_t time, int64_t *frame, rtsp_conn_info *conn) {
+int local_time_to_frame(uint64_t time, uint32_t *frame, rtsp_conn_info *conn) {
   debug_mutex_lock(&conn->reference_time_mutex, 1000, 1);
   int result = 0;
 
   uint64_t time_difference;
-  int64_t frame_difference;
+  uint32_t frame_difference;
   result = sanitised_source_rate_information(&frame_difference, &time_difference, conn);
 
   // first, get from [local] time to remote time.
@@ -1129,10 +1125,10 @@ int local_time_to_frame(uint64_t time, int64_t *frame, rtsp_conn_info *conn) {
   int64_t frame_interval = (time_interval * frame_difference) / time_difference;
   if (remote_time >= conn->remote_reference_timestamp_time) {
     // debug(1,"Frame interval is %" PRId64 " frames.",frame_interval);
-    *frame = (conn->reference_timestamp + frame_interval) * conn->output_sample_ratio;
+    *frame = (conn->reference_timestamp + frame_interval);
   } else {
     // debug(1,"Frame interval is %" PRId64 " frames.",-frame_interval);
-    *frame = (conn->reference_timestamp - frame_interval) * conn->output_sample_ratio;
+    *frame = (conn->reference_timestamp - frame_interval);
   }
   debug_mutex_unlock(&conn->reference_time_mutex, 3);
   return result;
diff --git a/rtp.h b/rtp.h
index 9bf5c696545e0d0a207b779b487f101964c0b8e4..171bd651a70fdd8386a47ba11ae43cafc0afdd39 100644 (file)
--- a/rtp.h
+++ b/rtp.h
@@ -25,9 +25,9 @@ int have_timestamp_timing_information(rtsp_conn_info *conn);
 
 int get_frame_play_time(int64_t timestamp, int sample_ratio, uint64_t *time_to_play);
 
-int frame_to_local_time(int64_t timestamp, uint64_t *time, rtsp_conn_info *conn);
-int local_time_to_frame(uint64_t time, int64_t *frame, rtsp_conn_info *conn);
+int frame_to_local_time(uint32_t timestamp, uint64_t *time, rtsp_conn_info *conn);
+int local_time_to_frame(uint64_t time, uint32_t *frame, rtsp_conn_info *conn);
 
-int sanitised_source_rate_information(int64_t *frames, uint64_t *time, rtsp_conn_info *conn);
+int sanitised_source_rate_information(uint32_t *frames, uint64_t *time, rtsp_conn_info *conn);
 
 #endif // _RTP_H