Skip to content

Commit 013f63a

Browse files
committed
Update notify_about_position logic
It would be so much easier to use elapsed but elapsed could potentially panic is rare cases. See: https://doc.rust-lang.org/std/time/struct.Instant.html#monotonicity Otherwise this is pretty straight forward. If anything fails getting expected_position_ms it will return 0 which will trigger a notify if either stream_position_ms or decoder_position_ms >= 1000. If all goes well it's simply a matter of calculating the max delta of expected_position_ms and stream_position_ms and expected_position_ms and decoder_position_ms. So if the decoder or the sample pipeline are off by more than 1 sec we notify.
1 parent 09bd1bd commit 013f63a

File tree

1 file changed

+40
-50
lines changed

1 file changed

+40
-50
lines changed

playback/src/player.rs

Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,68 +1150,58 @@ impl Future for PlayerInternal {
11501150
match decoder.next_packet() {
11511151
Ok(result) => {
11521152
if let Some((ref packet_position, ref packet)) = result {
1153-
let new_stream_position_ms = packet_position
1154-
.position_ms
1155-
.saturating_sub(sample_pipeline_latency_ms);
1153+
let decoder_position_ms = packet_position.position_ms;
11561154

1157-
let expected_position_ms = std::mem::replace(
1158-
&mut *stream_position_ms,
1159-
new_stream_position_ms,
1160-
);
1155+
*stream_position_ms =
1156+
decoder_position_ms.saturating_sub(sample_pipeline_latency_ms);
11611157

11621158
if !passthrough {
11631159
match packet.samples() {
11641160
Ok(_) => {
1165-
let new_stream_position = Duration::from_millis(
1166-
new_stream_position_ms as u64,
1167-
);
1168-
11691161
let now = Instant::now();
11701162

1171-
// Only notify if we're skipped some packets *or* we are behind.
1172-
// If we're ahead it's probably due to a buffer of the backend
1173-
// and we're actually in time.
1174-
let notify_about_position =
1175-
match *reported_nominal_start_time {
1176-
None => true,
1177-
Some(reported_nominal_start_time) => {
1178-
let mut notify = false;
1179-
1180-
if packet_position.skipped {
1181-
if let Some(ahead) = new_stream_position
1182-
.checked_sub(Duration::from_millis(
1183-
expected_position_ms as u64,
1184-
))
1185-
{
1186-
notify |=
1187-
ahead >= Duration::from_secs(1)
1188-
}
1189-
}
1190-
1191-
if let Some(lag) = now
1192-
.checked_duration_since(
1193-
reported_nominal_start_time,
1194-
)
1195-
{
1196-
if let Some(lag) =
1197-
lag.checked_sub(new_stream_position)
1198-
{
1199-
notify |=
1200-
lag >= Duration::from_secs(1)
1201-
}
1202-
}
1203-
1204-
notify || sample_pipeline_latency_ms > 1000
1205-
}
1206-
};
1163+
let notify_about_position = {
1164+
// It would be so much easier to use elapsed but elapsed could
1165+
// potentially panic is rare cases.
1166+
// See:
1167+
// https://doc.rust-lang.org/std/time/struct.Instant.html#monotonicity
1168+
//
1169+
// Otherwise this is pretty straight forward. If anything fails getting
1170+
// expected_position_ms it will return 0 which will trigger a notify if
1171+
// either stream_position_ms or decoder_position_ms >= 1000. If all goes
1172+
// well it's simply a matter of calculating the max delta of expected_position_ms
1173+
// and stream_position_ms and expected_position_ms and decoder_position_ms.
1174+
// So if the decoder or the sample pipeline are off by more than 1 sec we notify.
1175+
let expected_position_ms = now
1176+
.checked_duration_since(
1177+
reported_nominal_start_time.unwrap_or(now),
1178+
)
1179+
.unwrap_or(Duration::ZERO)
1180+
.as_millis();
1181+
1182+
let max_expected_position_delta_ms =
1183+
expected_position_ms
1184+
.abs_diff(*stream_position_ms as u128)
1185+
.max(
1186+
expected_position_ms.abs_diff(
1187+
decoder_position_ms as u128,
1188+
),
1189+
);
1190+
1191+
max_expected_position_delta_ms > 1000
1192+
};
12071193

12081194
if notify_about_position {
1209-
*reported_nominal_start_time =
1210-
now.checked_sub(new_stream_position);
1195+
let position_ms = *stream_position_ms;
1196+
1197+
*reported_nominal_start_time = now.checked_sub(
1198+
Duration::from_millis(position_ms as u64),
1199+
);
1200+
12111201
self.send_event(PlayerEvent::PositionCorrection {
12121202
play_request_id,
12131203
track_id,
1214-
position_ms: new_stream_position_ms,
1204+
position_ms,
12151205
});
12161206
}
12171207
}

0 commit comments

Comments
 (0)