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;
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<AudioProcessor>()
.add(new SpeedChangingAudioProcessor(new SegmentSpeedProvider(firstInputFormat)))
.add(
new SpeedChangingAudioProcessor(
new SegmentSpeedProvider(firstInputFormat.metadata)))
.addAll(audioProcessors)
.build();
}
......
......@@ -20,7 +20,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import androidx.annotation.Nullable;
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.mp4.SlowMotionData;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment;
......@@ -45,11 +44,11 @@ import java.util.TreeMap;
private final ImmutableSortedMap<Long, Float> 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<Long, Float> buildSpeedByStartTimeUsMap(
Format format, float baseSpeed) {
List<Segment> segments = extractSlowMotionSegments(format);
Metadata metadata, float baseSpeed) {
ImmutableList<Segment> 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<Segment> extractSlowMotionSegments(Format format) {
private static ImmutableList<Segment> extractSlowMotionSegments(Metadata metadata) {
List<Segment> 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);
......
......@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
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.mp4.SlowMotionData;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment;
......@@ -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));
}
}
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