public final class

DecoderCounters

extends java.lang.Object

 java.lang.Object

↳androidx.media3.exoplayer.DecoderCounters

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-exoplayer', version: '1.5.0-alpha01'

  • groupId: androidx.media3
  • artifactId: media3-exoplayer
  • version: 1.5.0-alpha01

Artifact androidx.media3:media3-exoplayer:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

Maintains decoder event counts, for debugging purposes only.

Counters should be written from the playback thread only. Counters may be read from any thread. To ensure that the counter values are made visible across threads, users of this class should invoke DecoderCounters.ensureUpdated() prior to reading and after writing.

Summary

Fields
public intdecoderInitCount

The number of times a decoder has been initialized.

public intdecoderReleaseCount

The number of times a decoder has been released.

public intdroppedBufferCount

The number of dropped buffers.

public intdroppedInputBufferCount

The number of input buffers dropped.

public intdroppedToKeyframeCount

The number of times all buffers to a keyframe were dropped.

public intmaxConsecutiveDroppedBufferCount

The maximum number of dropped buffers without an interleaving rendered output buffer.

public intqueuedInputBufferCount

The number of input buffers queued to the decoder.

public intrenderedOutputBufferCount

The number of rendered output buffers.

public intskippedInputBufferCount

The number of skipped input buffers.

public intskippedOutputBufferCount

The number of skipped output buffers.

public longtotalVideoFrameProcessingOffsetUs

The sum of the video frame processing offsets in microseconds.

public intvideoFrameProcessingOffsetCount

The number of video frame processing offsets added.

Constructors
publicDecoderCounters()

Methods
public voidaddVideoFrameProcessingOffset(long processingOffsetUs)

Adds a video frame processing offset to DecoderCounters.totalVideoFrameProcessingOffsetUs and increases DecoderCounters.videoFrameProcessingOffsetCount by one.

public synchronized voidensureUpdated()

Should be called to ensure counter values are made visible across threads.

public voidmerge(DecoderCounters other)

Merges the counts from other into this instance.

public java.lang.StringtoString()

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Fields

public int decoderInitCount

The number of times a decoder has been initialized.

public int decoderReleaseCount

The number of times a decoder has been released.

public int queuedInputBufferCount

The number of input buffers queued to the decoder.

public int skippedInputBufferCount

The number of skipped input buffers.

A skipped input buffer is an input buffer that was deliberately not queued to the decoder.

public int renderedOutputBufferCount

The number of rendered output buffers.

public int skippedOutputBufferCount

The number of skipped output buffers.

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 droppedBufferCount

The number of dropped buffers.

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.

This includes all of DecoderCounters.droppedInputBufferCount in addition to buffers dropped after being queued to the decoder.

public int droppedInputBufferCount

The number of input buffers dropped.

A dropped input buffer is a buffer that was not queued to the decoder because it would not be rendered in time.

public int maxConsecutiveDroppedBufferCount

The maximum number of dropped buffers without an interleaving rendered output buffer.

Skipped buffers are ignored for the purposes of calculating this value.

public int droppedToKeyframeCount

The number of times all buffers to a keyframe were dropped.

Each time buffers to a keyframe are dropped:

public long totalVideoFrameProcessingOffsetUs

The sum of the video frame processing offsets in microseconds.

The processing offset for a video frame is the difference between the time at which the frame became available to render, and the time at which it was scheduled to be rendered. A positive value indicates the frame became available early enough, whereas a negative value indicates that the frame wasn't available until after the time at which it should have been rendered.

Note: Use DecoderCounters.addVideoFrameProcessingOffset(long) to update this field instead of updating it directly.

public int videoFrameProcessingOffsetCount

The number of video frame processing offsets added.

Note: Use DecoderCounters.addVideoFrameProcessingOffset(long) to update this field instead of updating it directly.

Constructors

public DecoderCounters()

Methods

public synchronized void ensureUpdated()

Should be called to ensure counter values are made visible across threads. The playback thread should call this method after updating the counter values. Any other thread should call this method before reading the counters.

public void merge(DecoderCounters other)

Merges the counts from other into this instance.

Parameters:

other: The DecoderCounters to merge into this instance.

public void addVideoFrameProcessingOffset(long processingOffsetUs)

Adds a video frame processing offset to DecoderCounters.totalVideoFrameProcessingOffsetUs and increases DecoderCounters.videoFrameProcessingOffsetCount by one.

Convenience method to ensure both fields are updated when adding a single offset.

Parameters:

processingOffsetUs: The video frame processing offset in microseconds.

public java.lang.String toString()

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.exoplayer;

import static java.lang.Math.max;

import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;

/**
 * Maintains decoder 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 made visible across threads, users of this class
 * should invoke {@link #ensureUpdated()} prior to reading and after writing.
 */
@UnstableApi
public final class DecoderCounters {

  /** The number of times a decoder has been initialized. */
  public int decoderInitCount;

  /** The number of times a decoder has been released. */
  public int decoderReleaseCount;

