From 65afd4062257aec7a05a19f00b3ca84b8bab129c Mon Sep 17 00:00:00 2001 From: samrobinson Date: Wed, 1 Mar 2023 17:42:35 +0000 Subject: [PATCH] Only init SpeedChangingAudioProcessor if Format.Metadata not null. If the Metadata passed to SegmentSpeedProvider is null, then the SegmentSpeedProvider will always return 1f from getSpeed. Initializing a SpeedChangingAudioProcessor requires a SpeedProvider. Once configured,this audioProcessor is always active, so buffers are passed through it. Because getSpeed is always 1, the processor performs a no-op, but still has to do a buffer copy for each buffer. By not initializing the audio processor when metadata is null, this copy can be skipped and the audio pipeline is more performant. Note: This change does not affect the multiple media-item case, which is not supported with speed changes, as per Transformer API documentation. PiperOrigin-RevId: 513261811 --- .../transformer/AudioSamplePipeline.java | 6 ++-- .../transformer/SegmentSpeedProvider.java | 30 +++++++------------ .../transformer/SegmentSpeedProviderTest.java | 15 ++-------- 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSamplePipeline.java b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSamplePipeline.java index dbd1aa4e06..719d1eab2f 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSamplePipeline.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSamplePipeline.java @@ -84,10 +84,12 @@ import org.checkerframework.dataflow.qual.Pure; encoderInputBuffer = new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED); encoderOutputBuffer = new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED); - if (flattenForSlowMotion) { + if (flattenForSlowMotion && firstInputFormat.metadata != null) { audioProcessors = new ImmutableList.Builder() - .add(new SpeedChangingAudioProcessor(new SegmentSpeedProvider(firstInputFormat))) + .add( + new SpeedChangingAudioProcessor( + new SegmentSpeedProvider(firstInputFormat.metadata))) .addAll(audioProcessors) .build(); } diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/SegmentSpeedProvider.java b/libraries/transformer/src/main/java/androidx/media3/transformer/SegmentSpeedProvider.java index 42aa74423e..9ab8b7a01a 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/SegmentSpeedProvider.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/SegmentSpeedProvider.java @@ -20,7 +20,6 @@ import static androidx.media3.extractor.metadata.mp4.SlowMotionData.Segment.BY_S import androidx.annotation.Nullable; import androidx.media3.common.C; -import androidx.media3.common.Format; import androidx.media3.common.Metadata; import androidx.media3.common.util.Util; import androidx.media3.extractor.metadata.mp4.SlowMotionData; @@ -45,11 +44,11 @@ import java.util.TreeMap; private final ImmutableSortedMap speedsByStartTimeUs; private final float baseSpeedMultiplier; - public SegmentSpeedProvider(Format format) { - float captureFrameRate = getCaptureFrameRate(format); + public SegmentSpeedProvider(Metadata metadata) { + float captureFrameRate = getCaptureFrameRate(metadata); this.baseSpeedMultiplier = captureFrameRate == C.RATE_UNSET ? 1 : captureFrameRate / INPUT_FRAME_RATE; - this.speedsByStartTimeUs = buildSpeedByStartTimeUsMap(format, baseSpeedMultiplier); + this.speedsByStartTimeUs = buildSpeedByStartTimeUsMap(metadata, baseSpeedMultiplier); } @Override @@ -67,8 +66,8 @@ import java.util.TreeMap; } private static ImmutableSortedMap buildSpeedByStartTimeUsMap( - Format format, float baseSpeed) { - List segments = extractSlowMotionSegments(format); + Metadata metadata, float baseSpeed) { + ImmutableList segments = extractSlowMotionSegments(metadata); if (segments.isEmpty()) { return ImmutableSortedMap.of(); @@ -96,11 +95,7 @@ import java.util.TreeMap; return ImmutableSortedMap.copyOf(speedsByStartTimeUs); } - private static float getCaptureFrameRate(Format format) { - @Nullable Metadata metadata = format.metadata; - if (metadata == null) { - return C.RATE_UNSET; - } + private static float getCaptureFrameRate(Metadata metadata) { for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); if (entry instanceof SmtaMetadataEntry) { @@ -111,15 +106,12 @@ import java.util.TreeMap; return C.RATE_UNSET; } - private static ImmutableList extractSlowMotionSegments(Format format) { + private static ImmutableList extractSlowMotionSegments(Metadata metadata) { List segments = new ArrayList<>(); - @Nullable Metadata metadata = format.metadata; - if (metadata != null) { - for (int i = 0; i < metadata.length(); i++) { - Metadata.Entry entry = metadata.get(i); - if (entry instanceof SlowMotionData) { - segments.addAll(((SlowMotionData) entry).segments); - } + for (int i = 0; i < metadata.length(); i++) { + Metadata.Entry entry = metadata.get(i); + if (entry instanceof SlowMotionData) { + segments.addAll(((SlowMotionData) entry).segments); } } return ImmutableList.sortedCopyOf(BY_START_THEN_END_THEN_DIVISOR, segments); diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/SegmentSpeedProviderTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/SegmentSpeedProviderTest.java index ff6bd4cc55..0ca54b1017 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/SegmentSpeedProviderTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/SegmentSpeedProviderTest.java @@ -18,7 +18,6 @@ package androidx.media3.transformer; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; -import androidx.media3.common.Format; import androidx.media3.common.Metadata; import androidx.media3.common.util.Util; import androidx.media3.extractor.metadata.mp4.SlowMotionData; @@ -39,9 +38,7 @@ public class SegmentSpeedProviderTest { @Test public void getSpeed_noSegments_returnsBaseSpeed() { - SegmentSpeedProvider provider = - new SegmentSpeedProvider( - new Format.Builder().setMetadata(new Metadata(SMTA_SPEED_8)).build()); + SegmentSpeedProvider provider = new SegmentSpeedProvider(new Metadata(SMTA_SPEED_8)); assertThat(provider.getSpeed(0)).isEqualTo(8); assertThat(provider.getSpeed(1_000_000)).isEqualTo(8); } @@ -55,10 +52,7 @@ public class SegmentSpeedProviderTest { new Segment(/* startTimeMs= */ 2000, /* endTimeMs= */ 2500, /* speedDivisor= */ 2)); SegmentSpeedProvider provider = - new SegmentSpeedProvider( - new Format.Builder() - .setMetadata(new Metadata(new SlowMotionData(segments), SMTA_SPEED_8)) - .build()); + new SegmentSpeedProvider(new Metadata(new SlowMotionData(segments), SMTA_SPEED_8)); assertThat(provider.getSpeed(Util.msToUs(0))).isEqualTo(8); assertThat(provider.getSpeed(Util.msToUs(500))).isEqualTo(1); @@ -77,9 +71,6 @@ public class SegmentSpeedProviderTest { public void getSpeed_withNegativeTimestamp_throwsException() { assertThrows( IllegalArgumentException.class, - () -> - new SegmentSpeedProvider( - new Format.Builder().setMetadata(new Metadata(SMTA_SPEED_8)).build()) - .getSpeed(-1)); + () -> new SegmentSpeedProvider(new Metadata(SMTA_SPEED_8)).getSpeed(-1)); } }