Flush: Move TextureManager flush logic to abstract class.
This also adds flush support to texture input. PiperOrigin-RevId: 578536040
This commit is contained in:
parent
7b762642db
commit
44f317693b
@ -22,7 +22,6 @@ import static androidx.media3.common.util.Assertions.checkState;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import android.opengl.GLUtils;
|
import android.opengl.GLUtils;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.FrameInfo;
|
import androidx.media3.common.FrameInfo;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
@ -43,7 +42,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* <p>Public methods in this class can be called from any thread.
|
* <p>Public methods in this class can be called from any thread.
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
/* package */ final class BitmapTextureManager implements TextureManager {
|
/* package */ final class BitmapTextureManager extends TextureManager {
|
||||||
|
|
||||||
private static final String UNSUPPORTED_IMAGE_CONFIGURATION =
|
private static final String UNSUPPORTED_IMAGE_CONFIGURATION =
|
||||||
"Unsupported Image Configuration: No more than 8 bits of precision should be used for each"
|
"Unsupported Image Configuration: No more than 8 bits of precision should be used for each"
|
||||||
@ -51,7 +50,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
|
|
||||||
private final GlObjectsProvider glObjectsProvider;
|
private final GlObjectsProvider glObjectsProvider;
|
||||||
private final GlShaderProgram shaderProgram;
|
private final GlShaderProgram shaderProgram;
|
||||||
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
|
|
||||||
// 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;
|
||||||
|
|
||||||
@ -61,8 +59,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
private boolean currentInputStreamEnded;
|
private boolean currentInputStreamEnded;
|
||||||
private boolean isNextFrameInTexture;
|
private boolean isNextFrameInTexture;
|
||||||
|
|
||||||
@Nullable private volatile VideoFrameProcessingTaskExecutor.Task onFlushCompleteTask;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
@ -76,9 +72,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
GlObjectsProvider glObjectsProvider,
|
GlObjectsProvider glObjectsProvider,
|
||||||
GlShaderProgram shaderProgram,
|
GlShaderProgram shaderProgram,
|
||||||
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor) {
|
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor) {
|
||||||
|
super(videoFrameProcessingTaskExecutor);
|
||||||
this.glObjectsProvider = glObjectsProvider;
|
this.glObjectsProvider = glObjectsProvider;
|
||||||
this.shaderProgram = shaderProgram;
|
this.shaderProgram = shaderProgram;
|
||||||
this.videoFrameProcessingTaskExecutor = videoFrameProcessingTaskExecutor;
|
|
||||||
pendingBitmaps = new LinkedBlockingQueue<>();
|
pendingBitmaps = new LinkedBlockingQueue<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,11 +87,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFlush() {
|
|
||||||
videoFrameProcessingTaskExecutor.submit(this::flush);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void queueInputBitmap(
|
public void queueInputBitmap(
|
||||||
Bitmap inputBitmap,
|
Bitmap inputBitmap,
|
||||||
@ -129,11 +120,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task) {
|
|
||||||
onFlushCompleteTask = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void release() {
|
public void release() {
|
||||||
videoFrameProcessingTaskExecutor.submit(
|
videoFrameProcessingTaskExecutor.submit(
|
||||||
@ -199,11 +185,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flush() {
|
@Override
|
||||||
|
protected void flush() {
|
||||||
pendingBitmaps.clear();
|
pendingBitmaps.clear();
|
||||||
if (onFlushCompleteTask != null) {
|
super.flush();
|
||||||
videoFrameProcessingTaskExecutor.submitWithHighPriority(onFlushCompleteTask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Information needed to generate all the frames associated with a specific {@link Bitmap}. */
|
/** Information needed to generate all the frames associated with a specific {@link Bitmap}. */
|
||||||
|
@ -41,7 +41,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
* Forwards externally produced frames that become available via a {@link SurfaceTexture} to an
|
* Forwards externally produced frames that become available via a {@link SurfaceTexture} to an
|
||||||
* {@link ExternalShaderProgram} for consumption.
|
* {@link ExternalShaderProgram} for consumption.
|
||||||
*/
|
*/
|
||||||
/* package */ final class ExternalTextureManager implements TextureManager {
|
/* package */ final class ExternalTextureManager extends TextureManager {
|
||||||
|
|
||||||
private static final String TAG = "ExtTexMgr";
|
private static final String TAG = "ExtTexMgr";
|
||||||
private static final String TIMER_THREAD_NAME = "ExtTexMgr:Timer";
|
private static final String TIMER_THREAD_NAME = "ExtTexMgr:Timer";
|
||||||
@ -62,7 +62,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
: 500;
|
: 500;
|
||||||
|
|
||||||
private final GlObjectsProvider glObjectsProvider;
|
private final GlObjectsProvider glObjectsProvider;
|
||||||
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
|
|
||||||
private final ExternalShaderProgram externalShaderProgram;
|
private final ExternalShaderProgram externalShaderProgram;
|
||||||
private final int externalTexId;
|
private final int externalTexId;
|
||||||
private final Surface surface;
|
private final Surface surface;
|
||||||
@ -87,8 +86,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
// Set to null on any thread. Read and set to non-null on the GL thread only.
|
// Set to null on any thread. Read and set to non-null on the GL thread only.
|
||||||
@Nullable private volatile FrameInfo currentFrame;
|
@Nullable private volatile FrameInfo currentFrame;
|
||||||
|
|
||||||
// TODO(b/238302341) Remove the use of after flush task, block the calling thread instead.
|
|
||||||
@Nullable private volatile VideoFrameProcessingTaskExecutor.Task onFlushCompleteTask;
|
|
||||||
@Nullable private Future<?> forceSignalEndOfStreamFuture;
|
@Nullable private Future<?> forceSignalEndOfStreamFuture;
|
||||||
|
|
||||||
// Whether to reject frames from the SurfaceTexture. Accessed only on GL thread.
|
// Whether to reject frames from the SurfaceTexture. Accessed only on GL thread.
|
||||||
@ -110,9 +107,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
ExternalShaderProgram externalShaderProgram,
|
ExternalShaderProgram externalShaderProgram,
|
||||||
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor)
|
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor)
|
||||||
throws VideoFrameProcessingException {
|
throws VideoFrameProcessingException {
|
||||||
|
super(videoFrameProcessingTaskExecutor);
|
||||||
this.glObjectsProvider = glObjectsProvider;
|
this.glObjectsProvider = glObjectsProvider;
|
||||||
this.externalShaderProgram = externalShaderProgram;
|
this.externalShaderProgram = externalShaderProgram;
|
||||||
this.videoFrameProcessingTaskExecutor = videoFrameProcessingTaskExecutor;
|
|
||||||
try {
|
try {
|
||||||
externalTexId = GlUtil.createExternalTexture();
|
externalTexId = GlUtil.createExternalTexture();
|
||||||
} catch (GlUtil.GlException e) {
|
} catch (GlUtil.GlException e) {
|
||||||
@ -187,16 +184,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task) {
|
|
||||||
onFlushCompleteTask = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFlush() {
|
|
||||||
videoFrameProcessingTaskExecutor.submit(this::flush);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the {@code ExternalTextureManager} that a frame with the given {@link FrameInfo} will
|
* Notifies the {@code ExternalTextureManager} that a frame with the given {@link FrameInfo} will
|
||||||
* become available via the {@link SurfaceTexture} eventually.
|
* become available via the {@link SurfaceTexture} eventually.
|
||||||
@ -245,10 +232,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void maybeExecuteAfterFlushTask() {
|
private void maybeExecuteAfterFlushTask() {
|
||||||
if (onFlushCompleteTask == null || numberOfFramesToDropOnBecomingAvailable > 0) {
|
if (numberOfFramesToDropOnBecomingAvailable > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
videoFrameProcessingTaskExecutor.submitWithHighPriority(onFlushCompleteTask);
|
super.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods that must be called on the GL thread.
|
// Methods that must be called on the GL thread.
|
||||||
@ -290,7 +277,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
signalEndOfCurrentInputStream();
|
signalEndOfCurrentInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flush() {
|
@Override
|
||||||
|
protected void flush() {
|
||||||
// A frame that is registered before flush may arrive after flush.
|
// A frame that is registered before flush may arrive after flush.
|
||||||
numberOfFramesToDropOnBecomingAvailable = pendingFrames.size() - availableFrameCount;
|
numberOfFramesToDropOnBecomingAvailable = pendingFrames.size() - availableFrameCount;
|
||||||
removeAllSurfaceTextureFrames();
|
removeAllSurfaceTextureFrames();
|
||||||
|
@ -18,13 +18,11 @@ package androidx.media3.effect;
|
|||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
|
|
||||||
import android.opengl.GLES10;
|
import android.opengl.GLES10;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.FrameInfo;
|
import androidx.media3.common.FrameInfo;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
import androidx.media3.common.OnInputFrameProcessedListener;
|
import androidx.media3.common.OnInputFrameProcessedListener;
|
||||||
import androidx.media3.common.VideoFrameProcessingException;
|
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
@ -34,8 +32,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
*
|
*
|
||||||
* <p>Public methods in this class can be called from any thread.
|
* <p>Public methods in this class can be called from any thread.
|
||||||
*/
|
*/
|
||||||
/* package */ final class TexIdTextureManager implements TextureManager {
|
/* package */ final class TexIdTextureManager extends TextureManager {
|
||||||
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
|
|
||||||
private final FrameConsumptionManager frameConsumptionManager;
|
private final FrameConsumptionManager frameConsumptionManager;
|
||||||
|
|
||||||
private @MonotonicNonNull OnInputFrameProcessedListener frameProcessedListener;
|
private @MonotonicNonNull OnInputFrameProcessedListener frameProcessedListener;
|
||||||
@ -53,7 +50,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
GlObjectsProvider glObjectsProvider,
|
GlObjectsProvider glObjectsProvider,
|
||||||
GlShaderProgram shaderProgram,
|
GlShaderProgram shaderProgram,
|
||||||
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor) {
|
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor) {
|
||||||
this.videoFrameProcessingTaskExecutor = videoFrameProcessingTaskExecutor;
|
super(videoFrameProcessingTaskExecutor);
|
||||||
frameConsumptionManager =
|
frameConsumptionManager =
|
||||||
new FrameConsumptionManager(
|
new FrameConsumptionManager(
|
||||||
glObjectsProvider, shaderProgram, videoFrameProcessingTaskExecutor);
|
glObjectsProvider, shaderProgram, videoFrameProcessingTaskExecutor);
|
||||||
@ -72,11 +69,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
.onInputFrameProcessed(inputTexture.texId, GlUtil.createGlSyncFence()));
|
.onInputFrameProcessed(inputTexture.texId, GlUtil.createGlSyncFence()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFlush() {
|
|
||||||
videoFrameProcessingTaskExecutor.submit(frameConsumptionManager::onFlush);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void queueInputTexture(int inputTexId, long presentationTimeUs) {
|
public void queueInputTexture(int inputTexId, long presentationTimeUs) {
|
||||||
FrameInfo frameInfo = checkNotNull(this.inputFrameInfo);
|
FrameInfo frameInfo = checkNotNull(this.inputFrameInfo);
|
||||||
@ -124,12 +116,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task) {
|
public void release() {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Methods that must be called on the GL thread.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void release() throws VideoFrameProcessingException {
|
protected synchronized void flush() {
|
||||||
// Do nothing.
|
frameConsumptionManager.onFlush();
|
||||||
|
super.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package androidx.media3.effect;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
import androidx.annotation.GuardedBy;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.FrameInfo;
|
import androidx.media3.common.FrameInfo;
|
||||||
import androidx.media3.common.OnInputFrameProcessedListener;
|
import androidx.media3.common.OnInputFrameProcessedListener;
|
||||||
@ -27,15 +28,39 @@ import androidx.media3.common.VideoFrameProcessingException;
|
|||||||
import androidx.media3.common.VideoFrameProcessor;
|
import androidx.media3.common.VideoFrameProcessor;
|
||||||
import androidx.media3.common.util.TimestampIterator;
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
|
|
||||||
/** Handles {@code DefaultVideoFrameProcessor}'s input. */
|
/**
|
||||||
/* package */ interface TextureManager extends GlShaderProgram.InputListener {
|
* Handles {@code DefaultVideoFrameProcessor}'s input.
|
||||||
|
*
|
||||||
|
* <p>All instance methods must be called from either the thread that owns {@code this} instance, or
|
||||||
|
* an internal GL thread.
|
||||||
|
*/
|
||||||
|
/* package */ abstract class TextureManager implements GlShaderProgram.InputListener {
|
||||||
|
|
||||||
|
protected final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
|
||||||
|
|
||||||
|
private final Object lock;
|
||||||
|
|
||||||
|
// TODO(b/238302341) Remove the use of onFlushCompleteTask, block the calling thread instead.
|
||||||
|
@GuardedBy("lock")
|
||||||
|
@Nullable
|
||||||
|
private VideoFrameProcessingTaskExecutor.Task onFlushCompleteTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param videoFrameProcessingTaskExecutor The {@link VideoFrameProcessingTaskExecutor}.
|
||||||
|
*/
|
||||||
|
public TextureManager(VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor) {
|
||||||
|
this.videoFrameProcessingTaskExecutor = videoFrameProcessingTaskExecutor;
|
||||||
|
lock = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link DefaultVideoFrameProcessor#setInputDefaultBufferSize}.
|
* See {@link DefaultVideoFrameProcessor#setInputDefaultBufferSize}.
|
||||||
*
|
*
|
||||||
* <p>Only works when the input is received on a {@link SurfaceTexture}.
|
* <p>Only works when the input is received on a {@link SurfaceTexture}.
|
||||||
*/
|
*/
|
||||||
default void setDefaultBufferSize(int width, int height) {
|
public void setDefaultBufferSize(int width, int height) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +73,7 @@ import androidx.media3.common.util.TimestampIterator;
|
|||||||
* at. The timestamps should be monotonically increasing.
|
* at. The timestamps should be monotonically increasing.
|
||||||
* @param useHdr Whether input and/or output colors are HDR.
|
* @param useHdr Whether input and/or output colors are HDR.
|
||||||
*/
|
*/
|
||||||
default void queueInputBitmap(
|
public void queueInputBitmap(
|
||||||
Bitmap inputBitmap,
|
Bitmap inputBitmap,
|
||||||
FrameInfo frameInfo,
|
FrameInfo frameInfo,
|
||||||
TimestampIterator inStreamOffsetsUs,
|
TimestampIterator inStreamOffsetsUs,
|
||||||
@ -61,7 +86,7 @@ import androidx.media3.common.util.TimestampIterator;
|
|||||||
*
|
*
|
||||||
* @see VideoFrameProcessor#queueInputTexture
|
* @see VideoFrameProcessor#queueInputTexture
|
||||||
*/
|
*/
|
||||||
default void queueInputTexture(int inputTexId, long presentationTimeUs) {
|
public void queueInputTexture(int inputTexId, long presentationTimeUs) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +95,7 @@ import androidx.media3.common.util.TimestampIterator;
|
|||||||
*
|
*
|
||||||
* @see VideoFrameProcessor#setOnInputFrameProcessedListener
|
* @see VideoFrameProcessor#setOnInputFrameProcessedListener
|
||||||
*/
|
*/
|
||||||
default void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) {
|
public void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +108,7 @@ import androidx.media3.common.util.TimestampIterator;
|
|||||||
* <p>Pixels are expanded using the {@link FrameInfo#pixelWidthHeightRatio} so that the output
|
* <p>Pixels are expanded using the {@link FrameInfo#pixelWidthHeightRatio} so that the output
|
||||||
* frames' pixels have a ratio of 1.
|
* frames' pixels have a ratio of 1.
|
||||||
*/
|
*/
|
||||||
default void setInputFrameInfo(FrameInfo inputFrameInfo) {
|
public void setInputFrameInfo(FrameInfo inputFrameInfo) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,28 +117,48 @@ import androidx.media3.common.util.TimestampIterator;
|
|||||||
*
|
*
|
||||||
* <p>Only works when the input is received on a {@link SurfaceTexture}.
|
* <p>Only works when the input is received on a {@link SurfaceTexture}.
|
||||||
*/
|
*/
|
||||||
default Surface getInputSurface() {
|
public Surface getInputSurface() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Informs the {@code TextureManager} that a frame will be queued. */
|
/** Informs the {@code TextureManager} that a frame will be queued. */
|
||||||
default void registerInputFrame(FrameInfo frameInfo) {
|
public void registerInputFrame(FrameInfo frameInfo) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link VideoFrameProcessor#getPendingInputFrameCount}. */
|
/** See {@link VideoFrameProcessor#getPendingInputFrameCount}. */
|
||||||
int getPendingFrameCount();
|
public abstract int getPendingFrameCount();
|
||||||
|
|
||||||
/** Signals the end of the current input stream. */
|
/** Signals the end of the current input stream. */
|
||||||
void signalEndOfCurrentInputStream();
|
public abstract void signalEndOfCurrentInputStream();
|
||||||
|
|
||||||
/** Sets the task to run on completing flushing, or {@code null} to clear any task. */
|
/** Sets the task to run on completing flushing, or {@code null} to clear any task. */
|
||||||
void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task);
|
public final void setOnFlushCompleteListener(
|
||||||
|
@Nullable VideoFrameProcessingTaskExecutor.Task task) {
|
||||||
|
synchronized (lock) {
|
||||||
|
onFlushCompleteTask = task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onFlush() {
|
||||||
|
videoFrameProcessingTaskExecutor.submit(this::flush);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases all resources.
|
* Releases all resources.
|
||||||
*
|
*
|
||||||
* @see VideoFrameProcessor#release()
|
* @see VideoFrameProcessor#release()
|
||||||
*/
|
*/
|
||||||
void release() throws VideoFrameProcessingException;
|
public abstract void release() throws VideoFrameProcessingException;
|
||||||
|
|
||||||
|
// Methods that must be called on the GL thread.
|
||||||
|
|
||||||
|
protected void flush() {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (onFlushCompleteTask != null) {
|
||||||
|
videoFrameProcessingTaskExecutor.submitWithHighPriority(onFlushCompleteTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user