Does pretty well with flushing. Sometimes misses a flush on a repeat one.

This commit is contained in:
Mike Brady
2021-05-28 22:20:11 +01:00
parent e258cca33a
commit 2986b282d3
3 changed files with 35 additions and 80 deletions
+7 -4
View File
@@ -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");
+26 -74
View File
@@ -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];
+2 -2
View File
@@ -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");