Shorten some arbitrary delays, quieten some debug messages, add (and comment out) disgnostic code to introduce a timing error. Make the buffer size 0.4 sec -- so that if a timing error of 150 ms is detected, enough frames are immediately available to be used.

This commit is contained in:
Mike Brady
2021-06-03 09:24:26 +01:00
parent bcad9d5998
commit 7a26139c44
+34 -20
View File
@@ -290,8 +290,8 @@ void *rtp_control_receiver(void *arg) {
obfp += 2;
};
*obfp = 0;
// get raw timestamp information
// I think that a good way to understand these timestamps is that
// (1) the rtlt below is the timestamp of the frame that should be playing at the
@@ -302,19 +302,19 @@ void *rtp_control_receiver(void *arg) {
// Thus, (3) the latency can be calculated by subtracting the second from the
// first.
// There must be more to it -- there something missing.
// In addition, it seems that if the value of the short represented by the second
// pair of bytes in the packet is 7
// then an extra time lag is expected to be added, presumably by
// the AirPort Express.
// Best guess is that this delay is 11,025 frames.
uint32_t rtlt = nctohl(&packet[4]); // raw timestamp less latency
uint32_t rt = nctohl(&packet[16]); // raw timestamp
uint32_t fl = nctohs(&packet[2]); //
debug(1,"Sync Packet of %d bytes received: \"%s\", flags: %d, timestamps %u and %u,
giving a latency of %d frames.",plen,obf,fl,rt,rtlt,rt-rtlt);
//debug(1,"Monotonic timestamps are: %" PRId64 " and %" PRId64 "
@@ -1790,7 +1790,6 @@ void *rtp_realtime_audio_receiver(void *arg) {
ssize_t buffered_read(buffered_tcp_desc *descriptor, void *buf, size_t count) {
ssize_t response;
// usleep(1500000);
if (pthread_mutex_lock(&descriptor->mutex) != 0)
debug(1, "problem with mutex");
pthread_cleanup_push(mutex_unlock, (void *)&descriptor->mutex);
@@ -2157,7 +2156,7 @@ void *rtp_buffered_audio_processor(void *arg) {
av_format = AV_SAMPLE_FMT_S32;
conn->input_bytes_per_frame = 8; // the output from the decoder will be input to the player
conn->input_bit_depth = 32;
debug(1, "32-bit output format chosen");
debug(2, "32-bit output format chosen");
break;
case SPS_FORMAT_S16:
case SPS_FORMAT_S16_LE:
@@ -2208,8 +2207,9 @@ void *rtp_buffered_audio_processor(void *arg) {
int streaming_has_started = 0;
int play_enabled = 0;
uint32_t flush_from_timestamp;
double requested_lead_time = 0.100; // normal lead time minimum
reset_buffer(conn); // in case there is any garbage in the player
double requested_lead_time = 0.10; // normal lead time minimum
reset_buffer(conn); // in case there is any garbage in the player
// int not_first_time_out = 0;
do {
int flush_is_delayed = 0;
int flush_newly_requested = 0;
@@ -2261,7 +2261,7 @@ void *rtp_buffered_audio_processor(void *arg) {
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);
debug(1, "flushUntilSeq %u overshot at %u.", flushUntilSeq, seq_no);
conn->ap2_flush_requested = 0;
flush_request_active = 0;
flush_newly_requested = 0;
@@ -2310,15 +2310,14 @@ void *rtp_buffered_audio_processor(void *arg) {
// debug(1,"player buffer size and occupancy: %u and %u", player_buffer_size,
// player_buffer_occupancy);
if (player_buffer_occupancy >
((requested_lead_time + 0.10) * 44100.0 / 352)) { // must be greater than the lead time.
((requested_lead_time + 0.4) * 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
// debug(1,"sleep for 20 ms");
usleep(20000); // wait for a while
usleep(1000); // wait for a while
} else {
if ((pcm_buffer_occupancy - pcm_buffer_read_point) >= (352 * conn->input_bytes_per_frame)) {
new_buffer_needed = 0;
// send a frame to the player if allowed
// it it's way too late, it means that a new anchor time is needed
// it it's way too late, it probably means that a new anchor time is needed
/*
uint32_t at_rtp = conn->reference_timestamp;
@@ -2348,19 +2347,35 @@ void *rtp_buffered_audio_processor(void *arg) {
// pcm_buffer_read_point_rtptime, expected_rtptime);
//}
// expected_rtptime = pcm_buffer_read_point_rtptime + 352;
// this is a diagnostic for introducing a timing error that will force the
// processing chain to resync
// clang-format off
/*
if ((not_first_time_out == 0) && (blocks_read >= 20)) {
int timing_error = 150;
debug(1, "Connection %d: Introduce a timing error of %d milliseconds.",
conn->connection_number, timing_error);
if (timing_error >= 0)
pcm_buffer_read_point_rtptime += (conn->input_rate * timing_error) / 1000;
else
pcm_buffer_read_point_rtptime -= (conn->input_rate * (-timing_error)) / 1000;
not_first_time_out = 1;
}
*/
// clang-format on
player_put_packet(0, 0, pcm_buffer_read_point_rtptime,
pcm_buffer + pcm_buffer_read_point, 352, conn);
streaming_has_started++;
usleep(2000);
}
}
pcm_buffer_read_point_rtptime += 352;
pcm_buffer_read_point += 352 * conn->input_bytes_per_frame;
}
// usleep(2000); // let other stuff happens
} else {
usleep(20000); // wait before asking if play is enabled again
usleep(1000); // wait before asking if play is enabled again
}
} else {
new_buffer_needed = 1;
@@ -2599,7 +2614,6 @@ void *rtp_buffered_audio_processor(void *arg) {
}
} else {
// nread is 0 -- the port has been closed
// finished = 1;
debug(1, "buffered audio port closed!");
finished = 1;
}