Commit db540a02 by kimvde Committed by Rohit Singh

Make sure that tracks are transcoded/transmuxed consistently

All audio tracks should either all be transcoded or all be transmuxed.
Same for video tracks.

To achieve this, simplify the behaviour of transmuxAudio/Video.

PiperOrigin-RevId: 513809287
parent 93b9cc73
...@@ -120,9 +120,10 @@ public final class Composition { ...@@ -120,9 +120,10 @@ public final class Composition {
* audio track will only be transcoded if necessary. * audio track will only be transcoded if necessary.
* *
* <p>If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all * <p>If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all
* the audio tracks are transmuxed if {@code transmuxAudio} is {@code true} and exporting the * the audio tracks are transcoded by default. They are all transmuxed if {@code transmuxAudio}
* first {@link MediaItem} doesn't require audio transcoding. Otherwise, they are all * is {@code true}. Transmuxed tracks must be compatible (typically, all the {@link MediaItem}
* transcoded. Transmuxed tracks must be compatible and must not overlap in time. * instances containing the track to transmux are concatenated in a single {@link
* EditedMediaItemSequence} and have the same sample format for that track).
* *
* <p>Requesting audio transmuxing and {@linkplain #experimentalSetForceAudioTrack(boolean) * <p>Requesting audio transmuxing and {@linkplain #experimentalSetForceAudioTrack(boolean)
* forcing an audio track} are not allowed together because generating silence requires * forcing an audio track} are not allowed together because generating silence requires
...@@ -146,9 +147,10 @@ public final class Composition { ...@@ -146,9 +147,10 @@ public final class Composition {
* video track will only be transcoded if necessary. * video track will only be transcoded if necessary.
* *
* <p>If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all * <p>If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all
* the video tracks are transmuxed if {@code transmuxVideo} is {@code true} and exporting the * the video tracks are transcoded by default. They are all transmuxed if {@code transmuxVideo}
* first {@link MediaItem} doesn't require video transcoding. Otherwise, they are all * is {@code true}. Transmuxed tracks must be compatible (typically, all the {@link MediaItem}
* transcoded. Transmuxed tracks must be compatible and must not overlap in time. * instances containing the track to transmux are concatenated in a single {@link
* EditedMediaItemSequence} and have the same sample format for that track).
* *
* @param transmuxVideo Whether to transmux the video tracks. * @param transmuxVideo Whether to transmux the video tracks.
* @return This builder. * @return This builder.
......
...@@ -582,8 +582,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -582,8 +582,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
private boolean shouldTranscodeAudio(Format inputFormat) { private boolean shouldTranscodeAudio(Format inputFormat) {
if (editedMediaItems.size() > 1 && !composition.transmuxAudio) { if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) {
return true; return !composition.transmuxAudio;
} }
if (encoderFactory.audioNeedsEncoding()) { if (encoderFactory.audioNeedsEncoding()) {
return true; return true;
...@@ -603,14 +603,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -603,14 +603,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) { if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) {
return true; return true;
} }
return false; return false;
} }
private boolean shouldTranscodeVideo( private boolean shouldTranscodeVideo(
Format inputFormat, long streamStartPositionUs, long streamOffsetUs) { Format inputFormat, long streamStartPositionUs, long streamOffsetUs) {
if (editedMediaItems.size() > 1 && !composition.transmuxVideo) { if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) {
return true; return !composition.transmuxVideo;
} }
EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0); EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0);
if ((streamStartPositionUs - streamOffsetUs) != 0 if ((streamStartPositionUs - streamOffsetUs) != 0
......
...@@ -49,6 +49,7 @@ import com.google.android.exoplayer2.MediaItem; ...@@ -49,6 +49,7 @@ import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.SonicAudioProcessor; import com.google.android.exoplayer2.audio.SonicAudioProcessor;
import com.google.android.exoplayer2.effect.Presentation; import com.google.android.exoplayer2.effect.Presentation;
import com.google.android.exoplayer2.effect.RgbFilter;
import com.google.android.exoplayer2.effect.ScaleAndRotateTransformation; import com.google.android.exoplayer2.effect.ScaleAndRotateTransformation;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
...@@ -516,15 +517,16 @@ public final class TransformerEndToEndTest { ...@@ -516,15 +517,16 @@ public final class TransformerEndToEndTest {
} }
@Test @Test
public void start_multipleMediaItemsWithEffectsAndTransmux_ignoresTransmux() throws Exception { public void start_multipleMediaItemsAndTransmux_transmux() throws Exception {
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setPitch(2f); sonicAudioProcessor.setPitch(2f);
Effect videoEffect = RgbFilter.createGrayscaleFilter();
Effects effects = Effects effects =
new Effects(ImmutableList.of(sonicAudioProcessor), /* videoEffects= */ ImmutableList.of()); new Effects(ImmutableList.of(sonicAudioProcessor), ImmutableList.of(videoEffect));
EditedMediaItem editedMediaItem = EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).setRemoveVideo(true).build(); new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
EditedMediaItemSequence editedMediaItemSequence = EditedMediaItemSequence editedMediaItemSequence =
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem, editedMediaItem)); new EditedMediaItemSequence(ImmutableList.of(editedMediaItem, editedMediaItem));
Composition composition = Composition composition =
...@@ -536,13 +538,8 @@ public final class TransformerEndToEndTest { ...@@ -536,13 +538,8 @@ public final class TransformerEndToEndTest {
transformer.start(composition, outputPath); transformer.start(composition, outputPath);
TransformerTestRunner.runLooper(transformer); TransformerTestRunner.runLooper(transformer);
// The inputs should be transcoded even though transmuxing has been requested. This is because
// audio effects have been added to the first MediaItem in the sequence, so the transcoding
// audio sample pipeline should be picked to apply these effects.
DumpFileAsserts.assertOutput( DumpFileAsserts.assertOutput(
context, context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO + ".concatenated"));
testMuxer,
getDumpFileName(FILE_AUDIO_VIDEO + ".concatenated_with_high_pitch_and_no_video"));
} }
@Test @Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment