From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Fri, 28 May 2021 21:20:11 +0000 (+0100) Subject: Does pretty well with flushing. Sometimes misses a flush on a repeat one. X-Git-Tag: 4.1-dev~109 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2986b282d3139d4a22c472755c7f08f82aeccd96;p=thirdparty%2Fshairport-sync.git Does pretty well with flushing. Sometimes misses a flush on a repeat one. --- diff --git a/player.c b/player.c index efa40c63..a1bd0f40 100644 --- 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 3e1be921..465f25b5 100644 --- 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 24d8ea14..b9b38c25 100644 --- 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");