Expand and refactor TransformerInternal#shouldTranscode.

* Account for `AssetLoader` output types.
* Consider cases that are not audio/video specific.
* Use `Format#sampleMimeType` for track specific conditions to check.
* Untangle `SamplePipeline` initilization from `AssetLoader` state.

PiperOrigin-RevId: 511020865
This commit is contained in:
samrobinson 2023-02-20 18:59:03 +00:00 committed by tonihei
parent 86dca78845
commit 37bb432869

View File

@ -16,6 +16,7 @@
package androidx.media3.transformer; package androidx.media3.transformer;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_DECODED; import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_DECODED;
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_ENCODED; import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_ENCODED;
@ -372,7 +373,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
SamplePipeline samplePipeline = SamplePipeline samplePipeline =
getSamplePipeline( getSamplePipeline(
firstInputFormat, supportedOutputTypes, streamStartPositionUs, streamOffsetUs); firstInputFormat,
shouldTranscode(
firstInputFormat, supportedOutputTypes, streamStartPositionUs, streamOffsetUs),
streamStartPositionUs,
streamOffsetUs);
compositeAssetLoader.addOnMediaItemChangedListener(samplePipeline, trackType); compositeAssetLoader.addOnMediaItemChangedListener(samplePipeline, trackType);
internalHandler.obtainMessage(MSG_REGISTER_SAMPLE_PIPELINE, samplePipeline).sendToTarget(); internalHandler.obtainMessage(MSG_REGISTER_SAMPLE_PIPELINE, samplePipeline).sendToTarget();
@ -421,59 +426,74 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private SamplePipeline getSamplePipeline( private SamplePipeline getSamplePipeline(
Format firstInputFormat, Format firstInputFormat,
@AssetLoader.SupportedOutputTypes int supportedOutputTypes, boolean shouldTranscode,
long streamStartPositionUs, long streamStartPositionUs,
long streamOffsetUs) long streamOffsetUs)
throws ExportException { throws ExportException {
checkState(supportedOutputTypes != 0); if (shouldTranscode) {
boolean isAudio = MimeTypes.isAudio(firstInputFormat.sampleMimeType); if (MimeTypes.isAudio(firstInputFormat.sampleMimeType)) {
boolean shouldTranscode; return new AudioSamplePipeline(
if (mediaItemCount > 1 && !transmux) { firstInputFormat,
streamStartPositionUs,
streamOffsetUs,
transformationRequest,
firstEditedMediaItem.flattenForSlowMotion,
firstEditedMediaItem.effects.audioProcessors,
encoderFactory,
muxerWrapper,
fallbackListener);
}
if (MimeTypes.isVideo(firstInputFormat.sampleMimeType)) {
return new VideoSamplePipeline(
context,
firstInputFormat,
streamStartPositionUs,
streamOffsetUs,
transformationRequest,
firstEditedMediaItem.effects.videoEffects,
firstEditedMediaItem.effects.videoFrameProcessorFactory,
encoderFactory,
muxerWrapper,
/* errorConsumer= */ this::onError,
fallbackListener,
debugViewProvider);
}
}
return new EncodedSamplePipeline(
firstInputFormat,
streamStartPositionUs,
transformationRequest,
muxerWrapper,
fallbackListener);
}
private boolean shouldTranscode(
Format inputFormat,
@AssetLoader.SupportedOutputTypes int supportedOutputTypes,
long streamStartPositionUs,
long streamOffsetUs) {
boolean assetLoaderCanOutputDecoded =
(supportedOutputTypes & SUPPORTED_OUTPUT_TYPE_DECODED) != 0;
boolean assetLoaderCanOutputEncoded =
(supportedOutputTypes & SUPPORTED_OUTPUT_TYPE_ENCODED) != 0;
checkArgument(assetLoaderCanOutputDecoded || assetLoaderCanOutputEncoded);
boolean shouldTranscode = false;
if (!assetLoaderCanOutputEncoded) {
shouldTranscode = true; shouldTranscode = true;
} else { } else if (mediaItemCount > 1 && !transmux) {
shouldTranscode = shouldTranscode = true;
isAudio } else if (MimeTypes.isAudio(inputFormat.sampleMimeType)) {
? shouldTranscodeAudio(firstInputFormat) shouldTranscode = shouldTranscodeAudio(inputFormat);
: shouldTranscodeVideo(firstInputFormat, streamStartPositionUs, streamOffsetUs); } else if (MimeTypes.isVideo(inputFormat.sampleMimeType)) {
} shouldTranscode = shouldTranscodeVideo(inputFormat, streamStartPositionUs, streamOffsetUs);
boolean assetLoaderNeverDecodes = (supportedOutputTypes & SUPPORTED_OUTPUT_TYPE_DECODED) == 0;
checkState(!shouldTranscode || !assetLoaderNeverDecodes);
boolean assetLoaderAlwaysDecodes =
(supportedOutputTypes & SUPPORTED_OUTPUT_TYPE_ENCODED) == 0;
boolean shouldUseTranscodingPipeline = shouldTranscode || assetLoaderAlwaysDecodes;
if (isAudio && shouldUseTranscodingPipeline) {
return new AudioSamplePipeline(
firstInputFormat,
streamStartPositionUs,
streamOffsetUs,
transformationRequest,
firstEditedMediaItem.flattenForSlowMotion,
firstEditedMediaItem.effects.audioProcessors,
encoderFactory,
muxerWrapper,
fallbackListener);
} else if (shouldUseTranscodingPipeline) {
return new VideoSamplePipeline(
context,
firstInputFormat,
streamStartPositionUs,
streamOffsetUs,
transformationRequest,
firstEditedMediaItem.effects.videoEffects,
firstEditedMediaItem.effects.videoFrameProcessorFactory,
encoderFactory,
muxerWrapper,
/* errorConsumer= */ this::onError,
fallbackListener,
debugViewProvider);
} else {
return new EncodedSamplePipeline(
firstInputFormat,
streamStartPositionUs,
transformationRequest,
muxerWrapper,
fallbackListener);
} }
checkState(!shouldTranscode || assetLoaderCanOutputDecoded);
return shouldTranscode;
} }
private boolean shouldTranscodeAudio(Format inputFormat) { private boolean shouldTranscodeAudio(Format inputFormat) {