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 26852f38b2..5e62497dee 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 @@ -17,6 +17,7 @@ package androidx.media3.common.audio; import static java.lang.Math.min; +import static java.lang.Math.round; import androidx.media3.common.C; import androidx.media3.common.util.LongArray; @@ -210,17 +211,26 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor { floorIndex--; } long lastSegmentInputDuration = inputTimeUs - inputSegmentStartTimesUs.get(floorIndex); - long lastSegmentOutputDuration = - floorIndex == inputSegmentStartTimesUs.size() - 1 - ? getPlayoutDurationAtCurrentSpeed(lastSegmentInputDuration) - : lastSegmentInputDuration - * (inputSegmentStartTimesUs.get(floorIndex + 1) - - inputSegmentStartTimesUs.get(floorIndex)) - / (outputSegmentStartTimesUs.get(floorIndex + 1) - - outputSegmentStartTimesUs.get(floorIndex)); + long lastSegmentOutputDuration; + if (floorIndex == inputSegmentStartTimesUs.size() - 1) { + lastSegmentOutputDuration = getPlayoutDurationAtCurrentSpeed(lastSegmentInputDuration); + } else { + lastSegmentOutputDuration = + round( + lastSegmentInputDuration + * divide( + outputSegmentStartTimesUs.get(floorIndex + 1) + - outputSegmentStartTimesUs.get(floorIndex), + inputSegmentStartTimesUs.get(floorIndex + 1) + - inputSegmentStartTimesUs.get(floorIndex))); + } return outputSegmentStartTimesUs.get(floorIndex) + lastSegmentOutputDuration; } + private static double divide(long dividend, long divisor) { + return ((double) dividend) / divisor; + } + private void processPendingCallbacks() { synchronized (pendingCallbacksLock) { while (!pendingCallbacks.isEmpty() diff --git a/libraries/common/src/test/java/androidx/media3/common/audio/SpeedChangingAudioProcessorTest.java b/libraries/common/src/test/java/androidx/media3/common/audio/SpeedChangingAudioProcessorTest.java index 74caffbe42..84ee57bae4 100644 --- a/libraries/common/src/test/java/androidx/media3/common/audio/SpeedChangingAudioProcessorTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/audio/SpeedChangingAudioProcessorTest.java @@ -357,7 +357,7 @@ public class SpeedChangingAudioProcessorTest { // The speed change is at 113Us (5*MICROS_PER_SECOND/sampleRate). SpeedProvider speedProvider = TestSpeedProvider.createWithFrameCounts( - AUDIO_FORMAT, /* frameCounts= */ new int[] {5, 5}, /* speeds= */ new float[] {1, 2}); + AUDIO_FORMAT, /* frameCounts= */ new int[] {5, 5}, /* speeds= */ new float[] {2, 1}); SpeedChangingAudioProcessor speedChangingAudioProcessor = getConfiguredSpeedChangingAudioProcessor(speedProvider); ByteBuffer inputBuffer = getInputBuffer(/* frameCount= */ 5); @@ -374,7 +374,8 @@ public class SpeedChangingAudioProcessorTest { speedChangingAudioProcessor.getSpeedAdjustedTimeAsync( /* inputTimeUs= */ 150L, outputTimesUs::add); - assertThat(outputTimesUs).containsExactly(50L, 100L, 131L); + // 150 is after the speed change so floor(113 / 2 + (150 - 113)*1) -> 93 + assertThat(outputTimesUs).containsExactly(25L, 50L, 93L); } private static SpeedChangingAudioProcessor getConfiguredSpeedChangingAudioProcessor(