Make calculateSpeedAdjustedTime() output monotonically increasing

calculate based on the output of consecutive calls rather than the speed provider speed change point to ensure the timestamps are monotonically increasing.

PiperOrigin-RevId: 619584001
This commit is contained in:
tofunmi 2024-03-27 10:52:44 -07:00 committed by Copybara-Service
parent 8fe70332ee
commit 828f6d87f9

View File

@ -16,6 +16,7 @@
package androidx.media3.common.audio; package androidx.media3.common.audio;
import static androidx.media3.common.util.Assertions.checkArgument;
import static java.lang.Math.min; import static java.lang.Math.min;
import static java.lang.Math.round; import static java.lang.Math.round;
@ -60,8 +61,11 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
private float currentSpeed; private float currentSpeed;
private long bytesRead; private long bytesRead;
private long lastProcessedInputTime; private long lastProcessedInputTimeUs;
private long lastSpeedAdjustedInputTimeUs;
private long lastSpeedAdjustedOutputTimeUs;
private boolean endOfStreamQueuedToSonic; private boolean endOfStreamQueuedToSonic;
private long speedAdjustedTimeAsyncInputTimeUs;
public SpeedChangingAudioProcessor(SpeedProvider speedProvider) { public SpeedChangingAudioProcessor(SpeedProvider speedProvider) {
this.speedProvider = speedProvider; this.speedProvider = speedProvider;
@ -74,6 +78,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
inputSegmentStartTimesUs.add(0); inputSegmentStartTimesUs.add(0);
outputSegmentStartTimesUs.add(0); outputSegmentStartTimesUs.add(0);
currentSpeed = 1f; currentSpeed = 1f;
speedAdjustedTimeAsyncInputTimeUs = C.TIME_UNSET;
} }
@Override @Override
@ -143,7 +148,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
buffer.flip(); buffer.flip();
} }
bytesRead += inputBuffer.position() - startPosition; bytesRead += inputBuffer.position() - startPosition;
lastProcessedInputTime = updateLastProcessedInputTime(); lastProcessedInputTimeUs = updateLastProcessedInputTime();
inputBuffer.limit(inputBufferLimit); inputBuffer.limit(inputBufferLimit);
} }
@ -200,8 +205,11 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
* from the caller of this method. * from the caller of this method.
*/ */
public void getSpeedAdjustedTimeAsync(long inputTimeUs, LongConsumer callback) { public void getSpeedAdjustedTimeAsync(long inputTimeUs, LongConsumer callback) {
checkArgument(speedAdjustedTimeAsyncInputTimeUs < inputTimeUs);
speedAdjustedTimeAsyncInputTimeUs = inputTimeUs;
synchronized (pendingCallbacksLock) { synchronized (pendingCallbacksLock) {
if (inputTimeUs <= lastProcessedInputTime || isEnded()) { if ((inputTimeUs <= lastProcessedInputTimeUs && pendingCallbackInputTimesUs.isEmpty())
|| isEnded()) {
callback.accept(calculateSpeedAdjustedTime(inputTimeUs)); callback.accept(calculateSpeedAdjustedTime(inputTimeUs));
return; return;
} }
@ -219,11 +227,16 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
while (floorIndex > 0 && inputSegmentStartTimesUs.get(floorIndex) > inputTimeUs) { while (floorIndex > 0 && inputSegmentStartTimesUs.get(floorIndex) > inputTimeUs) {
floorIndex--; floorIndex--;
} }
long lastSegmentInputDuration = inputTimeUs - inputSegmentStartTimesUs.get(floorIndex);
long lastSegmentOutputDuration; long lastSegmentOutputDuration;
if (floorIndex == inputSegmentStartTimesUs.size() - 1) { if (floorIndex == inputSegmentStartTimesUs.size() - 1) {
if (lastSpeedAdjustedInputTimeUs < inputSegmentStartTimesUs.get(floorIndex)) {
lastSpeedAdjustedInputTimeUs = inputSegmentStartTimesUs.get(floorIndex);
lastSpeedAdjustedOutputTimeUs = outputSegmentStartTimesUs.get(floorIndex);
}
long lastSegmentInputDuration = inputTimeUs - lastSpeedAdjustedInputTimeUs;
lastSegmentOutputDuration = getPlayoutDurationAtCurrentSpeed(lastSegmentInputDuration); lastSegmentOutputDuration = getPlayoutDurationAtCurrentSpeed(lastSegmentInputDuration);
} else { } else {
long lastSegmentInputDuration = inputTimeUs - lastSpeedAdjustedInputTimeUs;
lastSegmentOutputDuration = lastSegmentOutputDuration =
round( round(
lastSegmentInputDuration lastSegmentInputDuration
@ -233,7 +246,9 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
inputSegmentStartTimesUs.get(floorIndex + 1) inputSegmentStartTimesUs.get(floorIndex + 1)
- inputSegmentStartTimesUs.get(floorIndex))); - inputSegmentStartTimesUs.get(floorIndex)));
} }
return outputSegmentStartTimesUs.get(floorIndex) + lastSegmentOutputDuration; lastSpeedAdjustedInputTimeUs = inputTimeUs;
lastSpeedAdjustedOutputTimeUs += lastSegmentOutputDuration;
return lastSpeedAdjustedOutputTimeUs;
} }
private static double divide(long dividend, long divisor) { private static double divide(long dividend, long divisor) {
@ -243,7 +258,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
private void processPendingCallbacks() { private void processPendingCallbacks() {
synchronized (pendingCallbacksLock) { synchronized (pendingCallbacksLock) {
while (!pendingCallbacks.isEmpty() while (!pendingCallbacks.isEmpty()
&& (pendingCallbackInputTimesUs.element() <= lastProcessedInputTime || isEnded())) { && (pendingCallbackInputTimesUs.element() <= lastProcessedInputTimeUs || isEnded())) {
pendingCallbacks pendingCallbacks
.remove() .remove()
.accept(calculateSpeedAdjustedTime(pendingCallbackInputTimesUs.remove())); .accept(calculateSpeedAdjustedTime(pendingCallbackInputTimesUs.remove()));