|
|
|
|
@ -65,6 +65,7 @@ struct StreamPlayerWindow::Playback {
|
|
|
|
|
if (!started) return 0; |
|
|
|
|
if (activeAudio && sound && audioAvailable) |
|
|
|
|
return std::max(position, stream_playback_audio_position(sound, played(now))); |
|
|
|
|
if (holdAudio) return position; |
|
|
|
|
int64_t proposed = position + (now - clockAt) * adaptation.tempo_milli / 1000; |
|
|
|
|
return std::max(position, std::min(ready, proposed)); |
|
|
|
|
} |
|
|
|
|
@ -242,7 +243,9 @@ void StreamPlayerWindow::decode() {
|
|
|
|
|
if (p.started && p.ready >= 0) { |
|
|
|
|
uint64_t played = p.played(now); |
|
|
|
|
p.holdAudio = !p.videos.empty() && p.videos.front().pts < position - 40000; |
|
|
|
|
int starved = p.holdAudio || (p.sound && stream_playback_audio_starved(p.sound, played)); |
|
|
|
|
int virtualEmpty = !p.activeAudio && p.position + (now - p.clockAt) * p.adaptation.tempo_milli / 1000 > p.ready; |
|
|
|
|
if (!p.activeAudio && p.holdAudio) position = p.position; |
|
|
|
|
int starved = p.holdAudio || virtualEmpty || (p.sound && stream_playback_audio_starved(p.sound, played)); |
|
|
|
|
int64_t guardUs = std::max<int64_t>(33333, p.activeAudio ? p.deviceLead + 10000 : 33333); |
|
|
|
|
int64_t pending = p.sound ? stream_playback_audio_pending_gain(p.sound, played) : 0; |
|
|
|
|
if (stream_playback_clock_update(&p.adaptation, now, std::max(p.position, position), p.ready, |
|
|
|
|
@ -269,7 +272,7 @@ void StreamPlayerWindow::decode() {
|
|
|
|
|
fail(text(reason)); break; |
|
|
|
|
} |
|
|
|
|
if (record.kind == StreamRecordKind::End) { |
|
|
|
|
std::lock_guard<std::mutex> guard(p.lock); p.ended = true; |
|
|
|
|
std::lock_guard<std::mutex> guard(p.lock); p.ended = true; p.holdAudio = false; |
|
|
|
|
if (p.sound) stream_playback_audio_finish(p.sound); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|