Commit f29da34d by huangdarwin Committed by tonihei

Effect: Update InternalTextureManager to use double timestamps.

Instead of using a long frameDurationUs with Math.floor, use a double
frameDurationUs with Math.round,

Before, playing an image with 30 fps over 1 second would result in the final
timestamp not being aligned to the expected 1 second timestamp. Over long
periods of time, this can lead to significant timestamp drift. Additionally,
for TimestampWrapper and constrained multi-asset, where TimestampWrapper
begins the 2nd effect on the 2nd asset's startTimeUs, this floor() behavior
can lead to the first few frames of the 2nd asset using the first asset's
effects, due to timestamps being mismatched.

PiperOrigin-RevId: 516529240
parent 4fe8195c
......@@ -16,7 +16,7 @@
package com.google.android.exoplayer2.effect;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static java.lang.Math.floor;
import static java.lang.Math.round;
import android.graphics.Bitmap;
import android.opengl.GLES20;
......@@ -45,7 +45,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private @MonotonicNonNull GlTextureInfo currentGlTextureInfo;
private int downstreamShaderProgramCapacity;
private int framesToQueueForCurrentBitmap;
private long currentPresentationTimeUs;
private double currentPresentationTimeUs;
private boolean inputEnded;
private boolean useHdr;
private boolean outputEnded;
......@@ -107,8 +107,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (inputEnded) {
return;
}
int framesToAdd = (int) floor(frameRate * (durationUs / (float) C.MICROS_PER_SECOND));
long frameDurationUs = (long) floor(C.MICROS_PER_SECOND / frameRate);
int framesToAdd = round(frameRate * (durationUs / (float) C.MICROS_PER_SECOND));
double frameDurationUs = C.MICROS_PER_SECOND / frameRate;
pendingBitmaps.add(new BitmapFrameSequenceInfo(bitmap, frameDurationUs, framesToAdd));
maybeQueueToShaderProgram();
......@@ -151,7 +151,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
framesToQueueForCurrentBitmap--;
downstreamShaderProgramCapacity--;
shaderProgram.queueInputFrame(checkNotNull(currentGlTextureInfo), currentPresentationTimeUs);
shaderProgram.queueInputFrame(
checkNotNull(currentGlTextureInfo), round(currentPresentationTimeUs));
currentPresentationTimeUs += currentBitmapInfo.frameDurationUs;
if (framesToQueueForCurrentBitmap == 0) {
......@@ -173,10 +174,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Information to generate all the frames associated with a specific {@link Bitmap}. */
private static final class BitmapFrameSequenceInfo {
public final Bitmap bitmap;
public final long frameDurationUs;
public final double frameDurationUs;
public final int numberOfFrames;
public BitmapFrameSequenceInfo(Bitmap bitmap, long frameDurationUs, int numberOfFrames) {
public BitmapFrameSequenceInfo(Bitmap bitmap, double frameDurationUs, int numberOfFrames) {
this.bitmap = bitmap;
this.frameDurationUs = frameDurationUs;
this.numberOfFrames = numberOfFrames;
......
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