Commit efaea811 by olly Committed by Oliver Woodman

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
parent 3760f514
......@@ -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();
}
......
......@@ -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;
}
}
......@@ -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++;
}
/**
......
......@@ -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();
}
......
......@@ -164,6 +164,7 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
if (outputBuffer == null) {
return false;
}
codecCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount;
}
if (outputBuffer.isEndOfStream()) {
......
......@@ -28,6 +28,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.
*/
public abstract void release();
......
......@@ -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.
*/
......
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