]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
use max-latency and min-latency information in AirPlay ANNOUNCE packets, remove diffe...
authorMike Brady <mikebrady@eircom.net>
Tue, 9 Jan 2018 17:54:24 +0000 (17:54 +0000)
committerMike Brady <mikebrady@eircom.net>
Tue, 9 Jan 2018 17:54:24 +0000 (17:54 +0000)
common.h
player.h
rtp.c
rtsp.c
shairport.c

index 2d1547c6609ac7dc01dfab72b865c64d559c27b3..aa4633b87fd7b4dfbd59a228df92ba3e450fa48e 100644 (file)
--- a/common.h
+++ b/common.h
@@ -123,9 +123,8 @@ typedef struct {
   int buffer_start_fill;
   int64_t latency;
   int64_t userSuppliedLatency; // overrides all other latencies -- use with caution
-  int64_t iTunesLatency;       // supplied with --iTunesLatency option
-  int64_t AirPlayLatency;      // supplied with --AirPlayLatency option
-  int64_t ForkedDaapdLatency;  // supplied with --ForkedDaapdLatency option
+  int64_t fixedLatencyOffset;  // add this to all automatic latencies supplied to get the actual total latency
+                               // the total latency will be limited to the min and max-latency values, if supplied
   int daemonise;
   int daemonise_store_pid; // don't try to save a PID file
   char *piddir;
index 0f55729913c24b4d0e9e58760d0487596d894ae7..2b0a47c7b44e6ef503cff69c22a479522b7c42a6 100644 (file)
--- a/player.h
+++ b/player.h
@@ -63,8 +63,9 @@ typedef struct {
 
 typedef struct {
   int connection_number;           // for debug ID purposes, nothing else...
-  int64_t staticLatencyCorrection; // it seems iTunes needs some offset before it's more or less
-                                   // right. Odd.
+  int64_t minimum_latency; // set if an a=min-latency: line appears in the ANNOUNCE message; zero otherwise
+  int64_t maximum_latency; // set if an a=max-latency: line appears in the ANNOUNCE message; zero otherwise
+  
 #if defined(HAVE_DBUS) || defined(HAVE_MPRIS)
   enum session_status_type play_state;
 #endif
diff --git a/rtp.c b/rtp.c
index 64fbe6d7cca27950979886d1de3d3a84453e5c62..c24940ca6f9ad1050763164673a944f8220f821c 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -226,18 +226,28 @@ void *rtp_control_receiver(void *arg) {
         rtp_timestamp_less_latency = monotonic_timestamp(ntohl(*((uint32_t *)&packet[4])), conn);
         sync_rtp_timestamp = monotonic_timestamp(ntohl(*((uint32_t *)&packet[16])), conn);
 
-        if (config.use_negotiated_latencies) {
+        if (config.userSuppliedLatency) {
+          if (config.userSuppliedLatency != config.latency) {
+            debug(1,"Using the user-supplied latency: %lld.",config.userSuppliedLatency);           
+          }
+          config.latency = config.userSuppliedLatency;
+        } else {
           int64_t la =
-              sync_rtp_timestamp - rtp_timestamp_less_latency + conn->staticLatencyCorrection;
+              sync_rtp_timestamp - rtp_timestamp_less_latency + config.fixedLatencyOffset;
+          if ((conn->maximum_latency) && (conn->maximum_latency<la))
+            la = conn->maximum_latency;
+          if ((conn->minimum_latency) && (conn->minimum_latency>la))
+            la = conn->minimum_latency;    
+                  
           if (la != config.latency) {
             config.latency = la;
-            // debug(1,
-            //      "Using negotiated latency of %lld frames and a static latency correction of
-            //      %lld",
-            //      sync_rtp_timestamp - rtp_timestamp_less_latency, conn->staticLatencyCorrection);
+            debug(1,"New latency: %lld, sync latency: %lld, minimum latency: %lld, maximum latency: %lld, fixed offset: %lld.",
+              la,sync_rtp_timestamp - rtp_timestamp_less_latency,conn->minimum_latency,conn->maximum_latency,config.fixedLatencyOffset);
           }
         }
 
+        // need to clarify this.
+
         if (packet[0] & 0x10) {
           // if it's a packet right after a flush or resume
           sync_rtp_timestamp += 352; // add frame_size -- can't see a reference to this anywhere,
diff --git a/rtsp.c b/rtsp.c
index fcb8a4d687c784ba7cd295dcb46163a5ce77285c..7f1769c7eaee5b4f30e3993b8611964839588f73 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -3,7 +3,7 @@
  * Copyright (c) James Laird 2013
 
  * Modifications associated with audio synchronization, mutithreading and
- * metadata handling copyright (c) Mike Brady 2014-2017
+ * metadata handling copyright (c) Mike Brady 2014-2018
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
@@ -771,70 +771,7 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
     send_metadata('ssnc', 'daid', ar, strlen(ar), req, 1);
 #endif
   }
-
-  // This latency-setting mechanism is deprecated and will be removed.
-  // If no non-standard latency is chosen, automatic negotiated latency setting
-  // is permitted.
-
-  // Select a static latency
-  // if iTunes V10 or later is detected, use the iTunes latency setting
-  // if AirPlay is detected, use the AirPlay latency setting
-  // for everything else, use the general latency setting, if given, or
-  // else use the default latency setting
-
-  config.latency = -1;
-
-  if (config.userSuppliedLatency)
-    config.latency = config.userSuppliedLatency;
-
-  char *ua = msg_get_header(req, "User-Agent");
-  if (ua == 0) {
-    debug(1, "No User-Agent string found in the SETUP message. Using latency "
-             "of %d frames.",
-          config.latency);
-  } else {
-    if (strstr(ua, "iTunes") == ua) {
-      int iTunesVersion = 0;
-      // now check it's version 10 or later
-      char *pp = strchr(ua, '/') + 1;
-      if (pp)
-        iTunesVersion = atoi(pp);
-      else
-        debug(2, "iTunes Version Number not found.");
-      if (iTunesVersion >= 10) {
-        debug(1, "User-Agent is iTunes 10 or better, (actual version is %d); "
-                 "selecting the iTunes "
-                 "latency of %d frames.",
-              iTunesVersion, config.iTunesLatency);
-        config.latency = config.iTunesLatency;
-        conn->staticLatencyCorrection = 11025;
-      }
-    } else if (strstr(ua, "AirPlay") == ua) {
-      debug(2, "User-Agent is AirPlay; selecting the AirPlay latency of %d frames.",
-            config.AirPlayLatency);
-      config.latency = config.AirPlayLatency;
-    } else if (strstr(ua, "forked-daapd") == ua) {
-      debug(2, "User-Agent is forked-daapd; selecting the forked-daapd latency "
-               "of %d frames.",
-            config.ForkedDaapdLatency);
-      config.latency = config.ForkedDaapdLatency;
-      conn->staticLatencyCorrection = 11025;
-    } else if (strstr(ua, "Airfoil") == ua) {
-      debug(2, "User-Agent is Airfoil");
-      conn->staticLatencyCorrection = 11025;
-    } else {
-      debug(2, "Unrecognised User-Agent. Using latency of %d frames.", config.latency);
-    }
-  }
-
-  if (config.latency == -1) {
-    // this means that no static latency was set, so we'll allow it to be set
-    // dynamically
-    config.latency = 88198; // to be sure, to be sure -- make it slighty
-                            // different from the default to ensure we get a
-                            // debug message when set to 88200
-    config.use_negotiated_latencies = 1;
-  }
+  
   char *hdr = msg_get_header(req, "Transport");
   if (!hdr)
     goto error;
@@ -1541,13 +1478,13 @@ static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag
     }
     
     if (pminlatency) {
-      int minl = atoi(pminlatency);
-      debug(1,"Minimum latency %d specified",minl);
+      conn->minimum_latency = atoi(pminlatency);
+      debug(1,"Minimum latency %d specified",conn->minimum_latency);
     }
 
     if (pmaxlatency) {
-      int maxl = atoi(pmaxlatency);
-      debug(1,"Maximum latency %d specified",maxl);
+      conn->maximum_latency = atoi(pmaxlatency);
+      debug(1,"Maximum latency %d specified",conn->maximum_latency);
     }
 
     if ((paesiv == NULL) && (prsaaeskey == NULL)) {
index ecabd07530206fc7fccd576814d44287835c84a8..e14830eb38385cb1c7a8580dc5cedccada5520ba 100644 (file)
@@ -279,18 +279,9 @@ void usage(char *progname) {
   printf("    -v, --verbose           -v print debug information; -vv more; -vvv lots.\n");
   printf("    -p, --port=PORT         set RTSP listening port.\n");
   printf("    -a, --name=NAME         set advertised name.\n");
-  //  printf("    -A, --AirPlayLatency=FRAMES [Deprecated] Set the latency for audio sent from an "
-  //         "AirPlay device.\n");
-  //  printf("                            The default is to set it automatically.\n");
-  //  printf("    -i, --iTunesLatency=FRAMES [Deprecated] Set the latency for audio sent from iTunes
-  //  "
-  //         "10 or later.\n");
-  //  printf("                            The default is to set it automatically.\n");
   printf("    -L, --latency=FRAMES    [Deprecated] Set the latency for audio sent from an unknown "
          "device.\n");
   printf("                            The default is to set it automatically.\n");
-  printf("    --forkedDaapdLatency=FRAMES [Deprecated] Set the latency for audio sent from "
-         "forked-daapd.\n");
   printf("                            The default is to set it automatically.\n");
   printf("    -S, --stuffing=MODE set how to adjust current latency to match desired latency, "
          "where \n");
@@ -369,9 +360,6 @@ int parse_options(int argc, char **argv) {
       {"wait-cmd", 'w', POPT_ARG_NONE, &config.cmd_blocking, 0, NULL},
       {"mdns", 'm', POPT_ARG_STRING, &config.mdns_name, 0, NULL},
       {"latency", 'L', POPT_ARG_INT, &config.userSuppliedLatency, 0, NULL},
-      {"AirPlayLatency", 'A', POPT_ARG_INT, &config.AirPlayLatency, 0, NULL},
-      {"iTunesLatency", 'i', POPT_ARG_INT, &config.iTunesLatency, 0, NULL},
-      {"forkedDaapdLatency", 'f', POPT_ARG_INT, &config.ForkedDaapdLatency, 0, NULL},
       {"stuffing", 'S', POPT_ARG_STRING, &stuffing, 'S', NULL},
       {"resync", 'r', POPT_ARG_INT, &fResyncthreshold, 0, NULL},
       {"timeout", 't', POPT_ARG_INT, &config.timeout, 't', NULL},
@@ -408,15 +396,15 @@ int parse_options(int argc, char **argv) {
       inform("Warning: the option -R or --reconnectToOutput is deprecated.");
       break;
     case 'A':
-      inform("Warning: the option -A or --AirPlayLatency is deprecated. This setting is now "
+      inform("Warning: the option -A or --AirPlayLatency is deprecated and ignored. This setting is now "
              "automatically received from the AirPlay device.");
       break;
     case 'i':
-      inform("Warning: the option -i or --iTunesLatency is deprecated. This setting is now "
+      inform("Warning: the option -i or --iTunesLatency is deprecated and ignored. This setting is now "
              "automatically received from iTunes");
       break;
     case 'f':
-      inform("Warning: the option --forkedDaapdLatency is deprecated. This setting is now "
+      inform("Warning: the option --forkedDaapdLatency is deprecated and ignored. This setting is now "
              "automatically received from forkedDaapd");
       break;
     case 'r':
@@ -447,6 +435,7 @@ int parse_options(int argc, char **argv) {
   config.audio_backend_silent_lead_in_time = -1.0; // flag to indicate it has not been set
   config.airplay_volume = -18.0; // if no volume is ever set, default to initial default value if
                                  // nothing else comes in first.
+  config.fixedLatencyOffset = 11025; // this sounds like it works properly.
 
   config_setting_t *setting;
   const char *str = 0;
@@ -710,18 +699,6 @@ int parse_options(int argc, char **argv) {
       if (config_lookup_int(config.cfg, "latencies.default", &value))
         config.userSuppliedLatency = value;
 
-      /* Get the itunes latency. Deprecated! */
-      if (config_lookup_int(config.cfg, "latencies.itunes", &value))
-        config.iTunesLatency = value;
-
-      /* Get the AirPlay latency. Deprecated! */
-      if (config_lookup_int(config.cfg, "latencies.airplay", &value))
-        config.AirPlayLatency = value;
-
-      /* Get the forkedDaapd latency. Deprecated! */
-      if (config_lookup_int(config.cfg, "latencies.forkedDaapd", &value))
-        config.ForkedDaapdLatency = value;
-
 #ifdef CONFIG_METADATA
       /* Get the metadata setting. */
       if (config_lookup_string(config.cfg, "metadata.enabled", &str)) {
@@ -1135,14 +1112,6 @@ int main(int argc, char **argv) {
   config.latency = -1; // -1 means not set. 88200 works well. This is also reset in rtsp.c when play
                        // is about to start
   config.userSuppliedLatency = 0; // zero means none supplied
-  config.iTunesLatency =
-      -1; // -1 means not supplied. 99400 seems to work pretty well for iTunes from Version 10 (?)
-          // upwards-- two left-ear headphones, one from the iMac jack, one
-          // from an NSLU2 running a cheap "3D Sound" USB Soundcard
-  config.AirPlayLatency =
-      -1; // -1 means not set. 88200 seems to work well for AirPlay -- Syncs sound and
-          // vision on AppleTV, but also used for iPhone/iPod/iPad sources
-  config.ForkedDaapdLatency = -1; // -1 means not set. 99400 seems to be right
   config.resyncthreshold = 0.05;  // 50 ms
   config.timeout = 120; // this number of seconds to wait for [more] audio before switching to idle.
   config.tolerance =
@@ -1374,55 +1343,12 @@ int main(int argc, char **argv) {
   }
 
   /* Mess around with the latency options */
-  // Basically, we used to rely on static latencies -- 99400 for iTunes 10 or later and forkedDaapd,
-  // 88200 for everything else
-  // Nowadays we allow the source to set the latency, which works out at 99651 for iTunes 10 and
-  // forkedDaapd and 88220 for everything else
-  // What we want to do here is allow the source to set the latency unless the user has specified an
-  // non-standard latency.
-  // If the user has specified a standard latency, we suggest to them to stop doing it.
+  // Basically, we expect the source to set the latency and add a fixed offset of 11025 frames to it, which sounds right
+  // If this latency is outside the max and min latensies that may be set by the source, clamp it to fit.
+  
   // If they specify a non-standard latency, we suggest the user to use the
   // audio_backend_latency_offset instead.
 
-  if (config.AirPlayLatency != -1) {
-    if (config.AirPlayLatency == 88200) {
-      inform("It is not necessary to set the AirPlay latency to 88200 -- you should remove this "
-             "setting or configuration option, as it is deprecated.");
-      config.AirPlayLatency = -1;
-    } else {
-      inform("The AirPlay latency setting is deprecated, as Shairport Sync can now get the correct "
-             "latency from the source.");
-      inform("Please remove this setting and use the relevant audio_backend_latency_offset "
-             "setting, if necessary, to compensate for delays elsewhere.");
-    }
-  }
-
-  if (config.iTunesLatency != -1) {
-    if (config.iTunesLatency == 99400) {
-      inform("It is not necessary to set the iTunes latency to 99400 -- you should remove this "
-             "setting or configuration option, as it is deprecated and ignored.");
-      config.iTunesLatency = -1;
-    } else {
-      inform("The iTunes latency setting is deprecated, as Shairport Sync can now get the correct "
-             "latency from the source.");
-      inform("Please remove this setting and use the relevant audio_backend_latency_offset "
-             "setting, if necessary, to compensate for delays elsewhere.");
-    }
-  }
-
-  if (config.ForkedDaapdLatency != -1) {
-    if (config.ForkedDaapdLatency == 99400) {
-      inform("It is not necessary to set the forkedDaapd latency to 99400 -- you should remove "
-             "this setting or configuration option, as it is deprecated and ignored.");
-      config.ForkedDaapdLatency = -1;
-    } else {
-      inform("The forkedDaapd latency setting is deprecated, as Shairport Sync can now get the "
-             "correct latency from the source.");
-      inform("Please remove this setting and use the relevant audio_backend_latency_offset "
-             "setting, if necessary, to compensate for delays elsewhere.");
-    }
-  }
-
   if (config.userSuppliedLatency) {
     inform("The default latency setting is deprecated, as Shairport Sync can now get the correct "
            "latency from the source.");
@@ -1455,9 +1381,6 @@ int main(int argc, char **argv) {
   debug(1, "on-start returns output is %d.", config.cmd_start_returns_output);
   debug(1, "mdns backend \"%s\".", config.mdns_name);
   debug(2, "userSuppliedLatency is %d.", config.userSuppliedLatency);
-  debug(2, "AirPlayLatency is %d.", config.AirPlayLatency);
-  debug(2, "iTunesLatency is %d.", config.iTunesLatency);
-  debug(2, "forkedDaapdLatency is %d.", config.ForkedDaapdLatency);
   debug(1, "stuffing option is \"%d\" (0-basic, 1-soxr).", config.packet_stuffing);
   debug(1, "resync time is %f seconds.", config.resyncthreshold);
   debug(1, "allow a session to be interrupted: %d.", config.allow_session_interruption);