mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
InternalTextureManager: delete texture after use
PiperOrigin-RevId: 510377977
This commit is contained in:
parent
7614ac4778
commit
a4ad85d25a
1 changed files with 33 additions and 29 deletions
|
|
@ -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;
|
||||||
// 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;
|
||||||
|
|
||||||
@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;
|
||||||
@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;
|
||||||
|
|
||||||
/** 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue