Cache audio timestamp frame position across track transition reset
Upon track transition of offloaded playback of gapless tracks, the framework will reset the audiotrack frame position. The `AudioTrackPositionTracker`'s `AudioTimestampPoller` must be made to expect the reset and cache accumulated sum of `AudioTimestamp.framePosition`. #cherrypick PiperOrigin-RevId: 647294360
This commit is contained in:
parent
dcbded0fa9
commit
a58e77a5a6
@ -236,6 +236,16 @@ import java.lang.annotation.Target;
|
|||||||
return audioTimestamp != null ? audioTimestamp.getTimestampPositionFrames() : C.INDEX_UNSET;
|
return audioTimestamp != null ? audioTimestamp.getTimestampPositionFrames() : C.INDEX_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the poller to expect a reset in audio track frame position due to an impending track
|
||||||
|
* transition and reusing of the {@link AudioTrack}.
|
||||||
|
*/
|
||||||
|
public void expectTimestampFramePositionReset() {
|
||||||
|
if (audioTimestamp != null) {
|
||||||
|
audioTimestamp.expectTimestampFramePositionReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateState(@State int state) {
|
private void updateState(@State int state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -270,6 +280,18 @@ import java.lang.annotation.Target;
|
|||||||
private long lastTimestampRawPositionFrames;
|
private long lastTimestampRawPositionFrames;
|
||||||
private long lastTimestampPositionFrames;
|
private long lastTimestampPositionFrames;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to expect a raw playback head reset.
|
||||||
|
*
|
||||||
|
* <p>When an {@link AudioTrack} is reused during offloaded playback, the {@link
|
||||||
|
* AudioTimestamp#framePosition} is reset upon track transition. {@link AudioTimestampWrapper}
|
||||||
|
* must be notified of the impending reset and keep track of total accumulated {@code
|
||||||
|
* AudioTimestamp.framePosition}.
|
||||||
|
*/
|
||||||
|
private boolean expectTimestampFramePositionReset;
|
||||||
|
|
||||||
|
private long accumulatedRawTimestampFramePosition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link AudioTimestamp} wrapper.
|
* Creates a new {@link AudioTimestamp} wrapper.
|
||||||
*
|
*
|
||||||
@ -291,12 +313,19 @@ import java.lang.annotation.Target;
|
|||||||
if (updated) {
|
if (updated) {
|
||||||
long rawPositionFrames = audioTimestamp.framePosition;
|
long rawPositionFrames = audioTimestamp.framePosition;
|
||||||
if (lastTimestampRawPositionFrames > rawPositionFrames) {
|
if (lastTimestampRawPositionFrames > rawPositionFrames) {
|
||||||
// The value must have wrapped around.
|
if (expectTimestampFramePositionReset) {
|
||||||
rawTimestampFramePositionWrapCount++;
|
accumulatedRawTimestampFramePosition += lastTimestampRawPositionFrames;
|
||||||
|
expectTimestampFramePositionReset = false;
|
||||||
|
} else {
|
||||||
|
// The value must have wrapped around.
|
||||||
|
rawTimestampFramePositionWrapCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastTimestampRawPositionFrames = rawPositionFrames;
|
lastTimestampRawPositionFrames = rawPositionFrames;
|
||||||
lastTimestampPositionFrames =
|
lastTimestampPositionFrames =
|
||||||
rawPositionFrames + (rawTimestampFramePositionWrapCount << 32);
|
rawPositionFrames
|
||||||
|
+ accumulatedRawTimestampFramePosition
|
||||||
|
+ (rawTimestampFramePositionWrapCount << 32);
|
||||||
}
|
}
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
@ -308,5 +337,9 @@ import java.lang.annotation.Target;
|
|||||||
public long getTimestampPositionFrames() {
|
public long getTimestampPositionFrames() {
|
||||||
return lastTimestampPositionFrames;
|
return lastTimestampPositionFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void expectTimestampFramePositionReset() {
|
||||||
|
expectTimestampFramePositionReset = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,6 +476,9 @@ import java.lang.reflect.Method;
|
|||||||
*/
|
*/
|
||||||
public void expectRawPlaybackHeadReset() {
|
public void expectRawPlaybackHeadReset() {
|
||||||
expectRawPlaybackHeadReset = true;
|
expectRawPlaybackHeadReset = true;
|
||||||
|
if (audioTimestampPoller != null) {
|
||||||
|
audioTimestampPoller.expectTimestampFramePositionReset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user