• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.exoplayer2.decoder;
17 
18 /**
19  * Maintains decoder event counts, for debugging purposes only.
20  * <p>
21  * Counters should be written from the playback thread only. Counters may be read from any thread.
22  * To ensure that the counter values are made visible across threads, users of this class should
23  * invoke {@link #ensureUpdated()} prior to reading and after writing.
24  */
25 public final class DecoderCounters {
26 
27   /**
28    * The number of times a decoder has been initialized.
29    */
30   public int decoderInitCount;
31   /**
32    * The number of times a decoder has been released.
33    */
34   public int decoderReleaseCount;
35   /**
36    * The number of queued input buffers.
37    */
38   public int inputBufferCount;
39   /**
40    * The number of skipped input buffers.
41    * <p>
42    * A skipped input buffer is an input buffer that was deliberately not sent to the decoder.
43    */
44   public int skippedInputBufferCount;
45   /**
46    * The number of rendered output buffers.
47    */
48   public int renderedOutputBufferCount;
49   /**
50    * The number of skipped output buffers.
51    * <p>
52    * A skipped output buffer is an output buffer that was deliberately not rendered.
53    */
54   public int skippedOutputBufferCount;
55   /**
56    * The number of dropped buffers.
57    * <p>
58    * A dropped buffer is an buffer that was supposed to be decoded/rendered, but was instead
59    * dropped because it could not be rendered in time.
60    */
61   public int droppedBufferCount;
62   /**
63    * The maximum number of dropped buffers without an interleaving rendered output buffer.
64    * <p>
65    * Skipped output buffers are ignored for the purposes of calculating this value.
66    */
67   public int maxConsecutiveDroppedBufferCount;
68   /**
69    * The number of times all buffers to a keyframe were dropped.
70    * <p>
71    * Each time buffers to a keyframe are dropped, this counter is increased by one, and the dropped
72    * buffer counters are increased by one (for the current output buffer) plus the number of buffers
73    * dropped from the source to advance to the keyframe.
74    */
75   public int droppedToKeyframeCount;
76   /**
77    * The sum of video frame processing offset samples in microseconds.
78    *
79    * <p>Video frame processing offset measures how early a video frame was processed by a video
80    * renderer compared to the player's current position.
81    *
82    * <p>Note: Use {@link #addVideoFrameProcessingOffsetSample(long)} to update this field instead of
83    * updating it directly.
84    */
85   public long totalVideoFrameProcessingOffsetUs;
86   /**
87    * The number of video frame processing offset samples added.
88    *
89    * <p>Note: Use {@link #addVideoFrameProcessingOffsetSample(long)} to update this field instead of
90    * updating it directly.
91    */
92   public int videoFrameProcessingOffsetCount;
93 
94   /**
95    * Should be called to ensure counter values are made visible across threads. The playback thread
96    * should call this method after updating the counter values. Any other thread should call this
97    * method before reading the counters.
98    */
ensureUpdated()99   public synchronized void ensureUpdated() {
100     // Do nothing. The use of synchronized ensures a memory barrier should another thread also
101     // call this method.
102   }
103 
104   /**
105    * Merges the counts from {@code other} into this instance.
106    *
107    * @param other The {@link DecoderCounters} to merge into this instance.
108    */
merge(DecoderCounters other)109   public void merge(DecoderCounters other) {
110     decoderInitCount += other.decoderInitCount;
111     decoderReleaseCount += other.decoderReleaseCount;
112     inputBufferCount += other.inputBufferCount;
113     skippedInputBufferCount += other.skippedInputBufferCount;
114     renderedOutputBufferCount += other.renderedOutputBufferCount;
115     skippedOutputBufferCount += other.skippedOutputBufferCount;
116     droppedBufferCount += other.droppedBufferCount;
117     maxConsecutiveDroppedBufferCount = Math.max(maxConsecutiveDroppedBufferCount,
118         other.maxConsecutiveDroppedBufferCount);
119     droppedToKeyframeCount += other.droppedToKeyframeCount;
120 
121     addVideoFrameProcessingOffsetSamples(
122         other.totalVideoFrameProcessingOffsetUs, other.videoFrameProcessingOffsetCount);
123   }
124 
125   /**
126    * Adds a video frame processing offset sample to {@link #totalVideoFrameProcessingOffsetUs} and
127    * increases {@link #videoFrameProcessingOffsetCount} by one.
128    *
129    * <p>Convenience method to ensure both fields are updated when adding a sample.
130    *
131    * @param sampleUs The sample in microseconds.
132    */
addVideoFrameProcessingOffsetSample(long sampleUs)133   public void addVideoFrameProcessingOffsetSample(long sampleUs) {
134     addVideoFrameProcessingOffsetSamples(sampleUs, /* count= */ 1);
135   }
136 
addVideoFrameProcessingOffsetSamples(long sampleUs, int count)137   private void addVideoFrameProcessingOffsetSamples(long sampleUs, int count) {
138     totalVideoFrameProcessingOffsetUs += sampleUs;
139     videoFrameProcessingOffsetCount += count;
140   }
141 }
142