Commit 3ef609fa by olly Committed by Ian Baker

Plumb playback speed and frame-rate via VideoFrameReleaseTimeHelper

PiperOrigin-RevId: 342289646
parent f6928c0e
...@@ -141,7 +141,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -141,7 +141,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private int currentHeight; private int currentHeight;
private int currentUnappliedRotationDegrees; private int currentUnappliedRotationDegrees;
private float currentPixelWidthHeightRatio; private float currentPixelWidthHeightRatio;
private float currentFrameRate;
private int reportedWidth; private int reportedWidth;
private int reportedHeight; private int reportedHeight;
private int reportedUnappliedRotationDegrees; private int reportedUnappliedRotationDegrees;
...@@ -588,6 +587,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -588,6 +587,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override @Override
public void setPlaybackSpeed(float playbackSpeed) throws ExoPlaybackException { public void setPlaybackSpeed(float playbackSpeed) throws ExoPlaybackException {
super.setPlaybackSpeed(playbackSpeed); super.setPlaybackSpeed(playbackSpeed);
frameReleaseTimeHelper.setPlaybackSpeed(playbackSpeed);
updateSurfaceFrameRate(/* isNewSurface= */ false); updateSurfaceFrameRate(/* isNewSurface= */ false);
} }
...@@ -690,7 +690,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -690,7 +690,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// On API level 20 and below the decoder does not apply the rotation. // On API level 20 and below the decoder does not apply the rotation.
currentUnappliedRotationDegrees = format.rotationDegrees; currentUnappliedRotationDegrees = format.rotationDegrees;
} }
currentFrameRate = format.frameRate; frameReleaseTimeHelper.setFormatFrameRate(format.frameRate);
updateSurfaceFrameRate(/* isNewSurface= */ false); updateSurfaceFrameRate(/* isNewSurface= */ false);
} }
...@@ -1079,8 +1079,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1079,8 +1079,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (Util.SDK_INT < 30 || surface == null || surface == dummySurface) { if (Util.SDK_INT < 30 || surface == null || surface == dummySurface) {
return; return;
} }
boolean shouldSetFrameRate = getState() == STATE_STARTED && currentFrameRate != Format.NO_VALUE; float playbackFrameRate = frameReleaseTimeHelper.getPlaybackFrameRate();
float surfaceFrameRate = shouldSetFrameRate ? currentFrameRate * getPlaybackSpeed() : 0; 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 // 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. // it might have been set to previously.
if (this.surfaceFrameRate == surfaceFrameRate && !isNewSurface) { if (this.surfaceFrameRate == surfaceFrameRate && !isNewSurface) {
......
...@@ -28,6 +28,7 @@ import android.view.WindowManager; ...@@ -28,6 +28,7 @@ import android.view.WindowManager;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
/** /**
...@@ -45,6 +46,9 @@ public final class VideoFrameReleaseTimeHelper { ...@@ -45,6 +46,9 @@ public final class VideoFrameReleaseTimeHelper {
@Nullable private final VSyncSampler vsyncSampler; @Nullable private final VSyncSampler vsyncSampler;
@Nullable private final DefaultDisplayListener displayListener; @Nullable private final DefaultDisplayListener displayListener;
private float formatFrameRate;
private float playbackSpeed;
private long vsyncDurationNs; private long vsyncDurationNs;
private long vsyncOffsetNs; private long vsyncOffsetNs;
...@@ -87,9 +91,11 @@ public final class VideoFrameReleaseTimeHelper { ...@@ -87,9 +91,11 @@ public final class VideoFrameReleaseTimeHelper {
} }
vsyncDurationNs = C.TIME_UNSET; vsyncDurationNs = C.TIME_UNSET;
vsyncOffsetNs = 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. @TargetApi(17) // displayListener is null if Util.SDK_INT < 17.
public void enable() { public void enable() {
haveSync = false; haveSync = false;
...@@ -102,7 +108,7 @@ public final class VideoFrameReleaseTimeHelper { ...@@ -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. @TargetApi(17) // displayListener is null if Util.SDK_INT < 17.
public void disable() { public void disable() {
if (windowManager != null) { if (windowManager != null) {
...@@ -113,12 +119,36 @@ public final class VideoFrameReleaseTimeHelper { ...@@ -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);
}
/**
* 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. Must be called from the playback thread. * Adjusts a frame release timestamp.
* *
* @param framePresentationTimeUs The frame's presentation time, in microseconds. * @param framePresentationTimeUs The frame's presentation time, in microseconds.
* @param unadjustedReleaseTimeNs The frame's unadjusted release time, in nanoseconds and in * @param unadjustedReleaseTimeNs The frame's unadjusted release time, in nanoseconds and in the
* the same time base as {@link System#nanoTime()}. * same time 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()}.
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment