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
8192bb55
authored
Dec 02, 2020
by
olly
Committed by
Oliver Woodman
Dec 03, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
VideoFrameReleaseTimeHelper: Simplify and add comments
PiperOrigin-RevId: 345198316
parent
69dcad71
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
36 additions
and
30 deletions
library/core/src/main/java/com/google/android/exoplayer2/video/VideoFrameReleaseTimeHelper.java
library/core/src/main/java/com/google/android/exoplayer2/video/VideoFrameReleaseTimeHelper.java
View file @
8192bb55
...
@@ -38,10 +38,20 @@ import com.google.android.exoplayer2.util.Util;
...
@@ -38,10 +38,20 @@ import com.google.android.exoplayer2.util.Util;
*/
*/
public
final
class
VideoFrameReleaseTimeHelper
{
public
final
class
VideoFrameReleaseTimeHelper
{
private
static
final
long
CHOREOGRAPHER_SAMPLE_DELAY_MILLIS
=
500
;
/** The period between sampling display VSYNC timestamps, in milliseconds. */
private
static
final
long
MAX_ALLOWED_DRIFT_NS
=
20_000_000
;
private
static
final
long
VSYNC_SAMPLE_UPDATE_PERIOD_MS
=
500
;
/**
* The maximum adjustment that can be made to a frame release timestamp, in nanoseconds, excluding
* the part of the adjustment that aligns frame release timestamps with the display VSYNC.
*/
private
static
final
long
MAX_ALLOWED_ADJUSTMENT_NS
=
20_000_000
;
/**
* If a frame is targeted to a display VSYNC with timestamp {@code vsyncTime}, the adjusted frame
* release timestamp will be calculated as {@code releaseTime = vsyncTime - ((vsyncDuration *
* VSYNC_OFFSET_PERCENTAGE) / 100)}.
*/
private
static
final
long
VSYNC_OFFSET_PERCENTAGE
=
80
;
private
static
final
long
VSYNC_OFFSET_PERCENTAGE
=
80
;
private
static
final
int
MIN_FRAMES_FOR_ADJUSTMENT
=
6
;
private
static
final
int
MIN_FRAMES_FOR_ADJUSTMENT
=
6
;
@Nullable
private
final
WindowManager
windowManager
;
@Nullable
private
final
WindowManager
windowManager
;
...
@@ -56,14 +66,14 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -56,14 +66,14 @@ public final class VideoFrameReleaseTimeHelper {
private
long
vsyncOffsetNs
;
private
long
vsyncOffsetNs
;
private
boolean
haveSync
;
private
boolean
haveSync
;
private
long
sync
Unadjusted
ReleaseTimeNs
;
private
long
syncReleaseTimeNs
;
private
long
syncFramePresentationTimeNs
;
private
long
syncFramePresentationTimeNs
;
private
long
frameCount
;
private
long
frameCount
;
private
long
pendingLastAdjustedFrameIndex
;
private
long
pendingLastAdjustedFrameIndex
;
private
long
pendingLastAdjusted
FramePresentation
TimeNs
;
private
long
pendingLastAdjusted
Release
TimeNs
;
private
long
lastAdjustedFrameIndex
;
private
long
lastAdjustedFrameIndex
;
private
long
lastAdjusted
FramePresentation
TimeNs
;
private
long
lastAdjusted
Release
TimeNs
;
/**
/**
* Constructs an instance that smooths frame release timestamps but does not align them with
* Constructs an instance that smooths frame release timestamps but does not align them with
...
@@ -159,7 +169,7 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -159,7 +169,7 @@ public final class VideoFrameReleaseTimeHelper {
*/
*/
public
void
onNextFrame
(
long
framePresentationTimeUs
)
{
public
void
onNextFrame
(
long
framePresentationTimeUs
)
{
lastAdjustedFrameIndex
=
pendingLastAdjustedFrameIndex
;
lastAdjustedFrameIndex
=
pendingLastAdjustedFrameIndex
;
lastAdjusted
FramePresentationTimeNs
=
pendingLastAdjustedFramePresentation
TimeNs
;
lastAdjusted
ReleaseTimeNs
=
pendingLastAdjustedRelease
TimeNs
;
nextFramePresentationTimeUs
=
framePresentationTimeUs
;
nextFramePresentationTimeUs
=
framePresentationTimeUs
;
frameCount
++;
frameCount
++;
}
}
...
@@ -178,17 +188,16 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -178,17 +188,16 @@ public final class VideoFrameReleaseTimeHelper {
* once (if the caller wishes to give the helper the opportunity to refine a release time closer
* once (if the caller wishes to give the helper the opportunity to refine a release time closer
* to when the frame needs to be released).
* to when the frame needs to be released).
*
*
* @param
unadjustedReleaseTimeNs The frame's unadjusted release time, in nanoseconds and in th
e
* @param
releaseTimeNs The frame's unadjusted release time, in nanoseconds and in the same tim
e
*
same time
base as {@link System#nanoTime()}.
* base as {@link System#nanoTime()}.
* @return The adjusted frame release timestamp, in nanoseconds and in the same time base as
* @return The adjusted frame release timestamp, in nanoseconds and in the same time base as
* {@link System#nanoTime()}.
* {@link System#nanoTime()}.
*/
*/
public
long
adjustReleaseTime
(
long
unadjustedR
eleaseTimeNs
)
{
public
long
adjustReleaseTime
(
long
r
eleaseTimeNs
)
{
long
framePresentationTimeNs
=
nextFramePresentationTimeUs
*
1000
;
long
framePresentationTimeNs
=
nextFramePresentationTimeUs
*
1000
;
// Until we know better, the adjustment will be a no-op.
// Until we know better, the adjustment will be a no-op.
long
adjustedFramePresentationTimeNs
=
framePresentationTimeNs
;
long
adjustedReleaseTimeNs
=
releaseTimeNs
;
long
adjustedReleaseTimeNs
=
unadjustedReleaseTimeNs
;
if
(
haveSync
)
{
if
(
haveSync
)
{
if
(
frameCount
>=
MIN_FRAMES_FOR_ADJUSTMENT
)
{
if
(
frameCount
>=
MIN_FRAMES_FOR_ADJUSTMENT
)
{
...
@@ -199,23 +208,21 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -199,23 +208,21 @@ public final class VideoFrameReleaseTimeHelper {
long
averageFrameDurationNs
=
(
framePresentationTimeNs
-
syncFramePresentationTimeNs
)
long
averageFrameDurationNs
=
(
framePresentationTimeNs
-
syncFramePresentationTimeNs
)
/
frameCount
;
/
frameCount
;
// Project the adjusted frame time forward using the average.
// Project the adjusted frame time forward using the average.
long
candidateAdjusted
FramePresentation
TimeNs
=
long
candidateAdjusted
Release
TimeNs
=
lastAdjusted
FramePresentation
TimeNs
lastAdjusted
Release
TimeNs
+
averageFrameDurationNs
*
(
frameCount
-
lastAdjustedFrameIndex
);
+
averageFrameDurationNs
*
(
frameCount
-
lastAdjustedFrameIndex
);
if
(
isDriftTooLarge
(
candidateAdjustedFramePresentationTimeNs
,
una
djustedReleaseTimeNs
))
{
if
(
adjustmentAllowed
(
releaseTimeNs
,
candidateA
djustedReleaseTimeNs
))
{
haveSync
=
false
;
adjustedReleaseTimeNs
=
candidateAdjustedReleaseTimeNs
;
}
else
{
}
else
{
adjustedFramePresentationTimeNs
=
candidateAdjustedFramePresentationTimeNs
;
haveSync
=
false
;
adjustedReleaseTimeNs
=
syncUnadjustedReleaseTimeNs
+
adjustedFramePresentationTimeNs
-
syncFramePresentationTimeNs
;
}
}
}
else
{
}
else
{
// We're synced but haven't waited the required number of frames to apply an adjustment.
// We're synced but haven't waited the required number of frames to apply an adjustment.
// Check drift anyway.
// Check for drift between the proposed and projected frame release timestamps.
if
(
isDriftTooLarge
(
framePresentationTimeNs
,
unadjustedReleaseTimeNs
))
{
long
projectedReleaseTimeNs
=
syncReleaseTimeNs
+
(
framePresentationTimeNs
-
syncFramePresentationTimeNs
);
if
(!
adjustmentAllowed
(
releaseTimeNs
,
projectedReleaseTimeNs
))
{
haveSync
=
false
;
haveSync
=
false
;
}
}
}
}
...
@@ -224,13 +231,13 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -224,13 +231,13 @@ public final class VideoFrameReleaseTimeHelper {
// If we need to sync, do so now.
// If we need to sync, do so now.
if
(!
haveSync
)
{
if
(!
haveSync
)
{
syncFramePresentationTimeNs
=
framePresentationTimeNs
;
syncFramePresentationTimeNs
=
framePresentationTimeNs
;
sync
UnadjustedReleaseTimeNs
=
unadjustedR
eleaseTimeNs
;
sync
ReleaseTimeNs
=
r
eleaseTimeNs
;
frameCount
=
0
;
frameCount
=
0
;
haveSync
=
true
;
haveSync
=
true
;
}
}
pendingLastAdjustedFrameIndex
=
frameCount
;
pendingLastAdjustedFrameIndex
=
frameCount
;
pendingLastAdjusted
FramePresentationTimeNs
=
adjustedFramePresentation
TimeNs
;
pendingLastAdjusted
ReleaseTimeNs
=
adjustedRelease
TimeNs
;
if
(
vsyncSampler
==
null
||
vsyncDurationNs
==
C
.
TIME_UNSET
)
{
if
(
vsyncSampler
==
null
||
vsyncDurationNs
==
C
.
TIME_UNSET
)
{
return
adjustedReleaseTimeNs
;
return
adjustedReleaseTimeNs
;
...
@@ -262,10 +269,9 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -262,10 +269,9 @@ public final class VideoFrameReleaseTimeHelper {
}
}
}
}
private
boolean
isDriftTooLarge
(
long
frameTimeNs
,
long
releaseTimeNs
)
{
private
static
boolean
adjustmentAllowed
(
long
elapsedFrameTimeNs
=
frameTimeNs
-
syncFramePresentationTimeNs
;
long
unadjustedReleaseTimeNs
,
long
adjustedReleaseTimeNs
)
{
long
elapsedReleaseTimeNs
=
releaseTimeNs
-
syncUnadjustedReleaseTimeNs
;
return
Math
.
abs
(
unadjustedReleaseTimeNs
-
adjustedReleaseTimeNs
)
<=
MAX_ALLOWED_ADJUSTMENT_NS
;
return
Math
.
abs
(
elapsedReleaseTimeNs
-
elapsedFrameTimeNs
)
>
MAX_ALLOWED_DRIFT_NS
;
}
}
private
static
long
closestVsync
(
long
releaseTime
,
long
sampledVsyncTime
,
long
vsyncDuration
)
{
private
static
long
closestVsync
(
long
releaseTime
,
long
sampledVsyncTime
,
long
vsyncDuration
)
{
...
@@ -372,7 +378,7 @@ public final class VideoFrameReleaseTimeHelper {
...
@@ -372,7 +378,7 @@ public final class VideoFrameReleaseTimeHelper {
@Override
@Override
public
void
doFrame
(
long
vsyncTimeNs
)
{
public
void
doFrame
(
long
vsyncTimeNs
)
{
sampledVsyncTimeNs
=
vsyncTimeNs
;
sampledVsyncTimeNs
=
vsyncTimeNs
;
choreographer
.
postFrameCallbackDelayed
(
this
,
CHOREOGRAPHER_SAMPLE_DELAY_MILLI
S
);
choreographer
.
postFrameCallbackDelayed
(
this
,
VSYNC_SAMPLE_UPDATE_PERIOD_M
S
);
}
}
@Override
@Override
...
...
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