mirror of
https://github.com/androidx/media.git
synced 2025-05-17 12:39:52 +08:00
Add test to catch single asset audio sequence underruns
This test previews a composition containing only a single audio asset
sequence. The audio asset is a 1s, stereo, locally available WAV file.
Catching an underrun in this test is a likely indication of something
being seriously wrong with the device's state or a performance
regression on the audio pipeline.
This test is a verification of the fix in 2e20d35c3d
. Without this fix
the newly added test fails because MediaCodecAudioRenderer attempts to
use dynamic scheduling with AudioGraphInputAudioSync
(which is unsupported) after EoS is signalled.
PiperOrigin-RevId: 753552825
This commit is contained in:
parent
e06e9b4cc9
commit
bd24ec08d1
@ -35,11 +35,14 @@ import androidx.media3.common.PlaybackException;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.util.NullableType;
|
||||
import androidx.media3.effect.GlEffect;
|
||||
import androidx.media3.exoplayer.audio.AudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.junit.After;
|
||||
@ -504,6 +507,45 @@ public class CompositionPlaybackTest {
|
||||
.isEqualTo(expectedTimestampsUs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playback_singleAssetAudioSequence_doesNotUnderrun()
|
||||
throws PlaybackException, TimeoutException {
|
||||
EditedMediaItem clip =
|
||||
new EditedMediaItem.Builder(MediaItem.fromUri(AndroidTestUtil.WAV_ASSET.uri))
|
||||
.setDurationUs(1_000_000L)
|
||||
.build();
|
||||
Composition composition =
|
||||
new Composition.Builder(new EditedMediaItemSequence.Builder(clip).build()).build();
|
||||
AtomicInteger underrunCount = new AtomicInteger();
|
||||
AudioSink.Listener sinkListener =
|
||||
new AudioSink.Listener() {
|
||||
@Override
|
||||
public void onPositionDiscontinuity() {}
|
||||
|
||||
@Override
|
||||
public void onUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
|
||||
underrunCount.addAndGet(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {}
|
||||
};
|
||||
AudioSink sink = new DefaultAudioSink.Builder(context).build();
|
||||
sink.setListener(sinkListener);
|
||||
|
||||
getInstrumentation()
|
||||
.runOnMainSync(
|
||||
() -> {
|
||||
player = new CompositionPlayer.Builder(context).setAudioSink(sink).build();
|
||||
player.addListener(playerTestListener);
|
||||
player.setComposition(composition);
|
||||
player.prepare();
|
||||
player.play();
|
||||
});
|
||||
playerTestListener.waitUntilPlayerEnded();
|
||||
assertThat(underrunCount.get()).isEqualTo(0);
|
||||
}
|
||||
|
||||
private void runCompositionPlayer(Composition composition)
|
||||
throws PlaybackException, TimeoutException {
|
||||
runCompositionPlayer(composition, /* videoPrewarmingEnabled= */ true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user