SpeedChangingAudioProcessor: process all callbacks after audio ends
PiperOrigin-RevId: 616143969
This commit is contained in:
parent
b126bae93d
commit
b9843af6a0
@ -182,6 +182,9 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
||||
* <p>Calls {@linkplain LongConsumer#accept(long) the callback} with the output time as soon as
|
||||
* enough audio has been processed to calculate it.
|
||||
*
|
||||
* <p>If the audio processor has ended, speeds will come out at the last processed speed of the
|
||||
* audio processor.
|
||||
*
|
||||
* <p>Successive calls must have monotonically increasing {@code inputTimeUs}.
|
||||
*
|
||||
* <p>Can be called from any thread.
|
||||
@ -192,7 +195,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
||||
*/
|
||||
public void getSpeedAdjustedTimeAsync(long inputTimeUs, LongConsumer callback) {
|
||||
synchronized (pendingCallbacksLock) {
|
||||
if (inputTimeUs <= lastProcessedInputTime) {
|
||||
if (inputTimeUs <= lastProcessedInputTime || isEnded()) {
|
||||
callback.accept(calculateSpeedAdjustedTime(inputTimeUs));
|
||||
return;
|
||||
}
|
||||
@ -234,7 +237,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
||||
private void processPendingCallbacks() {
|
||||
synchronized (pendingCallbacksLock) {
|
||||
while (!pendingCallbacks.isEmpty()
|
||||
&& pendingCallbackInputTimesUs.element() <= lastProcessedInputTime) {
|
||||
&& (pendingCallbackInputTimesUs.element() <= lastProcessedInputTime || isEnded())) {
|
||||
pendingCallbacks
|
||||
.remove()
|
||||
.accept(calculateSpeedAdjustedTime(pendingCallbackInputTimesUs.remove()));
|
||||
|
@ -16,6 +16,7 @@
|
||||
package androidx.media3.common.audio;
|
||||
|
||||
import static androidx.media3.common.audio.AudioProcessor.EMPTY_BUFFER;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.media3.common.C;
|
||||
@ -378,6 +379,61 @@ public class SpeedChangingAudioProcessorTest {
|
||||
assertThat(outputTimesUs).containsExactly(25L, 50L, 93L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSpeedAdjustedTimeAsync_timeAfterEndTime_callbacksCalledWithCorrectParameters()
|
||||
throws Exception {
|
||||
ArrayList<Long> outputTimesUs = new ArrayList<>();
|
||||
// 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[] {2, 1});
|
||||
SpeedChangingAudioProcessor speedChangingAudioProcessor =
|
||||
getConfiguredSpeedChangingAudioProcessor(speedProvider);
|
||||
ByteBuffer inputBuffer = getInputBuffer(/* frameCount= */ 3);
|
||||
|
||||
speedChangingAudioProcessor.getSpeedAdjustedTimeAsync(
|
||||
/* inputTimeUs= */ 300L, outputTimesUs::add);
|
||||
speedChangingAudioProcessor.queueInput(inputBuffer);
|
||||
getAudioProcessorOutput(speedChangingAudioProcessor);
|
||||
inputBuffer.rewind();
|
||||
speedChangingAudioProcessor.queueInput(inputBuffer);
|
||||
getAudioProcessorOutput(speedChangingAudioProcessor);
|
||||
inputBuffer.rewind();
|
||||
speedChangingAudioProcessor.queueInput(inputBuffer);
|
||||
speedChangingAudioProcessor.queueEndOfStream();
|
||||
getAudioProcessorOutput(speedChangingAudioProcessor);
|
||||
|
||||
// 150 is after the speed change so floor(113 / 2 + (300 - 113)*1) -> 243
|
||||
assertThat(outputTimesUs).containsExactly(243L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
getSpeedAdjustedTimeAsync_timeAfterEndTimeAfterProcessorEnded_callbacksCalledWithCorrectParameters()
|
||||
throws Exception {
|
||||
ArrayList<Long> outputTimesUs = new ArrayList<>();
|
||||
// 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[] {2, 1});
|
||||
SpeedChangingAudioProcessor speedChangingAudioProcessor =
|
||||
getConfiguredSpeedChangingAudioProcessor(speedProvider);
|
||||
ByteBuffer inputBuffer = getInputBuffer(/* frameCount= */ 5);
|
||||
speedChangingAudioProcessor.queueInput(inputBuffer);
|
||||
getAudioProcessorOutput(speedChangingAudioProcessor);
|
||||
inputBuffer.rewind();
|
||||
speedChangingAudioProcessor.queueInput(inputBuffer);
|
||||
speedChangingAudioProcessor.queueEndOfStream();
|
||||
getAudioProcessorOutput(speedChangingAudioProcessor);
|
||||
checkState(speedChangingAudioProcessor.isEnded());
|
||||
|
||||
speedChangingAudioProcessor.getSpeedAdjustedTimeAsync(
|
||||
/* inputTimeUs= */ 300L, outputTimesUs::add);
|
||||
|
||||
// 150 is after the speed change so floor(113 / 2 + (300 - 113)*1) -> 243
|
||||
assertThat(outputTimesUs).containsExactly(243L);
|
||||
}
|
||||
|
||||
private static SpeedChangingAudioProcessor getConfiguredSpeedChangingAudioProcessor(
|
||||
SpeedProvider speedProvider) throws AudioProcessor.UnhandledAudioFormatException {
|
||||
SpeedChangingAudioProcessor speedChangingAudioProcessor =
|
||||
|
Loading…
x
Reference in New Issue
Block a user