Commit a4ad85d2 by tofunmi Committed by christosts

InternalTextureManager: delete texture after use

PiperOrigin-RevId: 510377977
parent 7614ac47
...@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.util.VideoFrameProcessingException; ...@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.util.VideoFrameProcessingException;
import com.google.android.exoplayer2.util.VideoFrameProcessor; import com.google.android.exoplayer2.util.VideoFrameProcessor;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /**
* Forwards a video frame produced from a {@link Bitmap} to a {@link GlShaderProgram} for * Forwards a video frame produced from a {@link Bitmap} to a {@link GlShaderProgram} for
...@@ -41,10 +42,12 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -41,10 +42,12 @@ import java.util.concurrent.LinkedBlockingQueue;
// The queue holds all bitmaps with one or more frames pending to be sent downstream. // The queue holds all bitmaps with one or more frames pending to be sent downstream.
private final Queue<BitmapFrameSequenceInfo> pendingBitmaps; private final Queue<BitmapFrameSequenceInfo> pendingBitmaps;
private @MonotonicNonNull TextureInfo currentTextureInfo;
private int downstreamShaderProgramCapacity; private int downstreamShaderProgramCapacity;
private int framesToQueueForCurrentBitmap; private int framesToQueueForCurrentBitmap;
private long currentPresentationTimeUs; private long currentPresentationTimeUs;
private boolean inputEnded; private boolean inputEnded;
private boolean useHdr;
private boolean outputEnded; private boolean outputEnded;
/** /**
...@@ -65,10 +68,6 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -65,10 +68,6 @@ import java.util.concurrent.LinkedBlockingQueue;
@Override @Override
public void onReadyToAcceptInputFrame() { public void onReadyToAcceptInputFrame() {
// TODO(b/262693274): Delete texture when last duplicate of the frame comes back from the shader
// program and change to only allocate one texId at a time. A change to the
// onInputFrameProcessed() method signature to include presentationTimeUs will probably be
// needed to do this.
videoFrameProcessingTaskExecutor.submit( videoFrameProcessingTaskExecutor.submit(
() -> { () -> {
downstreamShaderProgramCapacity++; downstreamShaderProgramCapacity++;
...@@ -103,48 +102,54 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -103,48 +102,54 @@ import java.util.concurrent.LinkedBlockingQueue;
@WorkerThread @WorkerThread
private void setupBitmap(Bitmap bitmap, long durationUs, float frameRate, boolean useHdr) private void setupBitmap(Bitmap bitmap, long durationUs, float frameRate, boolean useHdr)
throws VideoFrameProcessingException { throws VideoFrameProcessingException {
this.useHdr = useHdr;
if (inputEnded) { if (inputEnded) {
return; return;
} }
int bitmapTexId;
try {
bitmapTexId =
GlUtil.createTexture(
bitmap.getWidth(), bitmap.getHeight(), /* useHighPrecisionColorComponents= */ useHdr);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, bitmapTexId);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, /* level= */ 0, bitmap, /* border= */ 0);
GlUtil.checkGlError();
} catch (GlUtil.GlException e) {
throw VideoFrameProcessingException.from(e);
}
TextureInfo textureInfo =
new TextureInfo(
bitmapTexId, /* fboId= */ C.INDEX_UNSET, bitmap.getWidth(), bitmap.getHeight());
int framesToAdd = (int) floor(frameRate * (durationUs / (float) C.MICROS_PER_SECOND)); int framesToAdd = (int) floor(frameRate * (durationUs / (float) C.MICROS_PER_SECOND));
long frameDurationUs = (long) floor(C.MICROS_PER_SECOND / frameRate); long frameDurationUs = (long) floor(C.MICROS_PER_SECOND / frameRate);
pendingBitmaps.add(new BitmapFrameSequenceInfo(textureInfo, frameDurationUs, framesToAdd)); pendingBitmaps.add(new BitmapFrameSequenceInfo(bitmap, frameDurationUs, framesToAdd));
maybeQueueToShaderProgram(); maybeQueueToShaderProgram();
} }
@WorkerThread @WorkerThread
private void maybeQueueToShaderProgram() { private void maybeQueueToShaderProgram() throws VideoFrameProcessingException {
if (pendingBitmaps.isEmpty() || downstreamShaderProgramCapacity == 0) { if (pendingBitmaps.isEmpty() || downstreamShaderProgramCapacity == 0) {
return; return;
} }
BitmapFrameSequenceInfo currentBitmap = checkNotNull(pendingBitmaps.peek()); BitmapFrameSequenceInfo currentBitmapInfo = checkNotNull(pendingBitmaps.peek());
if (framesToQueueForCurrentBitmap == 0) { if (framesToQueueForCurrentBitmap == 0) {
framesToQueueForCurrentBitmap = currentBitmap.numberOfFrames; Bitmap bitmap = currentBitmapInfo.bitmap;
framesToQueueForCurrentBitmap = currentBitmapInfo.numberOfFrames;
int currentTexId;
try {
if (currentTextureInfo != null) {
GlUtil.deleteTexture(currentTextureInfo.texId);
}
currentTexId =
GlUtil.createTexture(
bitmap.getWidth(),
bitmap.getHeight(),
/* useHighPrecisionColorComponents= */ useHdr);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, currentTexId);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, /* level= */ 0, bitmap, /* border= */ 0);
GlUtil.checkGlError();
} catch (GlUtil.GlException e) {
throw VideoFrameProcessingException.from(e);
}
currentTextureInfo =
new TextureInfo(
currentTexId, /* fboId= */ C.INDEX_UNSET, bitmap.getWidth(), bitmap.getHeight());
} }
framesToQueueForCurrentBitmap--; framesToQueueForCurrentBitmap--;
downstreamShaderProgramCapacity--; downstreamShaderProgramCapacity--;
shaderProgram.queueInputFrame(currentBitmap.textureInfo, currentPresentationTimeUs); shaderProgram.queueInputFrame(checkNotNull(currentTextureInfo), currentPresentationTimeUs);
currentPresentationTimeUs += currentBitmap.frameDurationUs; currentPresentationTimeUs += currentBitmapInfo.frameDurationUs;
if (framesToQueueForCurrentBitmap == 0) { if (framesToQueueForCurrentBitmap == 0) {
pendingBitmaps.remove(); pendingBitmaps.remove();
maybeSignalEndOfOutput(); maybeSignalEndOfOutput();
...@@ -164,13 +169,12 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -164,13 +169,12 @@ import java.util.concurrent.LinkedBlockingQueue;
/** Information to generate all the frames associated with a specific {@link Bitmap}. */ /** Information to generate all the frames associated with a specific {@link Bitmap}. */
private static final class BitmapFrameSequenceInfo { private static final class BitmapFrameSequenceInfo {
public final TextureInfo textureInfo; public final Bitmap bitmap;
public final long frameDurationUs; public final long frameDurationUs;
public final int numberOfFrames; public final int numberOfFrames;
public BitmapFrameSequenceInfo( public BitmapFrameSequenceInfo(Bitmap bitmap, long frameDurationUs, int numberOfFrames) {
TextureInfo textureInfo, long frameDurationUs, int numberOfFrames) { this.bitmap = bitmap;
this.textureInfo = textureInfo;
this.frameDurationUs = frameDurationUs; this.frameDurationUs = frameDurationUs;
this.numberOfFrames = numberOfFrames; 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