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:
parent
3760f514a9
commit
efaea81194
@ -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()) {
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user