diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/MuxerWrapper.java b/libraries/transformer/src/main/java/androidx/media3/transformer/MuxerWrapper.java index d2bb5e87b1..9f06756cda 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/MuxerWrapper.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/MuxerWrapper.java @@ -32,7 +32,6 @@ import static androidx.media3.effect.DebugTraceUtil.EVENT_OUTPUT_ENDED; import static java.lang.Math.max; import static java.lang.Math.min; import static java.lang.annotation.ElementType.TYPE_USE; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import android.media.MediaCodec.BufferInfo; import android.util.SparseArray; @@ -61,8 +60,6 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import org.checkerframework.checker.nullness.qual.EnsuresNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @@ -130,14 +127,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** Muxer is released after an error occurred during the export. */ public static final int MUXER_RELEASE_REASON_ERROR = 2; - private static final String TIMER_THREAD_NAME = "Muxer:Timer"; - private static final String MUXER_TIMEOUT_ERROR_FORMAT_STRING = - "Abort: no output sample written in the last %d milliseconds. DebugTrace: %s"; - public interface Listener { void onTrackEnded( @C.TrackType int trackType, Format format, int averageBitrate, int sampleCount); + void onSampleWrittenOrDropped(); + void onEnded(long durationMs, long fileSizeBytes); void onError(ExportException exportException); @@ -156,9 +151,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final Listener listener; private final boolean dropSamplesBeforeFirstVideoSample; private final SparseArray trackTypeToInfo; - private final ScheduledExecutorService abortScheduledExecutorService; @Nullable private final Format appendVideoFormat; - private final long maxDelayBetweenSamplesMs; private final BufferInfo bufferInfo; private boolean isReady; @@ -167,8 +160,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private long minTrackTimeUs; private long minEndedTrackTimeUs; private long maxEndedTrackTimeUs; - private @MonotonicNonNull ScheduledFuture abortScheduledFuture; - private boolean isAborted; private @MonotonicNonNull Muxer muxer; private @MuxerMode int muxerMode; private boolean muxedPartialVideo; @@ -193,8 +184,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; * presentation timestamps before the first video sample. * @param appendVideoFormat The format which will be used to write samples after transitioning * from {@link #MUXER_MODE_MUX_PARTIAL} to {@link #MUXER_MODE_APPEND}. - * @param maxDelayBetweenSamplesMs The maximum delay allowed between output samples regardless of - * the track type, or {@link C#TIME_UNSET} if there is no maximum. */ public MuxerWrapper( String outputPath, @@ -202,8 +191,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; Listener listener, @MuxerMode int muxerMode, boolean dropSamplesBeforeFirstVideoSample, - @Nullable Format appendVideoFormat, - long maxDelayBetweenSamplesMs) { + @Nullable Format appendVideoFormat) { this.outputPath = outputPath; this.muxerFactory = muxerFactory; this.listener = listener; @@ -215,12 +203,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; || (muxerMode == MUXER_MODE_MUX_PARTIAL && appendVideoFormat != null), "appendVideoFormat must be present if and only if muxerMode is MUXER_MODE_MUX_PARTIAL."); this.appendVideoFormat = appendVideoFormat; - this.maxDelayBetweenSamplesMs = maxDelayBetweenSamplesMs; trackTypeToInfo = new SparseArray<>(); previousTrackType = C.TRACK_TYPE_NONE; firstVideoPresentationTimeUs = C.TIME_UNSET; minEndedTrackTimeUs = Long.MAX_VALUE; - abortScheduledExecutorService = Util.newSingleThreadScheduledExecutor(TIMER_THREAD_NAME); bufferInfo = new BufferInfo(); } @@ -474,7 +460,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; throw new AppendTrackFormatException("Audio format mismatch - initializationData."); } } - resetAbortTimer(); return; } @@ -503,7 +488,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; if (trackTypeToInfo.size() == trackCount) { isReady = true; - resetAbortTimer(); } } @@ -560,7 +544,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; && firstVideoPresentationTimeUs != C.TIME_UNSET && presentationTimeUs < firstVideoPresentationTimeUs) { // Drop the buffer. - resetAbortTimer(); + listener.onSampleWrittenOrDropped(); return true; } } @@ -589,8 +573,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; trackInfo.sampleCount++; trackInfo.bytesWritten += data.remaining(); trackInfo.timeUs = max(trackInfo.timeUs, presentationTimeUs); - - resetAbortTimer(); + listener.onSampleWrittenOrDropped(); checkStateNotNull(muxer); bufferInfo.set( data.position(), @@ -651,15 +634,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; && muxedPartialVideo && (muxedPartialAudio || trackCount == 1)) { listener.onEnded(durationMs, getCurrentOutputSizeBytes()); - if (abortScheduledFuture != null) { - abortScheduledFuture.cancel(/* mayInterruptIfRunning= */ false); - } return; } if (isEnded) { listener.onEnded(durationMs, getCurrentOutputSizeBytes()); - abortScheduledExecutorService.shutdownNow(); } } @@ -695,7 +674,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; return; } isReady = false; - abortScheduledExecutorService.shutdownNow(); if (muxer != null) { try { muxer.close(); @@ -740,34 +718,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; return presentationTimeUs - minTrackTimeUs <= MAX_TRACK_WRITE_AHEAD_US; } - private void resetAbortTimer() { - checkStateNotNull(muxer); - if (maxDelayBetweenSamplesMs == C.TIME_UNSET) { - return; - } - if (abortScheduledFuture != null) { - abortScheduledFuture.cancel(/* mayInterruptIfRunning= */ false); - } - abortScheduledFuture = - abortScheduledExecutorService.schedule( - () -> { - if (isAborted) { - return; - } - isAborted = true; - listener.onError( - ExportException.createForMuxer( - new IllegalStateException( - Util.formatInvariant( - MUXER_TIMEOUT_ERROR_FORMAT_STRING, - maxDelayBetweenSamplesMs, - DebugTraceUtil.generateTraceSummary())), - ExportException.ERROR_CODE_MUXING_TIMEOUT)); - }, - maxDelayBetweenSamplesMs, - MILLISECONDS); - } - @EnsuresNonNull("muxer") private void ensureMuxerInitialized() throws MuxerException { if (muxer == null) { diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java index 3c23de2965..ee029a1103 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java @@ -653,7 +653,7 @@ public final class Transformer { * between output samples}. */ public static final long DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS = - isRunningOnEmulator() ? 21_000 : 10_000; + isRunningOnEmulator() ? 25_000 : 10_000; @Documented @Retention(RetentionPolicy.SOURCE) @@ -761,6 +761,7 @@ public final class Transformer { getResumeMetadataFuture; private @MonotonicNonNull ListenableFuture copyOutputFuture; @Nullable private Mp4Info mediaItemInfo; + @Nullable private WatchdogTimer exportWatchdogTimer; private Transformer( Context context, @@ -927,8 +928,7 @@ public final class Transformer { componentListener, MuxerWrapper.MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ fileStartsOnVideoFrameEnabled, - /* appendVideoFormat= */ null, - maxDelayBetweenMuxerSamplesMs), + /* appendVideoFormat= */ null), componentListener, /* initialTimestampOffsetUs= */ 0, /* useDefaultAssetLoaderFactory= */ false); @@ -1144,6 +1144,7 @@ public final class Transformer { public void cancel() { verifyApplicationThread(); if (transformerInternal == null) { + maybeStopExportWatchdogTimer(); return; } try { @@ -1158,6 +1159,7 @@ public final class Transformer { if (copyOutputFuture != null && !copyOutputFuture.isDone()) { copyOutputFuture.cancel(/* mayInterruptIfRunning= */ false); } + maybeStopExportWatchdogTimer(); } /** @@ -1187,7 +1189,37 @@ public final class Transformer { remuxProcessedVideo(); } + private void maybeInitializeExportWatchdogTimer() { + if (maxDelayBetweenMuxerSamplesMs == C.TIME_UNSET) { + return; + } + exportWatchdogTimer = + new WatchdogTimer( + maxDelayBetweenMuxerSamplesMs, + () -> { + ExportException exportException = + ExportException.createForMuxer( + new IllegalStateException( + Util.formatInvariant( + "Abort: no output sample written in the last %d milliseconds." + + " DebugTrace: %s", + maxDelayBetweenMuxerSamplesMs, + DebugTraceUtil.generateTraceSummary())), + ExportException.ERROR_CODE_MUXING_TIMEOUT); + checkNotNull(transformerInternal).endWithException(exportException); + }); + exportWatchdogTimer.start(); + } + + private void maybeStopExportWatchdogTimer() { + if (exportWatchdogTimer != null) { + exportWatchdogTimer.stop(); + exportWatchdogTimer = null; + } + } + private void initialize(Composition composition, String outputFilePath) { + maybeInitializeExportWatchdogTimer(); this.composition = composition; this.outputFilePath = outputFilePath; exportResultBuilder.reset(); @@ -1203,8 +1235,7 @@ public final class Transformer { componentListener, MuxerWrapper.MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - maxDelayBetweenMuxerSamplesMs), + /* appendVideoFormat= */ null), componentListener, /* initialTimestampOffsetUs= */ 0, /* useDefaultAssetLoaderFactory= */ false); @@ -1237,8 +1268,7 @@ public final class Transformer { componentListener, MuxerWrapper.MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ resumeMetadata.videoFormat, - maxDelayBetweenMuxerSamplesMs); + /* appendVideoFormat= */ resumeMetadata.videoFormat); startInternal( TransmuxTranscodeHelper.createVideoOnlyComposition( @@ -1289,8 +1319,7 @@ public final class Transformer { componentListener, MuxerWrapper.MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - maxDelayBetweenMuxerSamplesMs); + /* appendVideoFormat= */ null); startInternal( TransmuxTranscodeHelper.createAudioTranscodeAndVideoTransmuxComposition( @@ -1407,8 +1436,7 @@ public final class Transformer { componentListener, MuxerWrapper.MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - mp4Info.videoFormat, - maxDelayBetweenMuxerSamplesMs); + mp4Info.videoFormat); if (shouldTranscodeVideo( checkNotNull(mp4Info.videoFormat), composition, @@ -1541,6 +1569,7 @@ public final class Transformer { } private void onExportCompletedWithSuccess() { + maybeStopExportWatchdogTimer(); listeners.queueEvent( /* eventFlag= */ C.INDEX_UNSET, listener -> listener.onCompleted(checkNotNull(composition), exportResultBuilder.build())); @@ -1549,6 +1578,7 @@ public final class Transformer { } private void onExportCompletedWithError(ExportException exception) { + maybeStopExportWatchdogTimer(); listeners.queueEvent( /* eventFlag= */ C.INDEX_UNSET, listener -> @@ -1661,6 +1691,15 @@ public final class Transformer { } } + @Override + public void onSampleWrittenOrDropped() { + if (exportWatchdogTimer != null) { + exportWatchdogTimer.reset(); + } else { + checkState(maxDelayBetweenMuxerSamplesMs == C.TIME_UNSET); + } + } + @Override public void onEnded(long durationMs, long fileSizeBytes) { exportResultBuilder.setDurationMs(durationMs).setFileSizeBytes(fileSizeBytes); diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/WatchdogTimer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/WatchdogTimer.java new file mode 100644 index 0000000000..8edb9b5ba9 --- /dev/null +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/WatchdogTimer.java @@ -0,0 +1,92 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.transformer; + +import static androidx.media3.common.util.Assertions.checkNotNull; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import androidx.media3.common.util.Util; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +/** + * A watchdog timer. + * + *

Callers must follow this sequence: + * + *

+ */ +/* package */ final class WatchdogTimer { + /** A listener for timeout events. */ + public interface Listener { + /** Called when a timeout occurs. */ + void onTimeout(); + } + + private final long timeoutDurationMs; + private final Listener listener; + private final ScheduledExecutorService watchdogScheduledExecutorService; + + private @MonotonicNonNull ScheduledFuture timeoutScheduledFuture; + + /** + * Creates an instance. + * + * @param timeoutDurationMs The timeout duration in milliseconds. + * @param listener The {@link Listener} to be notified when a timeout occurs. + */ + public WatchdogTimer(long timeoutDurationMs, Listener listener) { + this.timeoutDurationMs = timeoutDurationMs; + this.listener = listener; + watchdogScheduledExecutorService = Util.newSingleThreadScheduledExecutor("WatchdogTimer"); + } + + /** Starts the watchdog timer. */ + public void start() { + scheduleNewTimer(); + } + + /** Resets the watchdog timer. */ + public void reset() { + cancelExistingTimer(); + scheduleNewTimer(); + } + + /** + * Stops the watchdog timer. + * + *

The watchdog timer can not be used after its stopped. + */ + public void stop() { + cancelExistingTimer(); + watchdogScheduledExecutorService.shutdownNow(); + } + + private void cancelExistingTimer() { + checkNotNull(timeoutScheduledFuture).cancel(/* mayInterruptIfRunning= */ false); + } + + private void scheduleNewTimer() { + timeoutScheduledFuture = + watchdogScheduledExecutorService.schedule( + listener::onTimeout, timeoutDurationMs, MILLISECONDS); + } +} diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/EncodedSampleExporterTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/EncodedSampleExporterTest.java index cbf9dda85f..b81ae93a95 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/EncodedSampleExporterTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/EncodedSampleExporterTest.java @@ -70,8 +70,7 @@ public final class EncodedSampleExporterTest { mock(MuxerWrapper.Listener.class), MuxerWrapper.MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS), + /* appendVideoFormat= */ null), fallbackListener, /* initialTimestampOffsetUs= */ 0); } diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/MuxerWrapperTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/MuxerWrapperTest.java index a175cb1fe2..c1aa9032e0 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/MuxerWrapperTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/MuxerWrapperTest.java @@ -92,8 +92,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); muxerWrapper.setAdditionalRotationDegrees(90); muxerWrapper.setTrackCount(1); muxerWrapper.setAdditionalRotationDegrees(180); @@ -111,8 +110,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); muxerWrapper.setAdditionalRotationDegrees(90); muxerWrapper.setTrackCount(1); muxerWrapper.setAdditionalRotationDegrees(180); @@ -130,8 +128,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); assertThrows(IllegalStateException.class, muxerWrapper::changeToAppendMode); } @@ -148,8 +145,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS)); + /* appendVideoFormat= */ null)); } @Test @@ -161,8 +157,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); @@ -185,8 +180,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_AUDIO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -209,8 +203,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ differentVideoFormat, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ differentVideoFormat); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -245,8 +238,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ differentVideoFormat, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ differentVideoFormat); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -272,8 +264,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_AUDIO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -300,8 +291,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ true, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); muxerWrapper.setTrackCount(2); muxerWrapper.addTrackFormat(FAKE_AUDIO_TRACK_FORMAT); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); @@ -329,8 +319,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ true, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); muxerWrapper.setTrackCount(2); muxerWrapper.addTrackFormat(FAKE_AUDIO_TRACK_FORMAT); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); @@ -369,8 +358,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -391,8 +379,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(2); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); @@ -421,8 +408,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -579,8 +565,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -606,8 +591,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -632,8 +616,7 @@ public class MuxerWrapperTest { new NoOpMuxerListenerImpl(), MUXER_MODE_MUX_PARTIAL, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.setTrackCount(1); muxerWrapper.addTrackFormat(FAKE_VIDEO_TRACK_FORMAT); muxerWrapper.writeSample( @@ -655,6 +638,9 @@ public class MuxerWrapperTest { public void onTrackEnded( @C.TrackType int trackType, Format format, int averageBitrate, int sampleCount) {} + @Override + public void onSampleWrittenOrDropped() {} + @Override public void onEnded(long durationMs, long fileSizeBytes) {} diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerUtilTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerUtilTest.java index 3b2814c5c3..62d202f85e 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerUtilTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerUtilTest.java @@ -72,8 +72,7 @@ public final class TransformerUtilTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); assertThat( shouldTranscodeVideo( @@ -107,8 +106,7 @@ public final class TransformerUtilTest { new NoOpMuxerListenerImpl(), MUXER_MODE_DEFAULT, /* dropSamplesBeforeFirstVideoSample= */ false, - /* appendVideoFormat= */ null, - Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS); + /* appendVideoFormat= */ null); assertThat( shouldTranscodeVideo( @@ -127,6 +125,9 @@ public final class TransformerUtilTest { public void onTrackEnded( @C.TrackType int trackType, Format format, int averageBitrate, int sampleCount) {} + @Override + public void onSampleWrittenOrDropped() {} + @Override public void onEnded(long durationMs, long fileSizeBytes) {}