Commit 5438e6cd by samrobinson Committed by tonihei

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
parent a64a9e67
...@@ -84,10 +84,12 @@ import org.checkerframework.dataflow.qual.Pure; ...@@ -84,10 +84,12 @@ import org.checkerframework.dataflow.qual.Pure;
encoderInputBuffer = new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED); encoderInputBuffer = new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED);
encoderOutputBuffer = new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED); encoderOutputBuffer = new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED);
if (flattenForSlowMotion) { if (flattenForSlowMotion && firstInputFormat.metadata != null) {
audioProcessors = audioProcessors =
new ImmutableList.Builder<AudioProcessor>() new ImmutableList.Builder<AudioProcessor>()
.add(new SpeedChangingAudioProcessor(new SegmentSpeedProvider(firstInputFormat))) .add(
new SpeedChangingAudioProcessor(
new SegmentSpeedProvider(firstInputFormat.metadata)))
.addAll(audioProcessors) .addAll(audioProcessors)
.build(); .build();
} }
......
...@@ -20,7 +20,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkArgument; ...@@ -20,7 +20,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData; import com.google.android.exoplayer2.metadata.mp4.SlowMotionData;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment; import com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment;
...@@ -45,11 +44,11 @@ import java.util.TreeMap; ...@@ -45,11 +44,11 @@ import java.util.TreeMap;
private final ImmutableSortedMap<Long, Float> speedsByStartTimeUs; private final ImmutableSortedMap<Long, Float> speedsByStartTimeUs;
private final float baseSpeedMultiplier; private final float baseSpeedMultiplier;
public SegmentSpeedProvider(Format format) { public SegmentSpeedProvider(Metadata metadata) {
float captureFrameRate = getCaptureFrameRate(format); float captureFrameRate = getCaptureFrameRate(metadata);
this.baseSpeedMultiplier = this.baseSpeedMultiplier =
captureFrameRate == C.RATE_UNSET ? 1 : captureFrameRate / INPUT_FRAME_RATE; captureFrameRate == C.RATE_UNSET ? 1 : captureFrameRate / INPUT_FRAME_RATE;
this.speedsByStartTimeUs = buildSpeedByStartTimeUsMap(format, baseSpeedMultiplier); this.speedsByStartTimeUs = buildSpeedByStartTimeUsMap(metadata, baseSpeedMultiplier);
} }
@Override @Override
...@@ -67,8 +66,8 @@ import java.util.TreeMap; ...@@ -67,8 +66,8 @@ import java.util.TreeMap;
} }
private static ImmutableSortedMap<Long, Float> buildSpeedByStartTimeUsMap( private static ImmutableSortedMap<Long, Float> buildSpeedByStartTimeUsMap(
Format format, float baseSpeed) { Metadata metadata, float baseSpeed) {
List<Segment> segments = extractSlowMotionSegments(format); ImmutableList<Segment> segments = extractSlowMotionSegments(metadata);
if (segments.isEmpty()) { if (segments.isEmpty()) {
return ImmutableSortedMap.of(); return ImmutableSortedMap.of();
...@@ -96,11 +95,7 @@ import java.util.TreeMap; ...@@ -96,11 +95,7 @@ import java.util.TreeMap;
return ImmutableSortedMap.copyOf(speedsByStartTimeUs); return ImmutableSortedMap.copyOf(speedsByStartTimeUs);
} }
private static float getCaptureFrameRate(Format format) { private static float getCaptureFrameRate(Metadata metadata) {
@Nullable Metadata metadata = format.metadata;
if (metadata == null) {
return C.RATE_UNSET;
}
for (int i = 0; i < metadata.length(); i++) { for (int i = 0; i < metadata.length(); i++) {
Metadata.Entry entry = metadata.get(i); Metadata.Entry entry = metadata.get(i);
if (entry instanceof SmtaMetadataEntry) { if (entry instanceof SmtaMetadataEntry) {
...@@ -111,17 +106,14 @@ import java.util.TreeMap; ...@@ -111,17 +106,14 @@ import java.util.TreeMap;
return C.RATE_UNSET; return C.RATE_UNSET;
} }
private static ImmutableList<Segment> extractSlowMotionSegments(Format format) { private static ImmutableList<Segment> extractSlowMotionSegments(Metadata metadata) {
List<Segment> segments = new ArrayList<>(); List<Segment> segments = new ArrayList<>();
@Nullable Metadata metadata = format.metadata;
if (metadata != null) {
for (int i = 0; i < metadata.length(); i++) { for (int i = 0; i < metadata.length(); i++) {
Metadata.Entry entry = metadata.get(i); Metadata.Entry entry = metadata.get(i);
if (entry instanceof SlowMotionData) { if (entry instanceof SlowMotionData) {
segments.addAll(((SlowMotionData) entry).segments); segments.addAll(((SlowMotionData) entry).segments);
} }
} }
}
return ImmutableList.sortedCopyOf(BY_START_THEN_END_THEN_DIVISOR, segments); return ImmutableList.sortedCopyOf(BY_START_THEN_END_THEN_DIVISOR, segments);
} }
} }
...@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; ...@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData; import com.google.android.exoplayer2.metadata.mp4.SlowMotionData;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment; import com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment;
...@@ -39,9 +38,7 @@ public class SegmentSpeedProviderTest { ...@@ -39,9 +38,7 @@ public class SegmentSpeedProviderTest {
@Test @Test
public void getSpeed_noSegments_returnsBaseSpeed() { public void getSpeed_noSegments_returnsBaseSpeed() {
SegmentSpeedProvider provider = SegmentSpeedProvider provider = new SegmentSpeedProvider(new Metadata(SMTA_SPEED_8));
new SegmentSpeedProvider(
new Format.Builder().setMetadata(new Metadata(SMTA_SPEED_8)).build());
assertThat(provider.getSpeed(0)).isEqualTo(8); assertThat(provider.getSpeed(0)).isEqualTo(8);
assertThat(provider.getSpeed(1_000_000)).isEqualTo(8); assertThat(provider.getSpeed(1_000_000)).isEqualTo(8);
} }
...@@ -55,10 +52,7 @@ public class SegmentSpeedProviderTest { ...@@ -55,10 +52,7 @@ public class SegmentSpeedProviderTest {
new Segment(/* startTimeMs= */ 2000, /* endTimeMs= */ 2500, /* speedDivisor= */ 2)); new Segment(/* startTimeMs= */ 2000, /* endTimeMs= */ 2500, /* speedDivisor= */ 2));
SegmentSpeedProvider provider = SegmentSpeedProvider provider =
new SegmentSpeedProvider( new SegmentSpeedProvider(new Metadata(new SlowMotionData(segments), SMTA_SPEED_8));
new Format.Builder()
.setMetadata(new Metadata(new SlowMotionData(segments), SMTA_SPEED_8))
.build());
assertThat(provider.getSpeed(Util.msToUs(0))).isEqualTo(8); assertThat(provider.getSpeed(Util.msToUs(0))).isEqualTo(8);
assertThat(provider.getSpeed(Util.msToUs(500))).isEqualTo(1); assertThat(provider.getSpeed(Util.msToUs(500))).isEqualTo(1);
...@@ -77,9 +71,6 @@ public class SegmentSpeedProviderTest { ...@@ -77,9 +71,6 @@ public class SegmentSpeedProviderTest {
public void getSpeed_withNegativeTimestamp_throwsException() { public void getSpeed_withNegativeTimestamp_throwsException() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
() -> () -> new SegmentSpeedProvider(new Metadata(SMTA_SPEED_8)).getSpeed(-1));
new SegmentSpeedProvider(
new Format.Builder().setMetadata(new Metadata(SMTA_SPEED_8)).build())
.getSpeed(-1));
} }
} }
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