Use CodecCounters consistently in all renderers.

- Increment skippedBufferCount for VPX and ADTR.
- Set maxConsecutiveDroppedOutputBufferCount count for VPX.
  Tweak its meaning to ignore skipped frames.
- Remove outputFormat/outputBuffer changed counts. These add
  limited value. Also, MediaCodec is moving toward a model where
  you don't see the output buffers changing because you dequeue
  them one at a time (like how our extension decoders work).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122258530
This commit is contained in:
olly 2016-05-13 07:47:40 -07:00 committed by Oliver Woodman
parent 3760f514a9
commit efaea81194
7 changed files with 62 additions and 24 deletions

View File

@ -79,8 +79,9 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
private int previousWidth;
private int previousHeight;
private int droppedFrameCount;
private long droppedFrameAccumulationStartTimeMs;
private int droppedFrameCount;
private int consecutiveDroppedFrameCount;
/**
* @param scaleToFit Boolean that indicates if video frames should be scaled to fit when
@ -183,6 +184,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
if (outputBuffer == null) {
return false;
}
codecCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount;
}
if (nextOutputBuffer == null) {
@ -202,6 +204,9 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
// Drop frame if we are too late.
codecCounters.droppedOutputBufferCount++;
droppedFrameCount++;
consecutiveDroppedFrameCount++;
codecCounters.maxConsecutiveDroppedOutputBufferCount = Math.max(consecutiveDroppedFrameCount,
codecCounters.maxConsecutiveDroppedOutputBufferCount);
if (droppedFrameCount == maxDroppedFrameCountToNotify) {
notifyAndResetDroppedFrameCount();
}
@ -227,6 +232,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
private void renderBuffer() {
codecCounters.renderedOutputBufferCount++;
consecutiveDroppedFrameCount = 0;
notifyIfVideoSizeChanged(outputBuffer.width, outputBuffer.height);
if (outputBuffer.mode == VpxDecoder.OUTPUT_MODE_RGB && surface != null) {
renderRgbFrame(outputBuffer, scaleToFit);
@ -320,6 +326,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
inputStreamEnded = false;
outputStreamEnded = false;
renderedFirstFrame = false;
consecutiveDroppedFrameCount = 0;
if (decoder != null) {
flushDecoder();
}

View File

@ -24,14 +24,40 @@ package com.google.android.exoplayer;
*/
public final class CodecCounters {
/**
* The number of times the codec has been initialized.
*/
public int codecInitCount;
/**
* The number of times the codec has been released.
*/
public int codecReleaseCount;
/**
* The number of queued input buffers.
*/
public int inputBufferCount;
public int outputFormatChangedCount;
public int outputBuffersChangedCount;
/**
* The number of rendered output buffers.
*/
public int renderedOutputBufferCount;
/**
* The number of skipped output buffers.
* <p>
* A skipped output buffer is an output buffer that was deliberately not rendered.
*/
public int skippedOutputBufferCount;
/**
* The number of dropped output buffers.
* <p>
* A dropped output buffer is an output buffer that was supposed to be rendered, but was instead
* dropped because it could not be rendered in time.
*/
public int droppedOutputBufferCount;
/**
* The maximum number of dropped output buffers without an interleaving rendered output buffer.
* <p>
* Skipped output buffers are ignored for the purposes of calculating this value.
*/
public int maxConsecutiveDroppedOutputBufferCount;
/**
@ -46,15 +72,13 @@ public final class CodecCounters {
public String getDebugString() {
ensureUpdated();
return "cic:" + codecInitCount
+ " crc:" + codecReleaseCount
+ " ibc:" + inputBufferCount
+ " ofc:" + outputFormatChangedCount
+ " obc:" + outputBuffersChangedCount
+ " ren:" + renderedOutputBufferCount
+ " sob:" + skippedOutputBufferCount
+ " dob:" + droppedOutputBufferCount
+ " mcdob:" + maxConsecutiveDroppedOutputBufferCount;
return "ic:" + codecInitCount
+ " rc:" + codecReleaseCount
+ " ib:" + inputBufferCount
+ " rb:" + renderedOutputBufferCount
+ " sb:" + skippedOutputBufferCount
+ " db:" + droppedOutputBufferCount
+ " mcdb:" + maxConsecutiveDroppedOutputBufferCount;
}
}

View File

@ -827,7 +827,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
format.setInteger(android.media.MediaFormat.KEY_CHANNEL_COUNT, 1);
}
onOutputFormatChanged(codec, format);
codecCounters.outputFormatChangedCount++;
}
/**
@ -836,7 +835,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
@SuppressWarnings("deprecation")
private void processOutputBuffersChanged() {
outputBuffers = codec.getOutputBuffers();
codecCounters.outputBuffersChangedCount++;
}
/**

View File

@ -392,7 +392,6 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
boolean shouldSkip) {
if (shouldSkip) {
skipOutputBuffer(codec, bufferIndex);
consecutiveDroppedFrameCount = 0;
return true;
}
@ -402,7 +401,6 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
} else {
renderOutputBuffer(codec, bufferIndex);
}
consecutiveDroppedFrameCount = 0;
return true;
}
@ -433,7 +431,6 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
// Let the underlying framework time the release.
if (earlyUs < 50000) {
renderOutputBufferV21(codec, bufferIndex, adjustedReleaseTimeNs);
consecutiveDroppedFrameCount = 0;
return true;
}
} else {
@ -450,7 +447,6 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
}
renderOutputBuffer(codec, bufferIndex);
consecutiveDroppedFrameCount = 0;
return true;
}
}
@ -486,6 +482,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
codec.releaseOutputBuffer(bufferIndex, true);
TraceUtil.endSection();
codecCounters.renderedOutputBufferCount++;
consecutiveDroppedFrameCount = 0;
renderedFirstFrame = true;
maybeNotifyDrawnToSurface();
}
@ -497,6 +494,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
codec.releaseOutputBuffer(bufferIndex, releaseTimeNs);
TraceUtil.endSection();
codecCounters.renderedOutputBufferCount++;
consecutiveDroppedFrameCount = 0;
renderedFirstFrame = true;
maybeNotifyDrawnToSurface();
}

View File

@ -164,6 +164,7 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
if (outputBuffer == null) {
return false;
}
codecCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount;
}
if (outputBuffer.isEndOfStream()) {

View File

@ -27,6 +27,11 @@ public abstract class OutputBuffer extends Buffer {
*/
public long timestampUs;
/**
* The number of buffers immediately prior to this one that were skipped in the {@link Decoder}.
*/
public int skippedOutputBufferCount;
/**
* Releases the output buffer for reuse. Must be called when the buffer is no longer needed.
*/

View File

@ -56,6 +56,7 @@ public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends Outp
private E exception;
private boolean flushed;
private boolean released;
private int skippedOutputBufferCount;
/**
* @param inputBuffers An array of nulls that will be used to store references to input buffers.
@ -148,6 +149,7 @@ public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends Outp
public final void flush() {
synchronized (lock) {
flushed = true;
skippedOutputBufferCount = 0;
if (dequeuedInputBuffer != null) {
releaseInputBufferInternal(dequeuedInputBuffer);
dequeuedInputBuffer = null;
@ -242,12 +244,14 @@ public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends Outp
}
synchronized (lock) {
if (flushed || outputBuffer.isDecodeOnly()) {
// If a flush occurred while decoding or the buffer was only for decoding (not presentation)
// then make the output buffer available again rather than queueing it to be consumed.
if (flushed) {
releaseOutputBufferInternal(outputBuffer);
} else if (outputBuffer.isDecodeOnly()) {
skippedOutputBufferCount++;
releaseOutputBufferInternal(outputBuffer);
} else {
// Queue the decoded output buffer to be consumed.
outputBuffer.skippedOutputBufferCount = skippedOutputBufferCount;
skippedOutputBufferCount = 0;
queuedOutputBuffers.addLast(outputBuffer);
}
// Make the input buffer available again.
@ -287,8 +291,9 @@ public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends Outp
* @param inputBuffer The buffer to decode.
* @param outputBuffer The output buffer to store decoded data. The flag
* {@link C#BUFFER_FLAG_DECODE_ONLY} will be set if the same flag is set on
* {@code inputBuffer}, but the decoder may set/unset the flag if required. If the flag is set
* after this method returns, any output will not be presented.
* {@code inputBuffer}, but may be set/unset as required. If the flag is set when the call
* returns then the output buffer will not be made available to dequeue. The output buffer
* may not have been populated in this case.
* @param reset True if the decoder must be reset before decoding.
* @return A decoder exception if an error occurred, or null if decoding was successful.
*/