  /** The number of input buffers queued to the decoder. */
  public int queuedInputBufferCount;

  /**
   * The number of skipped input buffers.
   *
   * <p>A skipped input buffer is an input buffer that was deliberately not queued to the decoder.
   */
  public int skippedInputBufferCount;

  /** 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. This
   * includes buffers that were never dequeued from the decoder and instead skipped while 'inside'
   * the codec due to a flush.
   */
  public int skippedOutputBufferCount;

  /**
   * The number of dropped buffers.
   *
   * <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.
   *
   * <p>This includes all of {@link #droppedInputBufferCount} in addition to buffers dropped after
   * being queued to the decoder.
   */
  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.
   *
   * <p>Skipped buffers are ignored for the purposes of calculating this value.
   */
  public int maxConsecutiveDroppedBufferCount;

  /**
   * The number of times all buffers to a keyframe were dropped.
   *
   * <p>Each time buffers to a keyframe are dropped:
   *
   * <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;

  /**
   * The sum of the video frame processing offsets in microseconds.
   *
   * <p>The processing offset for a video frame is the difference between the time at which the
   * frame became available to render, and the time at which it was scheduled to be rendered. A
   * positive value indicates the frame became available early enough, whereas a negative value
   * indicates that the frame wasn't available until after the time at which it should have been
   * rendered.
   *
   * <p>Note: Use {@link #addVideoFrameProcessingOffset(long)} to update this field instead of
   * updating it directly.
   */
  public long totalVideoFrameProcessingOffsetUs;

  /**
   * The number of video frame processing offsets added.
   *
   * <p>Note: Use {@link #addVideoFrameProcessingOffset(long)} to update this field instead of
   * updating it directly.
   */
  public int videoFrameProcessingOffsetCount;

  /**
   * Should be called to ensure counter values are made visible across threads. The playback thread
   * should call this method after updating the counter values. Any other thread should call this
   * method before reading the counters.
   */
  public synchronized void ensureUpdated() {
    // Do nothing. The use of synchronized ensures a memory barrier should another thread also
    // call this method.
  }

  /**
   * Merges the counts from {@code other} into this instance.
   *
   * @param other The {@link DecoderCounters} to merge into this instance.
   */
  public void merge(DecoderCounters other) {
    decoderInitCount += other.decoderInitCount;
    decoderReleaseCount += other.decoderReleaseCount;
    queuedInputBufferCount += other.queuedInputBufferCount;
    skippedInputBufferCount += other.skippedInputBufferCount;
    renderedOutputBufferCount += other.renderedOutputBufferCount;
    skippedOutputBufferCount += other.skippedOutputBufferCount;
    droppedBufferCount += other.droppedBufferCount;
    droppedInputBufferCount += other.droppedInputBufferCount;
    maxConsecutiveDroppedBufferCount =
        max(maxConsecutiveDroppedBufferCount, other.maxConsecutiveDroppedBufferCount);
    droppedToKeyframeCount += other.droppedToKeyframeCount;
    addVideoFrameProcessingOffsets(
        other.totalVideoFrameProcessingOffsetUs, other.videoFrameProcessingOffsetCount);
  }

  /**
   * Adds a video frame processing offset to {@link #totalVideoFrameProcessingOffsetUs} and
   * increases {@link #videoFrameProcessingOffsetCount} by one.
   *
   * <p>Convenience method to ensure both fields are updated when adding a single offset.
   *
   * @param processingOffsetUs The video frame processing offset in microseconds.
   */
  public void addVideoFrameProcessingOffset(long processingOffsetUs) {
    addVideoFrameProcessingOffsets(processingOffsetUs, /* count= */ 1);
  }

  private void addVideoFrameProcessingOffsets(long totalProcessingOffsetUs, int count) {
    totalVideoFrameProcessingOffsetUs += totalProcessingOffsetUs;
    videoFrameProcessingOffsetCount += count;
  }

  @Override
  public String toString() {
    return Util.formatInvariant(
        "DecoderCounters {\n "
            + "decoderInits=%s,\n "
            + "decoderReleases=%s\n "
            + "queuedInputBuffers=%s\n "
            + "skippedInputBuffers=%s\n "
            + "renderedOutputBuffers=%s\n "
            + "skippedOutputBuffers=%s\n "
            + "droppedBuffers=%s\n "
            + "droppedInputBuffers=%s\n "
            + "maxConsecutiveDroppedBuffers=%s\n "
            + "droppedToKeyframeEvents=%s\n "
            + "totalVideoFrameProcessingOffsetUs=%s\n "
            + "videoFrameProcessingOffsetCount=%s\n}",
        decoderInitCount,
        decoderReleaseCount,
        queuedInputBufferCount,
        skippedInputBufferCount,
        renderedOutputBufferCount,
        skippedOutputBufferCount,
        droppedBufferCount,
        droppedInputBufferCount,
        maxConsecutiveDroppedBufferCount,
        droppedToKeyframeCount,
        totalVideoFrameProcessingOffsetUs,
        videoFrameProcessingOffsetCount);
  }
}