Round bytesToNextSpeedChange up instead of down
Rounding down means that very small diferrences (e.g. 1 us) result in bytesToNextSpeedChange==0, which stalls progress forever as no new bytes are read. Rounding up instead ensures that we always read at least one audio frame if nextSpeedChangeTimeUs is in the future. PiperOrigin-RevId: 632116560
This commit is contained in:
parent
49fa343127
commit
971486f5f9
@ -27,6 +27,7 @@ import androidx.media3.common.util.SpeedProviderUtil;
|
||||
import androidx.media3.common.util.TimestampConsumer;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
@ -117,11 +118,12 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
||||
if (nextSpeedChangeTimeUs != C.TIME_UNSET) {
|
||||
bytesToNextSpeedChange =
|
||||
(int)
|
||||
Util.scaleLargeTimestamp(
|
||||
Util.scaleLargeValue(
|
||||
/* timestamp= */ nextSpeedChangeTimeUs - timeUs,
|
||||
/* multiplier= */ (long) inputAudioFormat.sampleRate
|
||||
* inputAudioFormat.bytesPerFrame,
|
||||
/* divisor= */ C.MICROS_PER_SECOND);
|
||||
/* divisor= */ C.MICROS_PER_SECOND,
|
||||
RoundingMode.CEILING);
|
||||
int bytesToNextFrame =
|
||||
inputAudioFormat.bytesPerFrame - bytesToNextSpeedChange % inputAudioFormat.bytesPerFrame;
|
||||
if (bytesToNextFrame != inputAudioFormat.bytesPerFrame) {
|
||||
|
@ -239,6 +239,25 @@ public class SpeedChangingAudioProcessorTest {
|
||||
assertThat(inputBuffer.limit()).isEqualTo(inputBufferLimit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queueInput_multipleSpeedsInBufferWithLimitVeryClose_readsDataUntilSpeedLimit()
|
||||
throws Exception {
|
||||
long speedChangeTimeUs = 1; // Change speed very close to current position at 1us.
|
||||
SpeedProvider speedProvider =
|
||||
TestSpeedProvider.createWithStartTimes(
|
||||
/* startTimesUs= */ new long[] {0L, speedChangeTimeUs},
|
||||
/* speeds= */ new float[] {1, 2});
|
||||
SpeedChangingAudioProcessor speedChangingAudioProcessor =
|
||||
getConfiguredSpeedChangingAudioProcessor(speedProvider);
|
||||
ByteBuffer inputBuffer = getInputBuffer(/* frameCount= */ 5);
|
||||
int inputBufferLimit = inputBuffer.limit();
|
||||
|
||||
speedChangingAudioProcessor.queueInput(inputBuffer);
|
||||
|
||||
assertThat(inputBuffer.position()).isEqualTo(AUDIO_FORMAT.bytesPerFrame);
|
||||
assertThat(inputBuffer.limit()).isEqualTo(inputBufferLimit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queueEndOfStream_afterNoSpeedChangeAndWithOutputRetrieved_endsProcessor()
|
||||
throws Exception {
|
||||
|
Loading…
x
Reference in New Issue
Block a user