From 828f6d87f994da9f9d9da2393f107bffeb6cfc5b Mon Sep 17 00:00:00 2001 From: tofunmi Date: Wed, 27 Mar 2024 10:52:44 -0700 Subject: [PATCH] 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 --- .../audio/SpeedChangingAudioProcessor.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/audio/SpeedChangingAudioProcessor.java b/libraries/common/src/main/java/androidx/media3/common/audio/SpeedChangingAudioProcessor.java index 6226006122..987c30849a 100644 --- a/libraries/common/src/main/java/androidx/media3/common/audio/SpeedChangingAudioProcessor.java +++ b/libraries/common/src/main/java/androidx/media3/common/audio/SpeedChangingAudioProcessor.java @@ -16,6 +16,7 @@ package androidx.media3.common.audio; +import static androidx.media3.common.util.Assertions.checkArgument; import static java.lang.Math.min; import static java.lang.Math.round; @@ -60,8 +61,11 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { private float currentSpeed; private long bytesRead; - private long lastProcessedInputTime; + private long lastProcessedInputTimeUs; + private long lastSpeedAdjustedInputTimeUs; + private long lastSpeedAdjustedOutputTimeUs; private boolean endOfStreamQueuedToSonic; + private long speedAdjustedTimeAsyncInputTimeUs; public SpeedChangingAudioProcessor(SpeedProvider speedProvider) { this.speedProvider = speedProvider; @@ -74,6 +78,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { inputSegmentStartTimesUs.add(0); outputSegmentStartTimesUs.add(0); currentSpeed = 1f; + speedAdjustedTimeAsyncInputTimeUs = C.TIME_UNSET; } @Override @@ -143,7 +148,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { buffer.flip(); } bytesRead += inputBuffer.position() - startPosition; - lastProcessedInputTime = updateLastProcessedInputTime(); + lastProcessedInputTimeUs = updateLastProcessedInputTime(); inputBuffer.limit(inputBufferLimit); } @@ -200,8 +205,11 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { * from the caller of this method. */ public void getSpeedAdjustedTimeAsync(long inputTimeUs, LongConsumer callback) { + checkArgument(speedAdjustedTimeAsyncInputTimeUs < inputTimeUs); + speedAdjustedTimeAsyncInputTimeUs = inputTimeUs; synchronized (pendingCallbacksLock) { - if (inputTimeUs <= lastProcessedInputTime || isEnded()) { + if ((inputTimeUs <= lastProcessedInputTimeUs && pendingCallbackInputTimesUs.isEmpty()) + || isEnded()) { callback.accept(calculateSpeedAdjustedTime(inputTimeUs)); return; } @@ -219,11 +227,16 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { while (floorIndex > 0 && inputSegmentStartTimesUs.get(floorIndex) > inputTimeUs) { floorIndex--; } - long lastSegmentInputDuration = inputTimeUs - inputSegmentStartTimesUs.get(floorIndex); long lastSegmentOutputDuration; 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); } else { + long lastSegmentInputDuration = inputTimeUs - lastSpeedAdjustedInputTimeUs; lastSegmentOutputDuration = round( lastSegmentInputDuration @@ -233,7 +246,9 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { inputSegmentStartTimesUs.get(floorIndex + 1) - inputSegmentStartTimesUs.get(floorIndex))); } - return outputSegmentStartTimesUs.get(floorIndex) + lastSegmentOutputDuration; + lastSpeedAdjustedInputTimeUs = inputTimeUs; + lastSpeedAdjustedOutputTimeUs += lastSegmentOutputDuration; + return lastSpeedAdjustedOutputTimeUs; } private static double divide(long dividend, long divisor) { @@ -243,7 +258,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { private void processPendingCallbacks() { synchronized (pendingCallbacksLock) { while (!pendingCallbacks.isEmpty() - && (pendingCallbackInputTimesUs.element() <= lastProcessedInputTime || isEnded())) { + && (pendingCallbackInputTimesUs.element() <= lastProcessedInputTimeUs || isEnded())) { pendingCallbacks .remove() .accept(calculateSpeedAdjustedTime(pendingCallbackInputTimesUs.remove()));