Skip to content

Commit

Permalink
Fix AudioTrackPositionTracker logic for playback speed adjustments
Browse files Browse the repository at this point in the history
The AudioTrackPositionTracker needs to correct positions by
the speed set on the AudioTrack itself whenever it makes
estimations based on real-time (=the real-time playout
duration is not equal to the media duration played).

This happens for the main playback path already, but not for
the mode in which the position is estimated from the playback
head position and also not in the phase after the track has
been stopped. Both cases are not very noticeable during
normal playback, but become relevant when playing in offload
mode.

PiperOrigin-RevId: 507736408
(cherry picked from commit 01d7bc7)
  • Loading branch information
tonihei committed Feb 28, 2023
1 parent bd664ad commit ba2b9b3
Showing 1 changed file with 10 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ public void setAudioTrackPlaybackSpeed(float audioTrackPlaybackSpeed) {
if (audioTimestampPoller != null) {
audioTimestampPoller.reset();
}
resetSyncParams();
}

public long getCurrentPositionUs(boolean sourceEnded) {
Expand Down Expand Up @@ -282,7 +283,9 @@ public long getCurrentPositionUs(boolean sourceEnded) {
// getPlaybackHeadPositionUs() only has a granularity of ~20 ms, so we base the position off
// the system clock (and a smoothed offset between it and the playhead position) so as to
// prevent jitter in the reported positions.
positionUs = systemTimeUs + smoothedPlayheadOffsetUs;
positionUs =
Util.getMediaDurationForPlayoutDuration(
systemTimeUs + smoothedPlayheadOffsetUs, audioTrackPlaybackSpeed);
}
if (!sourceEnded) {
positionUs = max(0, positionUs - latencyUs);
Expand Down Expand Up @@ -452,7 +455,9 @@ private void maybeSampleSyncParams() {
long systemTimeUs = System.nanoTime() / 1000;
if (systemTimeUs - lastPlayheadSampleTimeUs >= MIN_PLAYHEAD_OFFSET_SAMPLE_INTERVAL_US) {
// Take a new sample and update the smoothed offset between the system clock and the playhead.
playheadOffsets[nextPlayheadOffsetIndex] = playbackPositionUs - systemTimeUs;
playheadOffsets[nextPlayheadOffsetIndex] =
Util.getPlayoutDurationForMediaDuration(playbackPositionUs, audioTrackPlaybackSpeed)
- systemTimeUs;
nextPlayheadOffsetIndex = (nextPlayheadOffsetIndex + 1) % MAX_PLAYHEAD_OFFSET_COUNT;
if (playheadOffsetCount < MAX_PLAYHEAD_OFFSET_COUNT) {
playheadOffsetCount++;
Expand Down Expand Up @@ -580,7 +585,9 @@ private long getPlaybackHeadPosition() {
if (stopTimestampUs != C.TIME_UNSET) {
// Simulate the playback head position up to the total number of frames submitted.
long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
long mediaTimeSinceStopUs =
Util.getMediaDurationForPlayoutDuration(elapsedTimeSinceStopUs, audioTrackPlaybackSpeed);
long framesSinceStop = (mediaTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
return min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
}

Expand Down

0 comments on commit ba2b9b3

Please sign in to comment.