diff --git a/common.h b/common.h index 4a6c44f0..4aa3568a 100644 --- a/common.h +++ b/common.h @@ -69,7 +69,7 @@ typedef struct { uint32_t AirPlayLatency; // supplied with --AirPlayLatency option uint32_t ForkedDaapdLatency; // supplied with --ForkedDaapdLatency option int daemonise; - int statistics_requested; + int statistics_requested,use_negotiated_latencies; char *cmd_start, *cmd_stop; int cmd_blocking; int tolerance; // allow this much drift before attempting to correct it diff --git a/configure.ac b/configure.ac index 4d6f2983..9ac37f2e 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.50]) -AC_INIT([shairport-sync], [2.5.0.5], [mikebrady@eircom.net]) +AC_INIT([shairport-sync], [2.5.0.6], [mikebrady@eircom.net]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([shairport.c]) AC_CONFIG_HEADERS([config.h]) diff --git a/player.c b/player.c index 859e5136..80fcae22 100644 --- a/player.c +++ b/player.c @@ -299,11 +299,10 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len) time_of_last_audio_packet = get_absolute_time_in_fp(); if (connection_state_to_output) { // if we are supposed to be processing these packets - if (flush_rtp_timestamp != 0) - debug(1,"Flush_rtp_timestamp is %u",flush_rtp_timestamp); +// if (flush_rtp_timestamp != 0) +// debug(1,"Flush_rtp_timestamp is %u",flush_rtp_timestamp); -// if ((flush_rtp_timestamp != 0) && - if ((0) && + if ((flush_rtp_timestamp != 0) && ((timestamp == flush_rtp_timestamp) || seq32_order(timestamp, flush_rtp_timestamp))) { debug(2, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to " "timestamp: %u.", @@ -1247,7 +1246,7 @@ void player_volume(double f) { } void player_flush(uint32_t timestamp) { - debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp); + // debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp); pthread_mutex_lock(&flush_mutex); flush_requested = 1; // if (timestamp!=0) diff --git a/rtp.c b/rtp.c index 2053f43c..8ab96589 100644 --- a/rtp.c +++ b/rtp.c @@ -194,8 +194,14 @@ static void *rtp_control_receiver(void *arg) { rtp_timestamp_less_latency = ntohl(*((uint32_t *)&packet[4])); sync_rtp_timestamp = ntohl(*((uint32_t *)&packet[16])); - debug(1,"Latency is %u frames.",sync_rtp_timestamp-rtp_timestamp_less_latency); - + if (config.use_negotiated_latencies) { + uint32_t la = sync_rtp_timestamp-rtp_timestamp_less_latency+11025; + if (la!=config.latency) { + config.latency = la; + debug(1,"Using negotiated latency of %u frames.",config.latency); + } + } + 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 068b12f1..7e4c077c 100644 --- a/rtsp.c +++ b/rtsp.c @@ -582,7 +582,7 @@ static void msg_write_response(int fd, rtsp_message *resp) { } static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Handle Record"); + //debug(1,"Handle Record"); resp->respcode = 200; // I think this is for telling the client what the asbsolute minimum latency actually is, // and when the client specifies a latency, it should be added to this figure. @@ -590,7 +590,7 @@ static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message // Thus, AirPlay's latency figure of 77175, when added to 11025 gives you exactly 88200 // and iTunes' latency figure of 88553, when added to 11025 gives you 99578, pretty close to the 99400 we guessed. - msg_add_header(resp, "Audio-Latency", "88200"); + msg_add_header(resp, "Audio-Latency", "11025"); char *p; uint32_t rtptime = 0; @@ -650,7 +650,7 @@ static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message * } static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Handle Setup"); + // debug(1,"Handle Setup"); int cport, tport; int lsport, lcport, ltport; uint32_t active_remote = 0; diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf index b2ac51a5..a2975789 100644 --- a/scripts/shairport-sync.conf +++ b/scripts/shairport-sync.conf @@ -23,6 +23,7 @@ general = // It's probably better to compensate for a delay in the output device using the alsa "audio_backend_latency_offset" setting -- see below. latencies = { +// use_negotiated_latencies = "no"; // set this to "yes" to negotiate latencies with the client, and ignore the static settings listed below // default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X. // itunes = 99400; // used for iTunes 10 or later // airplay = 88200; diff --git a/shairport.c b/shairport.c index 2561350a..a1a37e80 100644 --- a/shairport.c +++ b/shairport.c @@ -399,6 +399,16 @@ int parse_options(int argc, char **argv) { die("Invalid ignore_volume_control option choice \"%s\". It should be \"yes\" or \"no\""); } + /* Get the dynamic latencies setting. */ + if (config_lookup_string(config.cfg, "latencies.use_negotiated_latencies", &str)) { + if (strcasecmp(str, "no") == 0) + config.use_negotiated_latencies = 0; + else if (strcasecmp(str, "yes") == 0) + config.use_negotiated_latencies = 1; + else + die("Invalid use_negotiated_latencies option choice \"%s\". It should be \"yes\" or \"no\""); + } + /* Get the default latency. */ if (config_lookup_int(config.cfg, "latencies.default", &value)) config.latency = value; @@ -850,6 +860,7 @@ int main(int argc, char **argv) { debug(2, "audio backend desired buffer length is %d.", config.audio_backend_buffer_desired_length); debug(2, "audio backend latency offset is %d.", config.audio_backend_latency_offset); + debug(2, "use_negotiated_latencies %d.", config.use_negotiated_latencies); char *realConfigPath = realpath(config.configfile,NULL); if (realConfigPath) {