mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Reduce flakiness for ServerSideAdInsertion±MediaSourceTest past SDK 30
PiperOrigin-RevId: 737631774
This commit is contained in:
parent
ff0a359e93
commit
4932300b9a
@ -57,6 +57,9 @@ import androidx.media3.exoplayer.FormatHolder;
|
||||
import androidx.media3.exoplayer.LoadingInfo;
|
||||
import androidx.media3.exoplayer.analytics.AnalyticsListener;
|
||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||
import androidx.media3.exoplayer.audio.AudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.media3.exoplayer.audio.TeeAudioProcessor;
|
||||
import androidx.media3.exoplayer.drm.DrmSessionEventListener;
|
||||
import androidx.media3.exoplayer.drm.DrmSessionManager;
|
||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||
@ -71,6 +74,7 @@ import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||
import androidx.media3.exoplayer.trackselection.FixedTrackSelection;
|
||||
import androidx.media3.exoplayer.upstream.Allocator;
|
||||
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
||||
import androidx.media3.test.utils.CapturingAudioSink;
|
||||
import androidx.media3.test.utils.CapturingRenderersFactory;
|
||||
import androidx.media3.test.utils.DumpFileAsserts;
|
||||
import androidx.media3.test.utils.FakeClock;
|
||||
@ -93,10 +97,8 @@ import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
/** Unit test for {@link ServerSideAdInsertionMediaSource}. */
|
||||
@Config(sdk = 30) // TODO: b/382017156 - Remove this when the tests pass on API 31+.
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class ServerSideAdInsertionMediaSourceTest {
|
||||
|
||||
@ -472,7 +474,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||
public void playbackWithNewlyInsertedAds_playsSuccessfulWithoutRendererResets() throws Exception {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
AtomicReference<Object> periodUid = new AtomicReference<>();
|
||||
CapturingRenderersFactory renderersFactory = new CapturingRenderersFactory(context);
|
||||
CapturingRenderersFactory renderersFactory =
|
||||
new CapturingRenderersFactory(context, DiscontinuitySkippingCapturingAudioSink.create());
|
||||
ExoPlayer player =
|
||||
new ExoPlayer.Builder(context, renderersFactory)
|
||||
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
|
||||
@ -552,7 +555,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||
throws Exception {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
AtomicReference<Object> periodUid = new AtomicReference<>();
|
||||
CapturingRenderersFactory renderersFactory = new CapturingRenderersFactory(context);
|
||||
CapturingRenderersFactory renderersFactory =
|
||||
new CapturingRenderersFactory(context, DiscontinuitySkippingCapturingAudioSink.create());
|
||||
ExoPlayer player =
|
||||
new ExoPlayer.Builder(context, renderersFactory)
|
||||
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
|
||||
@ -832,4 +836,29 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||
|
||||
assertThat(readSamples).containsExactly(0L, 200L, 400L, 600L, 800L).inOrder();
|
||||
}
|
||||
|
||||
private static final class DiscontinuitySkippingCapturingAudioSink extends CapturingAudioSink {
|
||||
/** Creates the capturing audio sink that skips dumping discontinuity events. */
|
||||
public static DiscontinuitySkippingCapturingAudioSink create() {
|
||||
InterceptingBufferSink interceptingBufferSink = new InterceptingBufferSink();
|
||||
DiscontinuitySkippingCapturingAudioSink capturingAudioSink =
|
||||
new DiscontinuitySkippingCapturingAudioSink(
|
||||
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext())
|
||||
.setAudioProcessorChain(
|
||||
new DefaultAudioSink.DefaultAudioProcessorChain(
|
||||
new TeeAudioProcessor(interceptingBufferSink)))
|
||||
.build());
|
||||
interceptingBufferSink.setCapturingAudioSink(capturingAudioSink);
|
||||
return capturingAudioSink;
|
||||
}
|
||||
|
||||
private DiscontinuitySkippingCapturingAudioSink(AudioSink sink) {
|
||||
super(sink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDiscontinuity() {
|
||||
getDelegateAudioSink().handleDiscontinuity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -593,9 +593,6 @@ AudioSink:
|
||||
buffer #19:
|
||||
time = 1000000485179
|
||||
data = empty
|
||||
discontinuity:
|
||||
discontinuity:
|
||||
discontinuity:
|
||||
buffer #20:
|
||||
time = 1000000508399
|
||||
data = empty
|
||||
|
@ -620,9 +620,6 @@ AudioSink:
|
||||
buffer #28:
|
||||
time = 1000000694158
|
||||
data = empty
|
||||
discontinuity:
|
||||
discontinuity:
|
||||
discontinuity:
|
||||
buffer #29:
|
||||
time = 1000000717378
|
||||
data = empty
|
||||
@ -635,7 +632,6 @@ AudioSink:
|
||||
buffer #32:
|
||||
time = 1000000787038
|
||||
data = empty
|
||||
discontinuity:
|
||||
buffer #33:
|
||||
time = 1000000810258
|
||||
data = empty
|
||||
|
@ -41,9 +41,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
* discontinuity and buffer events.
|
||||
*/
|
||||
@UnstableApi
|
||||
public final class CapturingAudioSink extends ForwardingAudioSink implements Dumper.Dumpable {
|
||||
public class CapturingAudioSink extends ForwardingAudioSink implements Dumper.Dumpable {
|
||||
|
||||
private final List<Dumper.Dumpable> interceptedData;
|
||||
private final AudioSink audioSink;
|
||||
|
||||
private int bufferCount;
|
||||
private long lastPresentationTimeUs;
|
||||
@ -53,19 +54,26 @@ public final class CapturingAudioSink extends ForwardingAudioSink implements Dum
|
||||
/** Creates the capturing audio sink. */
|
||||
public static CapturingAudioSink create() {
|
||||
InterceptingBufferSink interceptingBufferSink = new InterceptingBufferSink();
|
||||
return new CapturingAudioSink(
|
||||
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext())
|
||||
.setAudioProcessorChain(
|
||||
new DefaultAudioSink.DefaultAudioProcessorChain(
|
||||
new TeeAudioProcessor(interceptingBufferSink)))
|
||||
.build(),
|
||||
interceptingBufferSink);
|
||||
CapturingAudioSink capturingAudioSink =
|
||||
new CapturingAudioSink(
|
||||
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext())
|
||||
.setAudioProcessorChain(
|
||||
new DefaultAudioSink.DefaultAudioProcessorChain(
|
||||
new TeeAudioProcessor(interceptingBufferSink)))
|
||||
.build());
|
||||
interceptingBufferSink.setCapturingAudioSink(capturingAudioSink);
|
||||
return capturingAudioSink;
|
||||
}
|
||||
|
||||
private CapturingAudioSink(AudioSink sink, InterceptingBufferSink interceptingBufferSink) {
|
||||
protected CapturingAudioSink(AudioSink sink) {
|
||||
super(sink);
|
||||
audioSink = sink;
|
||||
interceptedData = new ArrayList<>();
|
||||
interceptingBufferSink.setCapturingAudioSink(this);
|
||||
}
|
||||
|
||||
/** Returns the wrapped {@link AudioSink}. */
|
||||
protected final AudioSink getDelegateAudioSink() {
|
||||
return audioSink;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,7 +129,7 @@ public final class CapturingAudioSink extends ForwardingAudioSink implements Dum
|
||||
dumper.endBlock();
|
||||
}
|
||||
|
||||
private static final class InterceptingBufferSink implements TeeAudioProcessor.AudioBufferSink {
|
||||
public static final class InterceptingBufferSink implements TeeAudioProcessor.AudioBufferSink {
|
||||
|
||||
private @MonotonicNonNull CapturingAudioSink capturingAudioSink;
|
||||
private @MonotonicNonNull Format format;
|
||||
|
@ -86,9 +86,19 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
|
||||
* @param context The {@link Context}.
|
||||
*/
|
||||
public CapturingRenderersFactory(Context context) {
|
||||
this(context, CapturingAudioSink.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param context The {@link Context}.
|
||||
* @param capturingAudioSink The audio sink to use for capturing audio output.
|
||||
*/
|
||||
public CapturingRenderersFactory(Context context, CapturingAudioSink capturingAudioSink) {
|
||||
this.context = context;
|
||||
this.mediaCodecAdapterFactory = new CapturingMediaCodecAdapter.Factory(context);
|
||||
this.audioSink = CapturingAudioSink.create();
|
||||
this.audioSink = capturingAudioSink;
|
||||
this.imageOutput = new CapturingImageOutput();
|
||||
this.imageDecoderFactory = ImageDecoder.Factory.DEFAULT;
|
||||
this.textRendererFactory = TextRenderer::new;
|
||||
|
Loading…
x
Reference in New Issue
Block a user