Fix how drop-to-keyframe events are recorded in DecoderCounters
The existing code creates an imbalance between `inputBufferCount` and `droppedBufferCount` by adding 'dropped source buffers' to `droppedBufferCount` but not to `inputBufferCount`. This results in assertion failures in `DashTestRunner`. PiperOrigin-RevId: 414672175
This commit is contained in:
parent
0b09ac5bb0
commit
dcc69056bf
@ -33,12 +33,12 @@ public final class DecoderCounters {
|
|||||||
public int decoderInitCount;
|
public int decoderInitCount;
|
||||||
/** The number of times a decoder has been released. */
|
/** The number of times a decoder has been released. */
|
||||||
public int decoderReleaseCount;
|
public int decoderReleaseCount;
|
||||||
/** The number of queued input buffers. */
|
/** The number of input buffers queued to the decoder. */
|
||||||
public int inputBufferCount;
|
public int inputBufferCount;
|
||||||
/**
|
/**
|
||||||
* The number of skipped input buffers.
|
* The number of skipped input buffers.
|
||||||
*
|
*
|
||||||
* <p>A skipped input buffer is an input buffer that was deliberately not sent to the decoder.
|
* <p>A skipped input buffer is an input buffer that was deliberately not queued to the decoder.
|
||||||
*/
|
*/
|
||||||
public int skippedInputBufferCount;
|
public int skippedInputBufferCount;
|
||||||
/** The number of rendered output buffers. */
|
/** The number of rendered output buffers. */
|
||||||
@ -46,16 +46,28 @@ public final class DecoderCounters {
|
|||||||
/**
|
/**
|
||||||
* The number of skipped output buffers.
|
* The number of skipped output buffers.
|
||||||
*
|
*
|
||||||
* <p>A skipped output buffer is an output buffer that was deliberately not rendered.
|
* <p>A skipped output buffer is an output buffer that was deliberately not rendered. This
|
||||||
|
* includes buffers that were never dequeued from the decoder and instead skipped while 'inside'
|
||||||
|
* the codec due to a flush.
|
||||||
*/
|
*/
|
||||||
public int skippedOutputBufferCount;
|
public int skippedOutputBufferCount;
|
||||||
/**
|
/**
|
||||||
* The number of dropped buffers.
|
* The number of dropped buffers.
|
||||||
*
|
*
|
||||||
* <p>A dropped buffer is an buffer that was supposed to be decoded/rendered, but was instead
|
* <p>A dropped buffer is a buffer that was supposed to be decoded/rendered, but was instead
|
||||||
* dropped because it could not be rendered in time.
|
* dropped because it could not be rendered in time.
|
||||||
|
*
|
||||||
|
* <p>This includes all of {@link #droppedInputBufferCount} in addition to buffers dropped after
|
||||||
|
* being queued to the decoder.
|
||||||
*/
|
*/
|
||||||
public int droppedBufferCount;
|
public int droppedBufferCount;
|
||||||
|
/**
|
||||||
|
* The number of input buffers dropped.
|
||||||
|
*
|
||||||
|
* <p>A dropped input buffer is a buffer that was not queued to the decoder because it would not
|
||||||
|
* be rendered in time.
|
||||||
|
*/
|
||||||
|
public int droppedInputBufferCount;
|
||||||
/**
|
/**
|
||||||
* The maximum number of dropped buffers without an interleaving rendered output buffer.
|
* The maximum number of dropped buffers without an interleaving rendered output buffer.
|
||||||
*
|
*
|
||||||
@ -65,9 +77,16 @@ public final class DecoderCounters {
|
|||||||
/**
|
/**
|
||||||
* The number of times all buffers to a keyframe were dropped.
|
* The number of times all buffers to a keyframe were dropped.
|
||||||
*
|
*
|
||||||
* <p>Each time buffers to a keyframe are dropped, this counter is increased by one, and the
|
* <p>Each time buffers to a keyframe are dropped:
|
||||||
* dropped buffer counters are increased by one (for the current output buffer) plus the number of
|
*
|
||||||
* buffers dropped from the source to advance to the keyframe.
|
* <ul>
|
||||||
|
* <li>This counter is incremented by one.
|
||||||
|
* <li>{@link #droppedInputBufferCount} is incremented by the number of buffers dropped from the
|
||||||
|
* source to advance to the keyframe.
|
||||||
|
* <li>{@link #droppedBufferCount} is incremented by the sum of the number of buffers dropped
|
||||||
|
* from the source to advance to the keyframe and the number of buffers 'inside' the
|
||||||
|
* decoder.
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public int droppedToKeyframeCount;
|
public int droppedToKeyframeCount;
|
||||||
/**
|
/**
|
||||||
@ -114,6 +133,7 @@ public final class DecoderCounters {
|
|||||||
renderedOutputBufferCount += other.renderedOutputBufferCount;
|
renderedOutputBufferCount += other.renderedOutputBufferCount;
|
||||||
skippedOutputBufferCount += other.skippedOutputBufferCount;
|
skippedOutputBufferCount += other.skippedOutputBufferCount;
|
||||||
droppedBufferCount += other.droppedBufferCount;
|
droppedBufferCount += other.droppedBufferCount;
|
||||||
|
droppedInputBufferCount += other.droppedInputBufferCount;
|
||||||
maxConsecutiveDroppedBufferCount =
|
maxConsecutiveDroppedBufferCount =
|
||||||
max(maxConsecutiveDroppedBufferCount, other.maxConsecutiveDroppedBufferCount);
|
max(maxConsecutiveDroppedBufferCount, other.maxConsecutiveDroppedBufferCount);
|
||||||
droppedToKeyframeCount += other.droppedToKeyframeCount;
|
droppedToKeyframeCount += other.droppedToKeyframeCount;
|
||||||
|
@ -488,7 +488,8 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
|||||||
* @param outputBuffer The output buffer to drop.
|
* @param outputBuffer The output buffer to drop.
|
||||||
*/
|
*/
|
||||||
protected void dropOutputBuffer(VideoDecoderOutputBuffer outputBuffer) {
|
protected void dropOutputBuffer(VideoDecoderOutputBuffer outputBuffer) {
|
||||||
updateDroppedBufferCounters(1);
|
updateDroppedBufferCounters(
|
||||||
|
/* droppedInputBufferCount= */ 0, /* droppedDecoderBufferCount= */ 1);
|
||||||
outputBuffer.release();
|
outputBuffer.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,21 +510,27 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
|||||||
decoderCounters.droppedToKeyframeCount++;
|
decoderCounters.droppedToKeyframeCount++;
|
||||||
// We dropped some buffers to catch up, so update the decoder counters and flush the decoder,
|
// We dropped some buffers to catch up, so update the decoder counters and flush the decoder,
|
||||||
// which releases all pending buffers buffers including the current output buffer.
|
// which releases all pending buffers buffers including the current output buffer.
|
||||||
updateDroppedBufferCounters(buffersInCodecCount + droppedSourceBufferCount);
|
updateDroppedBufferCounters(
|
||||||
|
droppedSourceBufferCount, /* droppedDecoderBufferCount= */ buffersInCodecCount);
|
||||||
flushDecoder();
|
flushDecoder();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates decoder counters to reflect that {@code droppedBufferCount} additional buffers were
|
* Updates local counters and {@link #decoderCounters} to reflect that buffers were dropped.
|
||||||
* dropped.
|
|
||||||
*
|
*
|
||||||
* @param droppedBufferCount The number of additional dropped buffers.
|
* @param droppedInputBufferCount The number of buffers dropped from the source before being
|
||||||
|
* passed to the decoder.
|
||||||
|
* @param droppedDecoderBufferCount The number of buffers dropped after being passed to the
|
||||||
|
* decoder.
|
||||||
*/
|
*/
|
||||||
protected void updateDroppedBufferCounters(int droppedBufferCount) {
|
protected void updateDroppedBufferCounters(
|
||||||
decoderCounters.droppedBufferCount += droppedBufferCount;
|
int droppedInputBufferCount, int droppedDecoderBufferCount) {
|
||||||
droppedFrames += droppedBufferCount;
|
decoderCounters.droppedInputBufferCount += droppedInputBufferCount;
|
||||||
consecutiveDroppedFrameCount += droppedBufferCount;
|
int totalDroppedBufferCount = droppedInputBufferCount + droppedDecoderBufferCount;
|
||||||
|
decoderCounters.droppedBufferCount += totalDroppedBufferCount;
|
||||||
|
droppedFrames += totalDroppedBufferCount;
|
||||||
|
consecutiveDroppedFrameCount += totalDroppedBufferCount;
|
||||||
decoderCounters.maxConsecutiveDroppedBufferCount =
|
decoderCounters.maxConsecutiveDroppedBufferCount =
|
||||||
max(consecutiveDroppedFrameCount, decoderCounters.maxConsecutiveDroppedBufferCount);
|
max(consecutiveDroppedFrameCount, decoderCounters.maxConsecutiveDroppedBufferCount);
|
||||||
if (maxDroppedFramesToNotify > 0 && droppedFrames >= maxDroppedFramesToNotify) {
|
if (maxDroppedFramesToNotify > 0 && droppedFrames >= maxDroppedFramesToNotify) {
|
||||||
|
@ -1111,7 +1111,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
TraceUtil.beginSection("dropVideoBuffer");
|
TraceUtil.beginSection("dropVideoBuffer");
|
||||||
codec.releaseOutputBuffer(index, false);
|
codec.releaseOutputBuffer(index, false);
|
||||||
TraceUtil.endSection();
|
TraceUtil.endSection();
|
||||||
updateDroppedBufferCounters(1);
|
updateDroppedBufferCounters(
|
||||||
|
/* droppedInputBufferCount= */ 0, /* droppedDecoderBufferCount= */ 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1131,29 +1132,35 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
if (droppedSourceBufferCount == 0) {
|
if (droppedSourceBufferCount == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
decoderCounters.droppedToKeyframeCount++;
|
|
||||||
// We dropped some buffers to catch up, so update the decoder counters and flush the codec,
|
// We dropped some buffers to catch up, so update the decoder counters and flush the codec,
|
||||||
// which releases all pending buffers buffers including the current output buffer.
|
// which releases all pending buffers buffers including the current output buffer.
|
||||||
int totalDroppedBufferCount = buffersInCodecCount + droppedSourceBufferCount;
|
|
||||||
if (treatDroppedBuffersAsSkipped) {
|
if (treatDroppedBuffersAsSkipped) {
|
||||||
decoderCounters.skippedOutputBufferCount += totalDroppedBufferCount;
|
decoderCounters.skippedInputBufferCount += droppedSourceBufferCount;
|
||||||
|
decoderCounters.skippedOutputBufferCount += buffersInCodecCount;
|
||||||
} else {
|
} else {
|
||||||
updateDroppedBufferCounters(totalDroppedBufferCount);
|
decoderCounters.droppedToKeyframeCount++;
|
||||||
|
updateDroppedBufferCounters(
|
||||||
|
droppedSourceBufferCount, /* droppedDecoderBufferCount= */ buffersInCodecCount);
|
||||||
}
|
}
|
||||||
flushOrReinitializeCodec();
|
flushOrReinitializeCodec();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates local counters and {@link DecoderCounters} to reflect that {@code droppedBufferCount}
|
* Updates local counters and {@link #decoderCounters} to reflect that buffers were dropped.
|
||||||
* additional buffers were dropped.
|
|
||||||
*
|
*
|
||||||
* @param droppedBufferCount The number of additional dropped buffers.
|
* @param droppedInputBufferCount The number of buffers dropped from the source before being
|
||||||
|
* passed to the decoder.
|
||||||
|
* @param droppedDecoderBufferCount The number of buffers dropped after being passed to the
|
||||||
|
* decoder.
|
||||||
*/
|
*/
|
||||||
protected void updateDroppedBufferCounters(int droppedBufferCount) {
|
protected void updateDroppedBufferCounters(
|
||||||
decoderCounters.droppedBufferCount += droppedBufferCount;
|
int droppedInputBufferCount, int droppedDecoderBufferCount) {
|
||||||
droppedFrames += droppedBufferCount;
|
decoderCounters.droppedInputBufferCount += droppedInputBufferCount;
|
||||||
consecutiveDroppedFrameCount += droppedBufferCount;
|
int totalDroppedBufferCount = droppedInputBufferCount + droppedDecoderBufferCount;
|
||||||
|
decoderCounters.droppedBufferCount += totalDroppedBufferCount;
|
||||||
|
droppedFrames += totalDroppedBufferCount;
|
||||||
|
consecutiveDroppedFrameCount += totalDroppedBufferCount;
|
||||||
decoderCounters.maxConsecutiveDroppedBufferCount =
|
decoderCounters.maxConsecutiveDroppedBufferCount =
|
||||||
max(consecutiveDroppedFrameCount, decoderCounters.maxConsecutiveDroppedBufferCount);
|
max(consecutiveDroppedFrameCount, decoderCounters.maxConsecutiveDroppedBufferCount);
|
||||||
if (maxDroppedFramesToNotify > 0 && droppedFrames >= maxDroppedFramesToNotify) {
|
if (maxDroppedFramesToNotify > 0 && droppedFrames >= maxDroppedFramesToNotify) {
|
||||||
|
@ -361,18 +361,8 @@ import java.util.List;
|
|||||||
tag + AUDIO_TAG_SUFFIX, audioCounters, 0);
|
tag + AUDIO_TAG_SUFFIX, audioCounters, 0);
|
||||||
DecoderCountersUtil.assertSkippedOutputBufferCount(
|
DecoderCountersUtil.assertSkippedOutputBufferCount(
|
||||||
tag + VIDEO_TAG_SUFFIX, videoCounters, 0);
|
tag + VIDEO_TAG_SUFFIX, videoCounters, 0);
|
||||||
// We allow one fewer output buffer due to the way that MediaCodecRenderer and the
|
DecoderCountersUtil.assertTotalBufferCount(tag + AUDIO_TAG_SUFFIX, audioCounters);
|
||||||
// underlying decoders handle the end of stream. This should be tightened up in the future.
|
DecoderCountersUtil.assertTotalBufferCount(tag + VIDEO_TAG_SUFFIX, videoCounters);
|
||||||
DecoderCountersUtil.assertTotalBufferCount(
|
|
||||||
tag + AUDIO_TAG_SUFFIX,
|
|
||||||
audioCounters,
|
|
||||||
audioCounters.inputBufferCount - 1,
|
|
||||||
audioCounters.inputBufferCount);
|
|
||||||
DecoderCountersUtil.assertTotalBufferCount(
|
|
||||||
tag + VIDEO_TAG_SUFFIX,
|
|
||||||
videoCounters,
|
|
||||||
videoCounters.inputBufferCount - 1,
|
|
||||||
videoCounters.inputBufferCount);
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!shouldSkipDroppedOutputBufferPerformanceAssertions()) {
|
if (!shouldSkipDroppedOutputBufferPerformanceAssertions()) {
|
||||||
|
@ -34,7 +34,8 @@ public final class DecoderCountersUtil {
|
|||||||
*/
|
*/
|
||||||
public static int getTotalBufferCount(DecoderCounters counters) {
|
public static int getTotalBufferCount(DecoderCounters counters) {
|
||||||
counters.ensureUpdated();
|
counters.ensureUpdated();
|
||||||
return counters.skippedOutputBufferCount
|
return counters.skippedInputBufferCount
|
||||||
|
+ counters.skippedOutputBufferCount
|
||||||
+ counters.droppedBufferCount
|
+ counters.droppedBufferCount
|
||||||
+ counters.renderedOutputBufferCount;
|
+ counters.renderedOutputBufferCount;
|
||||||
}
|
}
|
||||||
@ -49,6 +50,21 @@ public final class DecoderCountersUtil {
|
|||||||
.isEqualTo(expected);
|
.isEqualTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Asserts that the input and output values in {@code counters} are self-consistent. */
|
||||||
|
public static void assertTotalBufferCount(String name, DecoderCounters counters) {
|
||||||
|
// We allow one fewer output buffer due to the way that MediaCodecRenderer and the
|
||||||
|
// underlying decoders handle the end of stream. This should be tightened up in the future.
|
||||||
|
int totalInputBufferCount =
|
||||||
|
counters.skippedInputBufferCount
|
||||||
|
+ counters.droppedInputBufferCount
|
||||||
|
+ counters.inputBufferCount;
|
||||||
|
assertTotalBufferCount(
|
||||||
|
name,
|
||||||
|
counters,
|
||||||
|
/* minCount= */ totalInputBufferCount - 1,
|
||||||
|
/* maxCount= */ totalInputBufferCount);
|
||||||
|
}
|
||||||
|
|
||||||
public static void assertTotalBufferCount(
|
public static void assertTotalBufferCount(
|
||||||
String name, DecoderCounters counters, int minCount, int maxCount) {
|
String name, DecoderCounters counters, int minCount, int maxCount) {
|
||||||
int actual = getTotalBufferCount(counters);
|
int actual = getTotalBufferCount(counters);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user