From d652020229e36839f00387b55a64b4f8b4cf96cd Mon Sep 17 00:00:00 2001 From: kimvde Date: Thu, 27 Oct 2022 18:01:11 +0000 Subject: [PATCH] Add test for muxer watchdog timer PiperOrigin-RevId: 484298261 (cherry picked from commit 42057cc9f8f81e24c64c629d2e11e7102afd0f30) --- .../transformer/TransformerEndToEndTest.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java index 5500e46dc4..3a1816439b 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java @@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.media.MediaCrypto; import android.media.MediaFormat; +import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -42,6 +43,14 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.MediaItem; +import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; +import com.google.android.exoplayer2.extractor.Extractor; +import com.google.android.exoplayer2.extractor.ExtractorInput; +import com.google.android.exoplayer2.extractor.ExtractorOutput; +import com.google.android.exoplayer2.extractor.ExtractorsFactory; +import com.google.android.exoplayer2.extractor.PositionHolder; +import com.google.android.exoplayer2.source.DefaultMediaSourceFactory; +import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.testutil.DumpFileAsserts; import com.google.android.exoplayer2.testutil.FakeClock; import com.google.android.exoplayer2.util.MimeTypes; @@ -54,7 +63,9 @@ import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -477,6 +488,26 @@ public final class TransformerEndToEndTest { .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); } + @Test + public void startTransformation_withSlowOutputSampleRate_completesWithError() throws Exception { + MediaSource.Factory mediaSourceFactory = + new DefaultMediaSourceFactory( + context, new SlowExtractorsFactory(/* delayBetweenReadsMs= */ 10)); + Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ 1); + Transformer transformer = + createTransformerBuilder(/* enableFallback= */ false) + .setMediaSourceFactory(mediaSourceFactory) + .setMuxerFactory(muxerFactory) + .build(); + MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + + transformer.startTransformation(mediaItem, outputPath); + TransformationException exception = TransformerTestRunner.runUntilError(transformer); + + assertThat(exception).hasCauseThat().isInstanceOf(IllegalStateException.class); + assertThat(exception.errorCode).isEqualTo(TransformationException.ERROR_CODE_MUXING_FAILED); + } + @Test public void startTransformation_withUnsetMaxDelayBetweenSamples_completesSuccessfully() throws Exception { @@ -897,4 +928,73 @@ public final class TransformerEndToEndTest { return defaultMuxerFactory.getSupportedSampleMimeTypes(trackType); } } + + private static final class SlowExtractorsFactory implements ExtractorsFactory { + + private final long delayBetweenReadsMs; + private final ExtractorsFactory defaultExtractorsFactory; + + public SlowExtractorsFactory(long delayBetweenReadsMs) { + this.delayBetweenReadsMs = delayBetweenReadsMs; + this.defaultExtractorsFactory = new DefaultExtractorsFactory(); + } + + @Override + public Extractor[] createExtractors() { + return slowDownExtractors(defaultExtractorsFactory.createExtractors()); + } + + @Override + public Extractor[] createExtractors(Uri uri, Map> responseHeaders) { + return slowDownExtractors(defaultExtractorsFactory.createExtractors(uri, responseHeaders)); + } + + private Extractor[] slowDownExtractors(Extractor[] extractors) { + Extractor[] slowExtractors = new Extractor[extractors.length]; + Arrays.setAll(slowExtractors, i -> new SlowExtractor(extractors[i], delayBetweenReadsMs)); + return slowExtractors; + } + + private static final class SlowExtractor implements Extractor { + + private final Extractor extractor; + private final long delayBetweenReadsMs; + + public SlowExtractor(Extractor extractor, long delayBetweenReadsMs) { + this.extractor = extractor; + this.delayBetweenReadsMs = delayBetweenReadsMs; + } + + @Override + public boolean sniff(ExtractorInput input) throws IOException { + return extractor.sniff(input); + } + + @Override + public void init(ExtractorOutput output) { + extractor.init(output); + } + + @Override + public @ReadResult int read(ExtractorInput input, PositionHolder seekPosition) + throws IOException { + try { + Thread.sleep(delayBetweenReadsMs); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return extractor.read(input, seekPosition); + } + + @Override + public void seek(long position, long timeUs) { + extractor.seek(position, timeUs); + } + + @Override + public void release() { + extractor.release(); + } + } + } }