From 255c3b27f6ee08e09007addb6f177bebc62d8c0e Mon Sep 17 00:00:00 2001 From: Jonas Larsson Date: Fri, 14 Nov 2014 16:13:13 -0800 Subject: [PATCH] MediaCodecTrackRenderer: Avoid excessive garbage generation Looking up a long in a HashSet auto boxes the long and leaves it for the GC. As decodeOnly is relatively infrequent it's much better to do a simple linear search in a List. That way we can avoid boxing every incoming time stamp value. In the general case this will be linear searching in an empty list, a very fast operation. Signed-off-by: Jonas Larsson --- .../exoplayer/MediaCodecTrackRenderer.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java index 1fa103f395..d41211f3c2 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java @@ -30,7 +30,8 @@ import android.os.SystemClock; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -141,7 +142,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { private final SampleSource source; private final SampleHolder sampleHolder; private final MediaFormatHolder formatHolder; - private final HashSet decodeOnlyPresentationTimestamps; + private final List decodeOnlyPresentationTimestamps; private final MediaCodec.BufferInfo outputBufferInfo; private final EventListener eventListener; protected final Handler eventHandler; @@ -191,7 +192,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { codecCounters = new CodecCounters(); sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED); formatHolder = new MediaFormatHolder(); - decodeOnlyPresentationTimestamps = new HashSet(); + decodeOnlyPresentationTimestamps = new ArrayList(); outputBufferInfo = new MediaCodec.BufferInfo(); } @@ -738,12 +739,11 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { return false; } - boolean decodeOnly = decodeOnlyPresentationTimestamps.contains( - outputBufferInfo.presentationTimeUs); + int decodeOnlyIdx = getDecodeOnlyIndex(outputBufferInfo.presentationTimeUs); if (processOutputBuffer(positionUs, elapsedRealtimeUs, codec, outputBuffers[outputIndex], - outputBufferInfo, outputIndex, decodeOnly)) { - if (decodeOnly) { - decodeOnlyPresentationTimestamps.remove(outputBufferInfo.presentationTimeUs); + outputBufferInfo, outputIndex, decodeOnlyIdx >= 0)) { + if (decodeOnlyIdx >= 0) { + decodeOnlyPresentationTimestamps.remove(decodeOnlyIdx); } else { currentPositionUs = outputBufferInfo.presentationTimeUs; } @@ -794,4 +794,13 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { } } + private int getDecodeOnlyIndex(long presentationTimeUs) { + final int size = decodeOnlyPresentationTimestamps.size(); + for (int i = 0; i < size; i++) { + if (decodeOnlyPresentationTimestamps.get(i).longValue() == presentationTimeUs) { + return i; + } + } + return -1; + } }