Plumb playback speed and frame-rate via VideoFrameReleaseTimeHelper

PiperOrigin-RevId: 342289646
This commit is contained in:
olly 2020-11-13 18:28:55 +00:00 committed by Ian Baker
parent f6928c0ef9
commit 3ef609fa3b
2 changed files with 40 additions and 9 deletions

View file

@ -141,7 +141,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private int currentHeight;
private int currentUnappliedRotationDegrees;
private float currentPixelWidthHeightRatio;
private float currentFrameRate;
private int reportedWidth;
private int reportedHeight;
private int reportedUnappliedRotationDegrees;
@ -588,6 +587,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override
public void setPlaybackSpeed(float playbackSpeed) throws ExoPlaybackException {
super.setPlaybackSpeed(playbackSpeed);
frameReleaseTimeHelper.setPlaybackSpeed(playbackSpeed);
updateSurfaceFrameRate(/* isNewSurface= */ false);
}
@ -690,7 +690,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// On API level 20 and below the decoder does not apply the rotation.
currentUnappliedRotationDegrees = format.rotationDegrees;
}
currentFrameRate = format.frameRate;
frameReleaseTimeHelper.setFormatFrameRate(format.frameRate);
updateSurfaceFrameRate(/* isNewSurface= */ false);
}
@ -1079,8 +1079,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (Util.SDK_INT < 30 || surface == null || surface == dummySurface) {
return;
}
boolean shouldSetFrameRate = getState() == STATE_STARTED && currentFrameRate != Format.NO_VALUE;
float surfaceFrameRate = shouldSetFrameRate ? currentFrameRate * getPlaybackSpeed() : 0;
float playbackFrameRate = frameReleaseTimeHelper.getPlaybackFrameRate();
float surfaceFrameRate =
getState() == STATE_STARTED && playbackFrameRate != C.RATE_UNSET ? playbackFrameRate : 0;
// We always set the frame-rate if we have a new surface, since we have no way of knowing what
// it might have been set to previously.
if (this.surfaceFrameRate == surfaceFrameRate && !isNewSurface) {

View file

@ -28,6 +28,7 @@ import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.Util;
/**
@ -45,6 +46,9 @@ public final class VideoFrameReleaseTimeHelper {
@Nullable private final VSyncSampler vsyncSampler;
@Nullable private final DefaultDisplayListener displayListener;
private float formatFrameRate;
private float playbackSpeed;
private long vsyncDurationNs;
private long vsyncOffsetNs;
@ -87,9 +91,11 @@ public final class VideoFrameReleaseTimeHelper {
}
vsyncDurationNs = C.TIME_UNSET;
vsyncOffsetNs = C.TIME_UNSET;
formatFrameRate = Format.NO_VALUE;
playbackSpeed = 1f;
}
/** Enables the helper. Must be called from the playback thread. */
/** Enables the helper. */
@TargetApi(17) // displayListener is null if Util.SDK_INT < 17.
public void enable() {
haveSync = false;
@ -102,7 +108,7 @@ public final class VideoFrameReleaseTimeHelper {
}
}
/** Disables the helper. Must be called from the playback thread. */
/** Disables the helper. */
@TargetApi(17) // displayListener is null if Util.SDK_INT < 17.
public void disable() {
if (windowManager != null) {
@ -113,12 +119,36 @@ public final class VideoFrameReleaseTimeHelper {
}
}
/** Returns the estimated playback frame rate, or {@link C#RATE_UNSET} if unknown. */
public float getPlaybackFrameRate() {
return formatFrameRate == Format.NO_VALUE ? C.RATE_UNSET : (formatFrameRate * playbackSpeed);
}
/**
* Adjusts a frame release timestamp. Must be called from the playback thread.
* Sets the player's speed, where 1 is the default rate, 2 is twice the default rate, 0.5 is half
* the default rate and so on.
*
* @param playbackSpeed The player's speed.
*/
public void setPlaybackSpeed(float playbackSpeed) {
this.playbackSpeed = playbackSpeed;
}
/**
* Sets the format's frame rate in frames per second, or {@link Format#NO_VALUE} if unknown.
*
* @param formatFrameRate The format's frame rate, or {@link Format#NO_VALUE}.
*/
public void setFormatFrameRate(float formatFrameRate) {
this.formatFrameRate = formatFrameRate;
}
/**
* Adjusts a frame release timestamp.
*
* @param framePresentationTimeUs The frame's presentation time, in microseconds.
* @param unadjustedReleaseTimeNs The frame's unadjusted release time, in nanoseconds and in
* the same time base as {@link System#nanoTime()}.
* @param unadjustedReleaseTimeNs The frame's unadjusted release time, in nanoseconds and in the
* same time base as {@link System#nanoTime()}.
* @return The adjusted frame release timestamp, in nanoseconds and in the same time base as
* {@link System#nanoTime()}.
*/