Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
0a612ce3
authored
Feb 14, 2020
by
christosts
Committed by
Ian Baker
Feb 17, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Video processing offset in AnalyticsListener
PiperOrigin-RevId: 295146481
parent
51045482
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
146 additions
and
119 deletions
RELEASENOTES.md
library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java
library/core/src/main/java/com/google/android/exoplayer2/decoder/DecoderCounters.java
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/video/VideoRendererEventListener.java
library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java
library/core/src/test/java/com/google/android/exoplayer2/decoder/DecoderCountersTest.java
library/ui/src/main/java/com/google/android/exoplayer2/ui/DebugTextViewHelper.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/DecoderCountersUtil.java
RELEASENOTES.md
View file @
0a612ce3
...
...
@@ -3,6 +3,8 @@
### dev-v2 (not yet released) ###
*
Core library:
*
Add API in
`AnalyticsListener`
to report video frame processing offset.
`MediaCodecVideoRenderer`
reports the event.
*
Add fields
`videoFrameProcessingOffsetUsSum`
and
`videoFrameProcessingOffsetUsCount`
in
`DecoderCounters`
to compute
the average video frame processing offset.
...
...
library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
View file @
0a612ce3
...
...
@@ -1775,6 +1775,15 @@ public class SimpleExoPlayer extends BasePlayer
videoDecoderCounters
=
null
;
}
@Override
public
void
onVideoFrameProcessingOffset
(
long
totalProcessingOffsetUs
,
int
frameCount
,
Format
format
)
{
for
(
VideoRendererEventListener
videoDebugListener
:
videoDebugListeners
)
{
videoDebugListener
.
onVideoFrameProcessingOffset
(
totalProcessingOffsetUs
,
frameCount
,
format
);
}
}
// AudioRendererEventListener implementation
@Override
...
...
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java
View file @
0a612ce3
...
...
@@ -281,6 +281,15 @@ public class AnalyticsCollector
}
}
@Override
public
final
void
onVideoFrameProcessingOffset
(
long
totalProcessingOffsetUs
,
int
frameCount
,
Format
format
)
{
EventTime
eventTime
=
generatePlayingMediaPeriodEventTime
();
for
(
AnalyticsListener
listener
:
listeners
)
{
listener
.
onVideoFrameProcessingOffset
(
eventTime
,
totalProcessingOffsetUs
,
frameCount
,
format
);
}
}
// VideoListener implementation.
@Override
...
...
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java
View file @
0a612ce3
...
...
@@ -462,6 +462,30 @@ public interface AnalyticsListener {
default
void
onDroppedVideoFrames
(
EventTime
eventTime
,
int
droppedFrames
,
long
elapsedMs
)
{}
/**
* Called when there is an update to the video frame processing offset reported by a video
* renderer.
*
* <p>Video processing offset represents how early a video frame is processed compared to the
* player's current position. For each video frame, the offset is calculated as <em>P<sub>vf</sub>
* - P<sub>pl</sub></em> where <em>P<sub>vf</sub></em> is the presentation timestamp of the video
* frame and <em>P<sub>pl</sub></em> is the current position of the player. Positive values
* indicate the frame was processed early enough whereas negative values indicate that the
* player's position had progressed beyond the frame's timestamp when the frame was processed (and
* the frame was probably dropped).
*
* <p>The renderer reports the sum of video processing offset samples (one sample per processed
* video frame: dropped, skipped or rendered) and the total number of samples (frames).
*
* @param eventTime The event time.
* @param totalProcessingOffsetUs The sum of video frame processing offset samples for all video
* frames processed by the renderer in microseconds.
* @param frameCount The number to samples included in the {@code totalProcessingOffsetUs}.
* @param format The current output {@link Format} rendered by the video renderer.
*/
default
void
onVideoFrameProcessingOffset
(
EventTime
eventTime
,
long
totalProcessingOffsetUs
,
int
frameCount
,
Format
format
)
{}
/**
* Called before a frame is rendered for the first time since setting the surface, and each time
* there's a change in the size or pixel aspect ratio of the video being rendered.
*
...
...
library/core/src/main/java/com/google/android/exoplayer2/decoder/DecoderCounters.java
View file @
0a612ce3
...
...
@@ -15,8 +15,6 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
decoder
;
import
com.google.android.exoplayer2.util.Util
;
/**
* Maintains decoder event counts, for debugging purposes only.
* <p>
...
...
@@ -84,14 +82,14 @@ public final class DecoderCounters {
* <p>Note: Use {@link #addVideoFrameProcessingOffsetSample(long)} to update this field instead of
* updating it directly.
*/
public
long
videoFrameProcessingOffsetUsSum
;
public
long
totalVideoFrameProcessingOffsetUs
;
/**
* The number of video frame processing offset samples added.
*
* <p>Note: Use {@link #addVideoFrameProcessingOffsetSample(long)} to update this field instead of
* updating it directly.
*/
public
int
videoFrameProcessingOffset
Us
Count
;
public
int
videoFrameProcessingOffsetCount
;
/**
* Should be called to ensure counter values are made visible across threads. The playback thread
...
...
@@ -121,15 +119,14 @@ public final class DecoderCounters {
droppedToKeyframeCount
+=
other
.
droppedToKeyframeCount
;
addVideoFrameProcessingOffsetSamples
(
other
.
videoFrameProcessingOffsetUsSum
,
other
.
videoFrameProcessingOffsetUs
Count
);
other
.
totalVideoFrameProcessingOffsetUs
,
other
.
videoFrameProcessingOffset
Count
);
}
/**
* Adds a video frame processing offset sample to {@link #
videoFrameProcessingOffsetUsSum
} and
* increases {@link #videoFrameProcessingOffset
Us
Count} by one.
* Adds a video frame processing offset sample to {@link #
totalVideoFrameProcessingOffsetUs
} and
* increases {@link #videoFrameProcessingOffsetCount} by one.
*
* <p>This method checks if adding {@code sampleUs} to {@link #videoFrameProcessingOffsetUsSum}
* will cause an overflow, in which case this method is a no-op.
* <p>Convenience method to ensure both fields are updated when adding a sample.
*
* @param sampleUs The sample in microseconds.
*/
...
...
@@ -138,12 +135,7 @@ public final class DecoderCounters {
}
private
void
addVideoFrameProcessingOffsetSamples
(
long
sampleUs
,
int
count
)
{
long
overflowFlag
=
videoFrameProcessingOffsetUsSum
>
0
?
Long
.
MIN_VALUE
:
Long
.
MAX_VALUE
;
long
newSampleSum
=
Util
.
addWithOverflowDefault
(
videoFrameProcessingOffsetUsSum
,
sampleUs
,
overflowFlag
);
if
(
newSampleSum
!=
overflowFlag
)
{
videoFrameProcessingOffsetUsCount
+=
count
;
videoFrameProcessingOffsetUsSum
=
newSampleSum
;
}
totalVideoFrameProcessingOffsetUs
+=
sampleUs
;
videoFrameProcessingOffsetCount
+=
count
;
}
}
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java
View file @
0a612ce3
...
...
@@ -680,6 +680,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
@Nullable
protected
final
Format
getCurrentOutputFormat
()
{
return
outputFormat
;
}
@Nullable
protected
final
MediaCodec
getCodec
()
{
return
codec
;
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java
View file @
0a612ce3
...
...
@@ -138,6 +138,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private
int
consecutiveDroppedFrameCount
;
private
int
buffersInCodecCount
;
private
long
lastRenderTimeUs
;
private
long
totalVideoFrameProcessingOffsetUs
;
private
int
videoFrameProcessingOffsetCount
;
private
int
pendingRotationDegrees
;
private
float
pendingPixelWidthHeightRatio
;
...
...
@@ -510,12 +512,15 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
droppedFrames
=
0
;
droppedFrameAccumulationStartTimeMs
=
SystemClock
.
elapsedRealtime
();
lastRenderTimeUs
=
SystemClock
.
elapsedRealtime
()
*
1000
;
totalVideoFrameProcessingOffsetUs
=
0
;
videoFrameProcessingOffsetCount
=
0
;
}
@Override
protected
void
onStopped
()
{
joiningDeadlineMs
=
C
.
TIME_UNSET
;
maybeNotifyDroppedFrames
();
maybeNotifyVideoFrameProcessingOffset
();
super
.
onStopped
();
}
...
...
@@ -751,6 +756,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
+
1
:
outputMediaFormat
.
getInteger
(
MediaFormat
.
KEY_HEIGHT
);
processOutputFormat
(
codec
,
mediaFormatWidth
,
mediaFormatHeight
);
maybeNotifyVideoFrameProcessingOffset
();
}
@Override
...
...
@@ -1216,6 +1222,22 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
}
}
private
void
maybeNotifyVideoFrameProcessingOffset
()
{
Format
outputFormat
=
getCurrentOutputFormat
();
if
(
outputFormat
!=
null
)
{
long
totalOffsetDelta
=
decoderCounters
.
totalVideoFrameProcessingOffsetUs
-
totalVideoFrameProcessingOffsetUs
;
int
countDelta
=
decoderCounters
.
videoFrameProcessingOffsetCount
-
videoFrameProcessingOffsetCount
;
if
(
countDelta
!=
0
)
{
eventDispatcher
.
reportVideoFrameProcessingOffset
(
totalOffsetDelta
,
countDelta
,
outputFormat
);
totalVideoFrameProcessingOffsetUs
=
decoderCounters
.
totalVideoFrameProcessingOffsetUs
;
videoFrameProcessingOffsetCount
=
decoderCounters
.
videoFrameProcessingOffsetCount
;
}
}
}
private
static
boolean
isBufferLate
(
long
earlyUs
)
{
// Class a buffer as late if it should have been presented more than 30 ms ago.
return
earlyUs
<
-
30000
;
...
...
library/core/src/main/java/com/google/android/exoplayer2/video/VideoRendererEventListener.java
View file @
0a612ce3
...
...
@@ -72,6 +72,28 @@ public interface VideoRendererEventListener {
default
void
onDroppedFrames
(
int
count
,
long
elapsedMs
)
{}
/**
* Called to report the video processing offset of video frames processed by the video renderer.
*
* <p>Video processing offset represents how early a video frame is processed compared to the
* player's current position. For each video frame, the offset is calculated as <em>P<sub>vf</sub>
* - P<sub>pl</sub></em> where <em>P<sub>vf</sub></em> is the presentation timestamp of the video
* frame and <em>P<sub>pl</sub></em> is the current position of the player. Positive values
* indicate the frame was processed early enough whereas negative values indicate that the
* player's position had progressed beyond the frame's timestamp when the frame was processed (and
* the frame was probably dropped).
*
* <p>The renderer reports the sum of video processing offset samples (one sample per processed
* video frame: dropped, skipped or rendered) and the total number of samples.
*
* @param totalProcessingOffsetUs The sum of all video frame processing offset samples for the
* video frames processed by the renderer in microseconds.
* @param frameCount The number of samples included in the {@code totalProcessingOffsetUs}.
* @param format The {@link Format} that is currently output.
*/
default
void
onVideoFrameProcessingOffset
(
long
totalProcessingOffsetUs
,
int
frameCount
,
Format
format
)
{}
/**
* Called before a frame is rendered for the first time since setting the surface, and each time
* there's a change in the size, rotation or pixel aspect ratio of the video being rendered.
*
...
...
@@ -159,6 +181,17 @@ public interface VideoRendererEventListener {
}
}
/** Invokes {@link VideoRendererEventListener#onVideoFrameProcessingOffset}. */
public
void
reportVideoFrameProcessingOffset
(
long
totalProcessingOffsetUs
,
int
frameCount
,
Format
format
)
{
if
(
handler
!=
null
)
{
handler
.
post
(
()
->
castNonNull
(
listener
)
.
onVideoFrameProcessingOffset
(
totalProcessingOffsetUs
,
frameCount
,
format
));
}
}
/** Invokes {@link VideoRendererEventListener#onVideoSizeChanged(int, int, int, float)}. */
public
void
videoSizeChanged
(
int
width
,
...
...
library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java
View file @
0a612ce3
...
...
@@ -107,6 +107,7 @@ public final class AnalyticsCollectorTest {
private
static
final
int
EVENT_DRM_KEYS_REMOVED
=
36
;
private
static
final
int
EVENT_DRM_SESSION_ACQUIRED
=
37
;
private
static
final
int
EVENT_DRM_SESSION_RELEASED
=
38
;
private
static
final
int
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
=
39
;
private
static
final
int
TIMEOUT_MS
=
10000
;
private
static
final
Timeline
SINGLE_PERIOD_TIMELINE
=
new
FakeTimeline
(
/* windowCount= */
1
);
...
...
@@ -181,6 +182,7 @@ public final class AnalyticsCollectorTest {
assertThat
(
listener
.
getEvents
(
EVENT_DROPPED_VIDEO_FRAMES
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_SIZE_CHANGED
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
)).
containsExactly
(
period0
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -241,6 +243,7 @@ public final class AnalyticsCollectorTest {
assertThat
(
listener
.
getEvents
(
EVENT_DROPPED_VIDEO_FRAMES
)).
containsExactly
(
period1
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_SIZE_CHANGED
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
)).
containsExactly
(
period1
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -295,6 +298,7 @@ public final class AnalyticsCollectorTest {
assertThat
(
listener
.
getEvents
(
EVENT_DROPPED_VIDEO_FRAMES
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_SIZE_CHANGED
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
)).
containsExactly
(
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
)).
containsExactly
(
period0
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -442,6 +446,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
period0
,
period1Seq2
,
period1Seq2
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_SIZE_CHANGED
)).
containsExactly
(
period0
,
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
)).
containsExactly
(
period0
,
period0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
period0
,
period1Seq2
,
period1Seq2
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -518,6 +524,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
period0Seq0
,
period0Seq1
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
))
.
containsExactly
(
period0Seq0
,
period0Seq1
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
period0Seq1
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -587,6 +595,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
period0Seq0
,
period0Seq0
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
))
.
containsExactly
(
period0Seq0
,
period0Seq0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
period0Seq0
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -665,6 +675,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
window0Period1Seq0
,
period1Seq0
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
))
.
containsExactly
(
window0Period1Seq0
,
period1Seq0
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
window0Period1Seq0
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -735,6 +747,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
period0Seq0
,
period0Seq1
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
))
.
containsExactly
(
period0Seq0
,
period0Seq1
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
period0Seq1
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -952,6 +966,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
contentAfterPreroll
,
contentAfterMidroll
,
contentAfterPostroll
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_SIZE_CHANGED
)).
containsExactly
(
prerollAd
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
)).
containsExactly
(
prerollAd
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
contentAfterPreroll
,
contentAfterMidroll
,
contentAfterPostroll
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -1069,6 +1085,8 @@ public final class AnalyticsCollectorTest {
.
containsExactly
(
contentBeforeMidroll
,
midrollAd
);
assertThat
(
listener
.
getEvents
(
EVENT_RENDERED_FIRST_FRAME
))
.
containsExactly
(
contentBeforeMidroll
,
midrollAd
);
assertThat
(
listener
.
getEvents
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
))
.
containsExactly
(
contentAfterMidroll
);
listener
.
assertNoMoreEvents
();
}
...
...
@@ -1196,6 +1214,8 @@ public final class AnalyticsCollectorTest {
protected
void
onStopped
()
throws
ExoPlaybackException
{
super
.
onStopped
();
eventDispatcher
.
droppedFrames
(
/* droppedFrameCount= */
0
,
/* elapsedMs= */
0
);
eventDispatcher
.
reportVideoFrameProcessingOffset
(
/* totalProcessingOffsetUs= */
400000
,
/* frameCount= */
10
,
this
.
format
);
}
@Override
...
...
@@ -1561,6 +1581,12 @@ public final class AnalyticsCollectorTest {
reportedEvents
.
add
(
new
ReportedEvent
(
EVENT_DRM_SESSION_RELEASED
,
eventTime
));
}
@Override
public
void
onVideoFrameProcessingOffset
(
EventTime
eventTime
,
long
totalProcessingOffsetUs
,
int
frameCount
,
Format
format
)
{
reportedEvents
.
add
(
new
ReportedEvent
(
EVENT_VIDEO_FRAME_PROCESSING_OFFSET
,
eventTime
));
}
private
static
final
class
ReportedEvent
{
public
final
int
eventType
;
...
...
library/core/src/test/java/com/google/android/exoplayer2/decoder/DecoderCountersTest.java
deleted
100644 → 0
View file @
51045482
/*
* Copyright (C) 2020 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
com
.
google
.
android
.
exoplayer2
.
decoder
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit tests for {@link DecoderCounters}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
DecoderCountersTest
{
private
DecoderCounters
decoderCounters
;
@Before
public
void
setUp
()
{
decoderCounters
=
new
DecoderCounters
();
}
@Test
public
void
maybeAddVideoFrameProcessingOffsetSample_addsSamples
()
{
long
sampleSum
=
0
;
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
long
sample
=
(
i
+
10
)
*
10L
;
sampleSum
+=
sample
;
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
sample
);
}
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsSum
).
isEqualTo
(
sampleSum
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsCount
).
isEqualTo
(
100
);
}
@Test
public
void
addVideoFrameProcessingOffsetSample_sumReachesMaxLong_addsValues
()
{
long
highSampleValue
=
Long
.
MAX_VALUE
-
10
;
long
additionalSample
=
Long
.
MAX_VALUE
-
highSampleValue
;
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
highSampleValue
);
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
additionalSample
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsSum
).
isEqualTo
(
Long
.
MAX_VALUE
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsCount
).
isEqualTo
(
2
);
}
@Test
public
void
addVideoFrameProcessingOffsetSample_sumOverflows_isNoOp
()
{
long
highSampleValue
=
Long
.
MAX_VALUE
-
10
;
long
additionalSample
=
Long
.
MAX_VALUE
-
highSampleValue
+
10
;
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
highSampleValue
);
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
additionalSample
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsSum
).
isEqualTo
(
highSampleValue
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsCount
).
isEqualTo
(
1
);
}
@Test
public
void
addVideoFrameProcessingOffsetSample_sumReachesMinLong_addsValues
()
{
long
lowSampleValue
=
Long
.
MIN_VALUE
+
10
;
long
additionalSample
=
Long
.
MIN_VALUE
-
lowSampleValue
;
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
lowSampleValue
);
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
additionalSample
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsSum
).
isEqualTo
(
Long
.
MIN_VALUE
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsCount
).
isEqualTo
(
2
);
}
@Test
public
void
addVideoFrameProcessingOffsetSample_sumUnderflows_isNoOp
()
{
long
lowSampleValue
=
Long
.
MIN_VALUE
+
10
;
long
additionalSample
=
Long
.
MIN_VALUE
-
lowSampleValue
-
10
;
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
lowSampleValue
);
decoderCounters
.
addVideoFrameProcessingOffsetSample
(
additionalSample
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsSum
).
isEqualTo
(
lowSampleValue
);
assertThat
(
decoderCounters
.
videoFrameProcessingOffsetUsCount
).
isEqualTo
(
1
);
}
}
library/ui/src/main/java/com/google/android/exoplayer2/ui/DebugTextViewHelper.java
View file @
0a612ce3
...
...
@@ -158,7 +158,9 @@ public class DebugTextViewHelper implements Player.EventListener, Runnable {
+
getPixelAspectRatioString
(
format
.
pixelWidthHeightRatio
)
+
getDecoderCountersBufferCountString
(
decoderCounters
)
+
" vfpo: "
+
getVideoFrameProcessingOffsetAverageString
(
decoderCounters
)
+
getVideoFrameProcessingOffsetAverageString
(
decoderCounters
.
totalVideoFrameProcessingOffsetUs
,
decoderCounters
.
videoFrameProcessingOffsetCount
)
+
")"
;
}
...
...
@@ -199,13 +201,12 @@ public class DebugTextViewHelper implements Player.EventListener, Runnable {
:
(
" par:"
+
String
.
format
(
Locale
.
US
,
"%.02f"
,
pixelAspectRatio
));
}
private
static
String
getVideoFrameProcessingOffsetAverageString
(
DecoderCounters
counters
)
{
counters
.
ensureUpdated
();
int
sampleCount
=
counters
.
videoFrameProcessingOffsetUsCount
;
if
(
sampleCount
==
0
)
{
private
static
String
getVideoFrameProcessingOffsetAverageString
(
long
totalOffsetUs
,
int
frameCount
)
{
if
(
frameCount
==
0
)
{
return
"N/A"
;
}
else
{
long
averageUs
=
(
long
)
((
double
)
counters
.
videoFrameProcessingOffsetUsSum
/
sampl
eCount
);
long
averageUs
=
(
long
)
((
double
)
totalOffsetUs
/
fram
eCount
);
return
String
.
valueOf
(
averageUs
);
}
}
...
...
testutils/src/main/java/com/google/android/exoplayer2/testutil/DecoderCountersUtil.java
View file @
0a612ce3
...
...
@@ -100,7 +100,7 @@ public final class DecoderCountersUtil {
public
static
void
assertVideoFrameProcessingOffsetSampleCount
(
String
name
,
DecoderCounters
counters
,
int
minCount
,
int
maxCount
)
{
int
actual
=
counters
.
videoFrameProcessingOffset
Us
Count
;
int
actual
=
counters
.
videoFrameProcessingOffsetCount
;
assertWithMessage
(
"Codec("
+
name
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment