Throw when the video track disappears during export
Throw when the output has a video track but the current MediaItem in the sequence doesn't have any video. PiperOrigin-RevId: 512004463
This commit is contained in:
parent
672d7494f2
commit
c2fd7339e1
@ -17,6 +17,7 @@ package androidx.media3.transformer;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_AVAILABLE;
|
||||
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_NOT_STARTED;
|
||||
@ -52,8 +53,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
private final AssetLoader.Factory assetLoaderFactory;
|
||||
private final HandlerWrapper handler;
|
||||
private final Listener compositeAssetLoaderListener;
|
||||
/**
|
||||
* A mapping from track types to {@link SampleConsumer} instances.
|
||||
*
|
||||
* <p>This map never contains more than 2 entries, as the only track types allowed are audio and
|
||||
* video.
|
||||
*/
|
||||
private final Map<Integer, SampleConsumer> sampleConsumersByTrackType;
|
||||
/**
|
||||
* A mapping from track types to {@link OnMediaItemChangedListener} instances.
|
||||
*
|
||||
* <p>This map never contains more than 2 entries, as the only track types allowed are audio and
|
||||
* video.
|
||||
*/
|
||||
private final Map<Integer, OnMediaItemChangedListener> mediaItemChangedListenersByTrackType;
|
||||
|
||||
private final ImmutableList.Builder<ExportResult.ProcessedInput> processedInputsBuilder;
|
||||
private final AtomicInteger nonEndedTracks;
|
||||
|
||||
@ -133,10 +147,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
*
|
||||
* @param onMediaItemChangedListener The {@link OnMediaItemChangedListener}.
|
||||
* @param trackType The {@link C.TrackType} for which to listen to {@link MediaItem} change
|
||||
* events.
|
||||
* events. Must be {@link C#TRACK_TYPE_AUDIO} or {@link C#TRACK_TYPE_VIDEO}.
|
||||
*/
|
||||
public void addOnMediaItemChangedListener(
|
||||
OnMediaItemChangedListener onMediaItemChangedListener, @C.TrackType int trackType) {
|
||||
checkArgument(trackType == C.TRACK_TYPE_AUDIO || trackType == C.TRACK_TYPE_VIDEO);
|
||||
checkArgument(mediaItemChangedListenersByTrackType.get(trackType) == null);
|
||||
mediaItemChangedListenersByTrackType.put(trackType, onMediaItemChangedListener);
|
||||
}
|
||||
@ -172,19 +187,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
long streamStartPositionUs,
|
||||
long streamOffsetUs)
|
||||
throws ExportException {
|
||||
int trackType = MimeTypes.getTrackType(format.sampleMimeType);
|
||||
// Consider image as video because image inputs are fed to the VideoSamplePipeline.
|
||||
int trackType =
|
||||
MimeTypes.isAudio(format.sampleMimeType) ? C.TRACK_TYPE_AUDIO : C.TRACK_TYPE_VIDEO;
|
||||
SampleConsumer sampleConsumer;
|
||||
if (currentMediaItemIndex.get() == 0) {
|
||||
boolean addAudioTrack =
|
||||
boolean addForcedAudioTrack =
|
||||
forceAudioTrack && nonEndedTracks.get() == 1 && trackType == C.TRACK_TYPE_VIDEO;
|
||||
int trackCount = nonEndedTracks.get() + (addAudioTrack ? 1 : 0);
|
||||
int trackCount = nonEndedTracks.get() + (addForcedAudioTrack ? 1 : 0);
|
||||
compositeAssetLoaderListener.onTrackCount(trackCount);
|
||||
sampleConsumer =
|
||||
new SampleConsumerWrapper(
|
||||
compositeAssetLoaderListener.onTrackAdded(
|
||||
format, supportedOutputTypes, streamStartPositionUs, streamOffsetUs));
|
||||
sampleConsumersByTrackType.put(trackType, sampleConsumer);
|
||||
if (addAudioTrack) {
|
||||
if (addForcedAudioTrack) {
|
||||
Format firstAudioFormat =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(MimeTypes.AUDIO_AAC)
|
||||
@ -201,6 +218,14 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
sampleConsumersByTrackType.put(C.TRACK_TYPE_AUDIO, audioSampleConsumer);
|
||||
}
|
||||
} else {
|
||||
// TODO(b/270533049): Remove the check below when implementing blank video frames generation.
|
||||
boolean videoTrackDisappeared =
|
||||
nonEndedTracks.get() == 1
|
||||
&& trackType == C.TRACK_TYPE_AUDIO
|
||||
&& sampleConsumersByTrackType.size() == 2;
|
||||
checkState(
|
||||
!videoTrackDisappeared,
|
||||
"Inputs with no video track are not supported when the output contains a video track");
|
||||
sampleConsumer =
|
||||
checkStateNotNull(
|
||||
sampleConsumersByTrackType.get(trackType),
|
||||
|
@ -367,7 +367,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
long streamStartPositionUs,
|
||||
long streamOffsetUs)
|
||||
throws ExportException {
|
||||
int trackType = MimeTypes.getTrackType(firstInputFormat.sampleMimeType);
|
||||
if (!trackAdded) {
|
||||
// Call setTrackCount() methods here so that they are called from the same thread as the
|
||||
// MuxerWrapper and FallbackListener methods called when building the sample pipelines.
|
||||
@ -383,6 +382,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
firstInputFormat, supportedOutputTypes, streamStartPositionUs, streamOffsetUs),
|
||||
streamStartPositionUs,
|
||||
streamOffsetUs);
|
||||
// Consider image as video because image inputs are fed to the VideoSamplePipeline.
|
||||
int trackType =
|
||||
MimeTypes.isAudio(firstInputFormat.sampleMimeType)
|
||||
? C.TRACK_TYPE_AUDIO
|
||||
: C.TRACK_TYPE_VIDEO;
|
||||
compositeAssetLoader.addOnMediaItemChangedListener(samplePipeline, trackType);
|
||||
internalHandler.obtainMessage(MSG_REGISTER_SAMPLE_PIPELINE, samplePipeline).sendToTarget();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user