Optimize some CodecCounter inefficiency.

1. Use ints rather than longs.
2. Remove some counters that dont seem hugely useful.
3. Replace use of volatile with explicit method calls that
   cause a memory barrier. This is a lot more efficient than
   using volatile because it can be invoked only once per
   doSomeWork.
This commit is contained in:
Oliver Woodman 2014-08-11 17:42:08 +01:00
parent 9a124120ff
commit 25a532656c
3 changed files with 25 additions and 44 deletions

View File

@ -17,54 +17,41 @@ package com.google.android.exoplayer;
/**
* Maintains codec event counts, for debugging purposes only.
* <p>
* Counters should be written from the playback thread only. Counters may be read from any thread.
* To ensure that the counter values are correctly reflected between threads, users of this class
* should invoke {@link #ensureUpdated()} prior to reading and after writing.
*/
public final class CodecCounters {
public volatile long codecInitCount;
public volatile long codecReleaseCount;
public volatile long outputFormatChangedCount;
public volatile long outputBuffersChangedCount;
public volatile long queuedInputBufferCount;
public volatile long inputBufferWaitingForSampleCount;
public volatile long keyframeCount;
public volatile long queuedEndOfStreamCount;
public volatile long renderedOutputBufferCount;
public volatile long skippedOutputBufferCount;
public volatile long droppedOutputBufferCount;
public volatile long discardedSamplesCount;
public int codecInitCount;
public int codecReleaseCount;
public int outputFormatChangedCount;
public int outputBuffersChangedCount;
public int renderedOutputBufferCount;
public int skippedOutputBufferCount;
public int droppedOutputBufferCount;
/**
* Resets all counts to zero.
* Should be invoked from the playback thread after the counters have been updated. Should also
* be invoked from any other thread that wishes to read the counters, before reading. These calls
* ensure that counter updates are made visible to the reading threads.
*/
public void zeroAllCounts() {
codecInitCount = 0;
codecReleaseCount = 0;
outputFormatChangedCount = 0;
outputBuffersChangedCount = 0;
queuedInputBufferCount = 0;
inputBufferWaitingForSampleCount = 0;
keyframeCount = 0;
queuedEndOfStreamCount = 0;
renderedOutputBufferCount = 0;
skippedOutputBufferCount = 0;
droppedOutputBufferCount = 0;
discardedSamplesCount = 0;
public synchronized void ensureUpdated() {
// Do nothing. The use of synchronized ensures a memory barrier should another thread also
// call this method.
}
public String getDebugString() {
ensureUpdated();
StringBuilder builder = new StringBuilder();
builder.append("cic(").append(codecInitCount).append(")");
builder.append("crc(").append(codecReleaseCount).append(")");
builder.append("ofc(").append(outputFormatChangedCount).append(")");
builder.append("obc(").append(outputBuffersChangedCount).append(")");
builder.append("qib(").append(queuedInputBufferCount).append(")");
builder.append("wib(").append(inputBufferWaitingForSampleCount).append(")");
builder.append("kfc(").append(keyframeCount).append(")");
builder.append("qes(").append(queuedEndOfStreamCount).append(")");
builder.append("ren(").append(renderedOutputBufferCount).append(")");
builder.append("sob(").append(skippedOutputBufferCount).append(")");
builder.append("dob(").append(droppedOutputBufferCount).append(")");
builder.append("dsc(").append(discardedSamplesCount).append(")");
return builder.toString();
}

View File

@ -60,7 +60,7 @@ import java.util.List;
private static final int IDLE_INTERVAL_MS = 1000;
private final Handler handler;
private final HandlerThread internalPlayerThread;
private final HandlerThread internalPlaybackThread;
private final Handler eventHandler;
private final MediaClock mediaClock;
private final boolean[] rendererEnabledFlags;
@ -100,7 +100,7 @@ import java.util.List;
mediaClock = new MediaClock();
enabledRenderers = new ArrayList<TrackRenderer>(rendererEnabledFlags.length);
internalPlayerThread = new HandlerThread(getClass().getSimpleName() + ":Handler") {
internalPlaybackThread = new HandlerThread(getClass().getSimpleName() + ":Handler") {
@Override
public void run() {
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
@ -109,12 +109,12 @@ import java.util.List;
super.run();
}
};
internalPlayerThread.start();
handler = new Handler(internalPlayerThread.getLooper(), this);
internalPlaybackThread.start();
handler = new Handler(internalPlaybackThread.getLooper(), this);
}
public Looper getPlaybackLooper() {
return internalPlayerThread.getLooper();
return internalPlaybackThread.getLooper();
}
public int getCurrentPosition() {
@ -179,7 +179,7 @@ import java.util.List;
Thread.currentThread().interrupt();
}
}
internalPlayerThread.quit();
internalPlaybackThread.quit();
}
}

View File

@ -382,6 +382,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
while (feedInputBuffer()) {}
}
}
codecCounters.ensureUpdated();
} catch (IOException e) {
throw new ExoPlaybackException(e);
}
@ -403,7 +404,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
if (!sampleHolder.decodeOnly) {
currentPositionUs = sampleHolder.timeUs;
}
codecCounters.discardedSamplesCount++;
} else if (result == SampleSource.FORMAT_READ) {
onInputFormatChanged(formatHolder);
}
@ -476,7 +476,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
if (result == SampleSource.NOTHING_READ) {
codecCounters.inputBufferWaitingForSampleCount++;
return false;
}
if (result == SampleSource.DISCONTINUITY_READ) {
@ -505,7 +504,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
try {
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputIndex = -1;
codecCounters.queuedEndOfStreamCount++;
} catch (CryptoException e) {
notifyCryptoError(e);
throw new ExoPlaybackException(e);
@ -545,10 +543,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
} else {
codec.queueInputBuffer(inputIndex, 0 , bufferSize, presentationTimeUs, 0);
}
codecCounters.queuedInputBufferCount++;
if ((sampleHolder.flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
codecCounters.keyframeCount++;
}
inputIndex = -1;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
} catch (CryptoException e) {