mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
9a124120ff
commit
25a532656c
3 changed files with 25 additions and 44 deletions
|
|
@ -17,54 +17,41 @@ package com.google.android.exoplayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains codec event counts, for debugging purposes only.
|
* 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 final class CodecCounters {
|
||||||
|
|
||||||
public volatile long codecInitCount;
|
public int codecInitCount;
|
||||||
public volatile long codecReleaseCount;
|
public int codecReleaseCount;
|
||||||
public volatile long outputFormatChangedCount;
|
public int outputFormatChangedCount;
|
||||||
public volatile long outputBuffersChangedCount;
|
public int outputBuffersChangedCount;
|
||||||
public volatile long queuedInputBufferCount;
|
public int renderedOutputBufferCount;
|
||||||
public volatile long inputBufferWaitingForSampleCount;
|
public int skippedOutputBufferCount;
|
||||||
public volatile long keyframeCount;
|
public int droppedOutputBufferCount;
|
||||||
public volatile long queuedEndOfStreamCount;
|
|
||||||
public volatile long renderedOutputBufferCount;
|
|
||||||
public volatile long skippedOutputBufferCount;
|
|
||||||
public volatile long droppedOutputBufferCount;
|
|
||||||
public volatile long discardedSamplesCount;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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() {
|
public synchronized void ensureUpdated() {
|
||||||
codecInitCount = 0;
|
// Do nothing. The use of synchronized ensures a memory barrier should another thread also
|
||||||
codecReleaseCount = 0;
|
// call this method.
|
||||||
outputFormatChangedCount = 0;
|
|
||||||
outputBuffersChangedCount = 0;
|
|
||||||
queuedInputBufferCount = 0;
|
|
||||||
inputBufferWaitingForSampleCount = 0;
|
|
||||||
keyframeCount = 0;
|
|
||||||
queuedEndOfStreamCount = 0;
|
|
||||||
renderedOutputBufferCount = 0;
|
|
||||||
skippedOutputBufferCount = 0;
|
|
||||||
droppedOutputBufferCount = 0;
|
|
||||||
discardedSamplesCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDebugString() {
|
public String getDebugString() {
|
||||||
|
ensureUpdated();
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("cic(").append(codecInitCount).append(")");
|
builder.append("cic(").append(codecInitCount).append(")");
|
||||||
builder.append("crc(").append(codecReleaseCount).append(")");
|
builder.append("crc(").append(codecReleaseCount).append(")");
|
||||||
builder.append("ofc(").append(outputFormatChangedCount).append(")");
|
builder.append("ofc(").append(outputFormatChangedCount).append(")");
|
||||||
builder.append("obc(").append(outputBuffersChangedCount).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("ren(").append(renderedOutputBufferCount).append(")");
|
||||||
builder.append("sob(").append(skippedOutputBufferCount).append(")");
|
builder.append("sob(").append(skippedOutputBufferCount).append(")");
|
||||||
builder.append("dob(").append(droppedOutputBufferCount).append(")");
|
builder.append("dob(").append(droppedOutputBufferCount).append(")");
|
||||||
builder.append("dsc(").append(discardedSamplesCount).append(")");
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ import java.util.List;
|
||||||
private static final int IDLE_INTERVAL_MS = 1000;
|
private static final int IDLE_INTERVAL_MS = 1000;
|
||||||
|
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
private final HandlerThread internalPlayerThread;
|
private final HandlerThread internalPlaybackThread;
|
||||||
private final Handler eventHandler;
|
private final Handler eventHandler;
|
||||||
private final MediaClock mediaClock;
|
private final MediaClock mediaClock;
|
||||||
private final boolean[] rendererEnabledFlags;
|
private final boolean[] rendererEnabledFlags;
|
||||||
|
|
@ -100,7 +100,7 @@ import java.util.List;
|
||||||
|
|
||||||
mediaClock = new MediaClock();
|
mediaClock = new MediaClock();
|
||||||
enabledRenderers = new ArrayList<TrackRenderer>(rendererEnabledFlags.length);
|
enabledRenderers = new ArrayList<TrackRenderer>(rendererEnabledFlags.length);
|
||||||
internalPlayerThread = new HandlerThread(getClass().getSimpleName() + ":Handler") {
|
internalPlaybackThread = new HandlerThread(getClass().getSimpleName() + ":Handler") {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
||||||
|
|
@ -109,12 +109,12 @@ import java.util.List;
|
||||||
super.run();
|
super.run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
internalPlayerThread.start();
|
internalPlaybackThread.start();
|
||||||
handler = new Handler(internalPlayerThread.getLooper(), this);
|
handler = new Handler(internalPlaybackThread.getLooper(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Looper getPlaybackLooper() {
|
public Looper getPlaybackLooper() {
|
||||||
return internalPlayerThread.getLooper();
|
return internalPlaybackThread.getLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentPosition() {
|
public int getCurrentPosition() {
|
||||||
|
|
@ -179,7 +179,7 @@ import java.util.List;
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internalPlayerThread.quit();
|
internalPlaybackThread.quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
||||||
while (feedInputBuffer()) {}
|
while (feedInputBuffer()) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
codecCounters.ensureUpdated();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ExoPlaybackException(e);
|
throw new ExoPlaybackException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -403,7 +404,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
||||||
if (!sampleHolder.decodeOnly) {
|
if (!sampleHolder.decodeOnly) {
|
||||||
currentPositionUs = sampleHolder.timeUs;
|
currentPositionUs = sampleHolder.timeUs;
|
||||||
}
|
}
|
||||||
codecCounters.discardedSamplesCount++;
|
|
||||||
} else if (result == SampleSource.FORMAT_READ) {
|
} else if (result == SampleSource.FORMAT_READ) {
|
||||||
onInputFormatChanged(formatHolder);
|
onInputFormatChanged(formatHolder);
|
||||||
}
|
}
|
||||||
|
|
@ -476,7 +476,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == SampleSource.NOTHING_READ) {
|
if (result == SampleSource.NOTHING_READ) {
|
||||||
codecCounters.inputBufferWaitingForSampleCount++;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (result == SampleSource.DISCONTINUITY_READ) {
|
if (result == SampleSource.DISCONTINUITY_READ) {
|
||||||
|
|
@ -505,7 +504,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
||||||
try {
|
try {
|
||||||
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
codecCounters.queuedEndOfStreamCount++;
|
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
notifyCryptoError(e);
|
notifyCryptoError(e);
|
||||||
throw new ExoPlaybackException(e);
|
throw new ExoPlaybackException(e);
|
||||||
|
|
@ -545,10 +543,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
||||||
} else {
|
} else {
|
||||||
codec.queueInputBuffer(inputIndex, 0 , bufferSize, presentationTimeUs, 0);
|
codec.queueInputBuffer(inputIndex, 0 , bufferSize, presentationTimeUs, 0);
|
||||||
}
|
}
|
||||||
codecCounters.queuedInputBufferCount++;
|
|
||||||
if ((sampleHolder.flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
|
|
||||||
codecCounters.keyframeCount++;
|
|
||||||
}
|
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
|
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue