mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add FrameProcessorChain factory method and make constructor private.
PiperOrigin-RevId: 438804850
This commit is contained in:
parent
63c42b79d4
commit
0370e05395
4 changed files with 63 additions and 58 deletions
|
|
@ -246,7 +246,7 @@ public final class FrameProcessorChainPixelTest {
|
||||||
int inputWidth = checkNotNull(mediaFormat).getInteger(MediaFormat.KEY_WIDTH);
|
int inputWidth = checkNotNull(mediaFormat).getInteger(MediaFormat.KEY_WIDTH);
|
||||||
int inputHeight = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
|
int inputHeight = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
|
||||||
frameProcessorChain =
|
frameProcessorChain =
|
||||||
new FrameProcessorChain(
|
FrameProcessorChain.create(
|
||||||
context,
|
context,
|
||||||
PIXEL_WIDTH_HEIGHT_RATIO,
|
PIXEL_WIDTH_HEIGHT_RATIO,
|
||||||
inputWidth,
|
inputWidth,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,49 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
GlUtil.glAssertionsEnabled = true;
|
GlUtil.glAssertionsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param context A {@link Context}.
|
||||||
|
* @param pixelWidthHeightRatio The ratio of width over height, for each pixel.
|
||||||
|
* @param inputWidth The input frame width, in pixels.
|
||||||
|
* @param inputHeight The input frame height, in pixels.
|
||||||
|
* @param frameProcessors The {@link GlFrameProcessor GlFrameProcessors} to apply to each frame.
|
||||||
|
* @param enableExperimentalHdrEditing Whether to attempt to process the input as an HDR signal.
|
||||||
|
* @return A new instance.
|
||||||
|
* @throws TransformationException If the {@code pixelWidthHeightRatio} isn't 1.
|
||||||
|
*/
|
||||||
|
public static FrameProcessorChain create(
|
||||||
|
Context context,
|
||||||
|
float pixelWidthHeightRatio,
|
||||||
|
int inputWidth,
|
||||||
|
int inputHeight,
|
||||||
|
List<GlFrameProcessor> frameProcessors,
|
||||||
|
boolean enableExperimentalHdrEditing)
|
||||||
|
throws TransformationException {
|
||||||
|
if (pixelWidthHeightRatio != 1.0f) {
|
||||||
|
// TODO(b/211782176): Consider implementing support for non-square pixels.
|
||||||
|
throw TransformationException.createForFrameProcessorChain(
|
||||||
|
new UnsupportedOperationException(
|
||||||
|
"Transformer's FrameProcessorChain currently does not support frame edits on"
|
||||||
|
+ " non-square pixels. The pixelWidthHeightRatio is: "
|
||||||
|
+ pixelWidthHeightRatio),
|
||||||
|
TransformationException.ERROR_CODE_GL_INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalCopyFrameProcessor externalCopyFrameProcessor =
|
||||||
|
new ExternalCopyFrameProcessor(context, enableExperimentalHdrEditing);
|
||||||
|
externalCopyFrameProcessor.setInputSize(inputWidth, inputHeight);
|
||||||
|
Size inputSize = externalCopyFrameProcessor.getOutputSize();
|
||||||
|
for (int i = 0; i < frameProcessors.size(); i++) {
|
||||||
|
frameProcessors.get(i).setInputSize(inputSize.getWidth(), inputSize.getHeight());
|
||||||
|
inputSize = frameProcessors.get(i).getOutputSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FrameProcessorChain(
|
||||||
|
externalCopyFrameProcessor, frameProcessors, enableExperimentalHdrEditing);
|
||||||
|
}
|
||||||
|
|
||||||
private static final String THREAD_NAME = "Transformer:FrameProcessorChain";
|
private static final String THREAD_NAME = "Transformer:FrameProcessorChain";
|
||||||
|
|
||||||
private final boolean enableExperimentalHdrEditing;
|
private final boolean enableExperimentalHdrEditing;
|
||||||
|
|
@ -78,7 +121,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
private volatile boolean releaseRequested;
|
private volatile boolean releaseRequested;
|
||||||
|
|
||||||
private boolean inputStreamEnded;
|
private boolean inputStreamEnded;
|
||||||
private final Size inputSize;
|
|
||||||
/** Wraps the {@link #inputSurfaceTexture}. */
|
/** Wraps the {@link #inputSurfaceTexture}. */
|
||||||
private @MonotonicNonNull Surface inputSurface;
|
private @MonotonicNonNull Surface inputSurface;
|
||||||
/** Associated with an OpenGL external texture. */
|
/** Associated with an OpenGL external texture. */
|
||||||
|
|
@ -116,48 +158,23 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
*/
|
*/
|
||||||
private @MonotonicNonNull EGLSurface debugPreviewEglSurface;
|
private @MonotonicNonNull EGLSurface debugPreviewEglSurface;
|
||||||
|
|
||||||
/**
|
private FrameProcessorChain(
|
||||||
* Creates a new instance.
|
ExternalCopyFrameProcessor externalCopyFrameProcessor,
|
||||||
*
|
|
||||||
* @param context A {@link Context}.
|
|
||||||
* @param pixelWidthHeightRatio The ratio of width over height, for each pixel.
|
|
||||||
* @param inputWidth The input frame width, in pixels.
|
|
||||||
* @param inputHeight The input frame height, in pixels.
|
|
||||||
* @param frameProcessors The {@link GlFrameProcessor GlFrameProcessors} to apply to each frame.
|
|
||||||
* @param enableExperimentalHdrEditing Whether to attempt to process the input as an HDR signal.
|
|
||||||
* @throws TransformationException If the {@code pixelWidthHeightRatio} isn't 1.
|
|
||||||
*/
|
|
||||||
public FrameProcessorChain(
|
|
||||||
Context context,
|
|
||||||
float pixelWidthHeightRatio,
|
|
||||||
int inputWidth,
|
|
||||||
int inputHeight,
|
|
||||||
List<GlFrameProcessor> frameProcessors,
|
List<GlFrameProcessor> frameProcessors,
|
||||||
boolean enableExperimentalHdrEditing)
|
boolean enableExperimentalHdrEditing) {
|
||||||
throws TransformationException {
|
this.externalCopyFrameProcessor = externalCopyFrameProcessor;
|
||||||
if (pixelWidthHeightRatio != 1.0f) {
|
|
||||||
// TODO(b/211782176): Consider implementing support for non-square pixels.
|
|
||||||
throw TransformationException.createForFrameProcessorChain(
|
|
||||||
new UnsupportedOperationException(
|
|
||||||
"Transformer's FrameProcessorChain currently does not support frame edits on"
|
|
||||||
+ " non-square pixels. The pixelWidthHeightRatio is: "
|
|
||||||
+ pixelWidthHeightRatio),
|
|
||||||
TransformationException.ERROR_CODE_GL_INIT_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.enableExperimentalHdrEditing = enableExperimentalHdrEditing;
|
|
||||||
this.frameProcessors = ImmutableList.copyOf(frameProcessors);
|
this.frameProcessors = ImmutableList.copyOf(frameProcessors);
|
||||||
|
this.enableExperimentalHdrEditing = enableExperimentalHdrEditing;
|
||||||
|
|
||||||
singleThreadExecutorService = Util.newSingleThreadExecutor(THREAD_NAME);
|
singleThreadExecutorService = Util.newSingleThreadExecutor(THREAD_NAME);
|
||||||
futures = new ConcurrentLinkedQueue<>();
|
futures = new ConcurrentLinkedQueue<>();
|
||||||
pendingFrameCount = new AtomicInteger();
|
pendingFrameCount = new AtomicInteger();
|
||||||
inputSize = new Size(inputWidth, inputHeight);
|
|
||||||
textureTransformMatrix = new float[16];
|
textureTransformMatrix = new float[16];
|
||||||
externalCopyFrameProcessor =
|
|
||||||
new ExternalCopyFrameProcessor(context, enableExperimentalHdrEditing);
|
|
||||||
framebuffers = new int[frameProcessors.size()];
|
framebuffers = new int[frameProcessors.size()];
|
||||||
configureFrameProcessorSizes(inputSize, frameProcessors);
|
outputSize =
|
||||||
outputSize = frameProcessors.isEmpty() ? inputSize : getLast(frameProcessors).getOutputSize();
|
frameProcessors.isEmpty()
|
||||||
|
? externalCopyFrameProcessor.getOutputSize()
|
||||||
|
: getLast(frameProcessors).getOutputSize();
|
||||||
debugPreviewWidth = C.LENGTH_UNSET;
|
debugPreviewWidth = C.LENGTH_UNSET;
|
||||||
debugPreviewHeight = C.LENGTH_UNSET;
|
debugPreviewHeight = C.LENGTH_UNSET;
|
||||||
}
|
}
|
||||||
|
|
@ -380,10 +397,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputExternalTexId = GlUtil.createExternalTexture();
|
inputExternalTexId = GlUtil.createExternalTexture();
|
||||||
externalCopyFrameProcessor.setInputSize(inputSize.getWidth(), inputSize.getHeight());
|
|
||||||
externalCopyFrameProcessor.initialize(inputExternalTexId);
|
externalCopyFrameProcessor.initialize(inputExternalTexId);
|
||||||
|
|
||||||
Size intermediateSize = inputSize;
|
Size intermediateSize = externalCopyFrameProcessor.getOutputSize();
|
||||||
for (int i = 0; i < frameProcessors.size(); i++) {
|
for (int i = 0; i < frameProcessors.size(); i++) {
|
||||||
int inputTexId =
|
int inputTexId =
|
||||||
GlUtil.createTexture(intermediateSize.getWidth(), intermediateSize.getHeight());
|
GlUtil.createTexture(intermediateSize.getWidth(), intermediateSize.getHeight());
|
||||||
|
|
@ -411,13 +427,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
GlUtil.focusEglSurface(
|
GlUtil.focusEglSurface(
|
||||||
eglDisplay, eglContext, eglSurface, outputSize.getWidth(), outputSize.getHeight());
|
eglDisplay, eglContext, eglSurface, outputSize.getWidth(), outputSize.getHeight());
|
||||||
} else {
|
} else {
|
||||||
|
Size intermediateSize = externalCopyFrameProcessor.getOutputSize();
|
||||||
GlUtil.focusFramebuffer(
|
GlUtil.focusFramebuffer(
|
||||||
eglDisplay,
|
eglDisplay,
|
||||||
eglContext,
|
eglContext,
|
||||||
eglSurface,
|
eglSurface,
|
||||||
framebuffers[0],
|
framebuffers[0],
|
||||||
inputSize.getWidth(),
|
intermediateSize.getWidth(),
|
||||||
inputSize.getHeight());
|
intermediateSize.getHeight());
|
||||||
}
|
}
|
||||||
inputSurfaceTexture.updateTexImage();
|
inputSurfaceTexture.updateTexImage();
|
||||||
inputSurfaceTexture.getTransformMatrix(textureTransformMatrix);
|
inputSurfaceTexture.getTransformMatrix(textureTransformMatrix);
|
||||||
|
|
@ -466,16 +483,4 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||||
GlUtil.checkGlError();
|
GlUtil.checkGlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the input and output {@linkplain Size sizes} of a list of {@link GlFrameProcessor
|
|
||||||
* GlFrameProcessors}.
|
|
||||||
*/
|
|
||||||
private static void configureFrameProcessorSizes(
|
|
||||||
Size inputSize, List<GlFrameProcessor> frameProcessors) {
|
|
||||||
for (int i = 0; i < frameProcessors.size(); i++) {
|
|
||||||
frameProcessors.get(i).setInputSize(inputSize.getWidth(), inputSize.getHeight());
|
|
||||||
inputSize = frameProcessors.get(i).getOutputSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||||
.setResolution(transformationRequest.outputHeight)
|
.setResolution(transformationRequest.outputHeight)
|
||||||
.build();
|
.build();
|
||||||
frameProcessorChain =
|
frameProcessorChain =
|
||||||
new FrameProcessorChain(
|
FrameProcessorChain.create(
|
||||||
context,
|
context,
|
||||||
inputFormat.pixelWidthHeightRatio,
|
inputFormat.pixelWidthHeightRatio,
|
||||||
/* inputWidth= */ decodedWidth,
|
/* inputWidth= */ decodedWidth,
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,11 @@ import org.junit.runner.RunWith;
|
||||||
public final class FrameProcessorChainTest {
|
public final class FrameProcessorChainTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void construct_withSupportedPixelWidthHeightRatio_completesSuccessfully()
|
public void create_withSupportedPixelWidthHeightRatio_completesSuccessfully()
|
||||||
throws TransformationException {
|
throws TransformationException {
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
|
|
||||||
new FrameProcessorChain(
|
FrameProcessorChain.create(
|
||||||
context,
|
context,
|
||||||
/* pixelWidthHeightRatio= */ 1,
|
/* pixelWidthHeightRatio= */ 1,
|
||||||
/* inputWidth= */ 200,
|
/* inputWidth= */ 200,
|
||||||
|
|
@ -51,14 +51,14 @@ public final class FrameProcessorChainTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void construct_withUnsupportedPixelWidthHeightRatio_throwsException() {
|
public void create_withUnsupportedPixelWidthHeightRatio_throwsException() {
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
|
|
||||||
TransformationException exception =
|
TransformationException exception =
|
||||||
assertThrows(
|
assertThrows(
|
||||||
TransformationException.class,
|
TransformationException.class,
|
||||||
() ->
|
() ->
|
||||||
new FrameProcessorChain(
|
FrameProcessorChain.create(
|
||||||
context,
|
context,
|
||||||
/* pixelWidthHeightRatio= */ 2,
|
/* pixelWidthHeightRatio= */ 2,
|
||||||
/* inputWidth= */ 200,
|
/* inputWidth= */ 200,
|
||||||
|
|
@ -121,7 +121,7 @@ public final class FrameProcessorChainTest {
|
||||||
for (Size element : frameProcessorOutputSizes) {
|
for (Size element : frameProcessorOutputSizes) {
|
||||||
frameProcessors.add(new FakeFrameProcessor(element));
|
frameProcessors.add(new FakeFrameProcessor(element));
|
||||||
}
|
}
|
||||||
return new FrameProcessorChain(
|
return FrameProcessorChain.create(
|
||||||
getApplicationContext(),
|
getApplicationContext(),
|
||||||
/* pixelWidthHeightRatio= */ 1,
|
/* pixelWidthHeightRatio= */ 1,
|
||||||
inputSize.getWidth(),
|
inputSize.getWidth(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue