mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Start muxer watchdog timer on export start
Earlier watchdog timer was started only after all the tracks are
added. For the cases where export is stuck before adding tracks,
the export would hang forever and will not timeout automatically.
With the changes, watchdog timer is started as soon as export is
started/resumed. Now if the pipeline is stuck before writing any samples,
it will timeout and report error to the caller.
Existing test case: c35a9d62ba/libraries/transformer/src/test/java/androidx/media3/transformer/MediaItemExportTest.java (L996)
PiperOrigin-RevId: 695781654
This commit is contained in:
parent
19b38c83b6
commit
59106bba1c
@ -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<TrackInfo> 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) {
|
||||
|
@ -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<Void> 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);
|
||||
|
@ -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.
|
||||
*
|
||||
* <p>Callers must follow this sequence:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Call {@link #start()} once to start the timer.
|
||||
* <li>Call {@link #reset()} periodically to reset the timer and prevent a timeout.
|
||||
* <li>Call {@link #stop()} once to stop the timer.
|
||||
* </ul>
|
||||
*/
|
||||
/* 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.
|
||||
*
|
||||
* <p>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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
||||
|
@ -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) {}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user