Fix FrameEditor intermediate texture size.

ExternalCopyFrameProcessor's output dimensions match the input
size not the output size. So the intermediate texture size
should match the input size.

Also rename configureOutputDimensions to configureOutputSize.

PiperOrigin-RevId: 435058789
This commit is contained in:
hschlueter 2022-03-16 15:36:06 +00:00 committed by Ian Baker
parent 144a344b17
commit cd16995877
12 changed files with 56 additions and 55 deletions

View File

@ -222,17 +222,17 @@ public final class GlUtil {
}
/**
* Asserts that dimensions are valid for a texture.
* Asserts the texture size is valid.
*
* @param width The width for a texture.
* @param height The height for a texture.
* @throws GlException If the texture width or height is invalid.
*/
public static void assertValidTextureDimensions(int width, int height) {
// TODO(b/201293185): Consider handling adjustments for resolutions > GL_MAX_TEXTURE_SIZE
public static void assertValidTextureSize(int width, int height) {
// TODO(b/201293185): Consider handling adjustments for sizes > GL_MAX_TEXTURE_SIZE
// (ex. downscaling appropriately) in a FrameProcessor instead of asserting incorrect values.
// For valid GL resolutions, see:
// For valid GL sizes, see:
// https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glTexImage2D.xml
int[] maxTextureSizeBuffer = new int[1];
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeBuffer, 0);

View File

@ -244,9 +244,9 @@ public final class FrameEditorDataProcessingTest {
int inputWidth = checkNotNull(mediaFormat).getInteger(MediaFormat.KEY_WIDTH);
int inputHeight = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
Size outputDimensions = glFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
int outputWidth = outputDimensions.getWidth();
int outputHeight = outputDimensions.getHeight();
Size outputSize = glFrameProcessor.configureOutputSize(inputWidth, inputHeight);
int outputWidth = outputSize.getWidth();
int outputHeight = outputSize.getHeight();
frameEditorOutputImageReader =
ImageReader.newInstance(
outputWidth, outputHeight, PixelFormat.RGBA_8888, /* maxImages= */ 1);

View File

@ -101,7 +101,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
@Override
public Size configureOutputDimensions(int inputWidth, int inputHeight) {
public Size configureOutputSize(int inputWidth, int inputHeight) {
return new Size(inputWidth, inputHeight);
}

View File

@ -59,7 +59,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
@Override
public Size configureOutputDimensions(int inputWidth, int inputHeight) {
public Size configureOutputSize(int inputWidth, int inputHeight) {
return new Size(inputWidth, inputHeight);
}

View File

@ -193,13 +193,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
GlUtil.focusEglSurface(eglDisplay, eglContext, eglSurface, outputWidth, outputHeight);
GlUtil.assertValidTextureDimensions(outputWidth, outputHeight);
GlUtil.assertValidTextureSize(outputWidth, outputHeight);
int inputExternalTexId = GlUtil.createExternalTexture();
externalCopyFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
externalCopyFrameProcessor.initialize(inputExternalTexId);
int intermediateTexId = GlUtil.createTexture(outputWidth, outputHeight);
// TODO(b/214975934): Propagate output sizes through the chain of frame processors.
externalCopyFrameProcessor.configureOutputSize(inputWidth, inputHeight);
externalCopyFrameProcessor.initialize(/* inputTexId= */ inputExternalTexId);
int intermediateTexId = GlUtil.createTexture(inputWidth, inputHeight);
int frameBuffer = GlUtil.createFboForTexture(intermediateTexId);
transformationFrameProcessor.initialize(intermediateTexId);
transformationFrameProcessor.initialize(/* inputTexId= */ intermediateTexId);
return new FrameEditor(
singleThreadExecutorService,
@ -208,6 +209,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
eglSurface,
externalCopyFrameProcessor,
transformationFrameProcessor,
inputWidth,
inputHeight,
inputExternalTexId,
frameBuffer,
outputWidth,
@ -246,6 +249,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
*/
private final int frameBuffer;
private final int inputWidth;
private final int inputHeight;
private final int outputWidth;
private final int outputHeight;
@ -265,6 +270,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
EGLSurface eglSurface,
ExternalCopyFrameProcessor externalCopyFrameProcessor,
GlFrameProcessor transformationFrameProcessor,
int inputWidth,
int inputHeight,
int inputExternalTexId,
int frameBuffer,
int outputWidth,
@ -278,6 +285,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
this.eglSurface = eglSurface;
this.externalCopyFrameProcessor = externalCopyFrameProcessor;
this.transformationFrameProcessor = transformationFrameProcessor;
this.inputWidth = inputWidth;
this.inputHeight = inputHeight;
this.inputExternalTexId = inputExternalTexId;
this.frameBuffer = frameBuffer;
this.outputWidth = outputWidth;
@ -409,7 +418,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
long presentationTimeNs = inputSurfaceTexture.getTimestamp();
GlUtil.focusFramebuffer(
eglDisplay, eglContext, eglSurface, frameBuffer, outputWidth, outputHeight);
eglDisplay, eglContext, eglSurface, frameBuffer, inputWidth, inputHeight);
externalCopyFrameProcessor.setTextureTransformMatrix(textureTransformMatrix);
externalCopyFrameProcessor.updateProgramAndDraw(presentationTimeNs);

View File

@ -25,7 +25,7 @@ import java.io.IOException;
*
* <ol>
* <li>The constructor, for implementation-specific arguments.
* <li>{@link #configureOutputDimensions(int, int)}, to configure based on input dimensions.
* <li>{@link #configureOutputSize(int, int)}, to configure based on input dimensions.
* <li>{@link #initialize(int)}, to set up graphics initialization.
* <li>{@link #updateProgramAndDraw(long)}, to process one frame.
* <li>{@link #release()}, upon conclusion of processing.
@ -34,12 +34,12 @@ import java.io.IOException;
/* package */ interface GlFrameProcessor {
/**
* Returns the output {@link Size dimensions} of frames processed through {@link
* Returns the output {@link Size} of frames processed through {@link
* #updateProgramAndDraw(long)}.
*
* <p>This method must be called before {@link #initialize(int)} and does not use OpenGL.
*/
Size configureOutputDimensions(int inputWidth, int inputHeight);
Size configureOutputSize(int inputWidth, int inputHeight);
/**
* Does any initialization necessary such as loading and compiling a GLSL shader programs.

View File

@ -81,7 +81,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
*
* <p>Return values may be {@code 0} or {@code 90} degrees.
*
* <p>This method can only be called after {@link #configureOutputDimensions(int, int)}.
* <p>This method can only be called after {@link #configureOutputSize(int, int)}.
*/
public int getOutputRotationDegrees() {
checkState(outputRotationDegrees != C.LENGTH_UNSET);
@ -93,7 +93,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
*
* <p>The ScaleToFitFrameProcessor should only be used if this returns true.
*
* <p>This method can only be called after {@link #configureOutputDimensions(int, int)}.
* <p>This method can only be called after {@link #configureOutputSize(int, int)}.
*/
@RequiresNonNull("adjustedTransformationMatrix")
public boolean shouldProcess() {
@ -104,7 +104,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
@Override
@EnsuresNonNull("adjustedTransformationMatrix")
public Size configureOutputDimensions(int inputWidth, int inputHeight) {
public Size configureOutputSize(int inputWidth, int inputHeight) {
this.inputWidth = inputWidth;
this.inputHeight = inputHeight;
adjustedTransformationMatrix = new Matrix(transformationMatrix);
@ -179,7 +179,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public void initialize(int inputTexId) throws IOException {
checkStateNotNull(adjustedTransformationMatrix);
advancedFrameProcessor = new AdvancedFrameProcessor(context, adjustedTransformationMatrix);
advancedFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
advancedFrameProcessor.configureOutputSize(inputWidth, inputHeight);
advancedFrameProcessor.initialize(inputTexId);
}

View File

@ -74,7 +74,7 @@ import org.checkerframework.dataflow.qual.Pure;
transformationRequest.transformationMatrix,
transformationRequest.outputHeight);
Size requestedEncoderDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(decodedWidth, decodedHeight);
scaleToFitFrameProcessor.configureOutputSize(decodedWidth, decodedHeight);
outputRotationDegrees = scaleToFitFrameProcessor.getOutputRotationDegrees();
Format requestedEncoderFormat =

View File

@ -40,11 +40,10 @@ public final class AdvancedFrameProcessorTest {
AdvancedFrameProcessor advancedFrameProcessor =
new AdvancedFrameProcessor(getApplicationContext(), identityMatrix);
Size outputDimensions =
advancedFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = advancedFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(outputDimensions.getWidth()).isEqualTo(inputWidth);
assertThat(outputDimensions.getHeight()).isEqualTo(inputHeight);
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
assertThat(outputSize.getHeight()).isEqualTo(inputHeight);
}
@Test
@ -57,10 +56,9 @@ public final class AdvancedFrameProcessorTest {
AdvancedFrameProcessor advancedFrameProcessor =
new AdvancedFrameProcessor(getApplicationContext(), transformationMatrix);
Size outputDimensions =
advancedFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = advancedFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(outputDimensions.getWidth()).isEqualTo(inputWidth);
assertThat(outputDimensions.getHeight()).isEqualTo(inputHeight);
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
assertThat(outputSize.getHeight()).isEqualTo(inputHeight);
}
}

View File

@ -43,13 +43,12 @@ public final class ScaleToFitFrameProcessorTest {
ScaleToFitFrameProcessor scaleToFitFrameProcessor =
new ScaleToFitFrameProcessor(getApplicationContext(), identityMatrix, C.LENGTH_UNSET);
Size outputDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = scaleToFitFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(scaleToFitFrameProcessor.getOutputRotationDegrees()).isEqualTo(0);
assertThat(scaleToFitFrameProcessor.shouldProcess()).isFalse();
assertThat(outputDimensions.getWidth()).isEqualTo(inputWidth);
assertThat(outputDimensions.getHeight()).isEqualTo(inputHeight);
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
assertThat(outputSize.getHeight()).isEqualTo(inputHeight);
}
@Test
@ -83,13 +82,12 @@ public final class ScaleToFitFrameProcessorTest {
ScaleToFitFrameProcessor scaleToFitFrameProcessor =
new ScaleToFitFrameProcessor(getApplicationContext(), scaleNarrowMatrix, C.LENGTH_UNSET);
Size outputDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = scaleToFitFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(scaleToFitFrameProcessor.getOutputRotationDegrees()).isEqualTo(90);
assertThat(scaleToFitFrameProcessor.shouldProcess()).isTrue();
assertThat(outputDimensions.getWidth()).isEqualTo(inputHeight);
assertThat(outputDimensions.getHeight()).isEqualTo(Math.round(inputWidth * .5f));
assertThat(outputSize.getWidth()).isEqualTo(inputHeight);
assertThat(outputSize.getHeight()).isEqualTo(Math.round(inputWidth * .5f));
}
@Test
@ -101,13 +99,12 @@ public final class ScaleToFitFrameProcessorTest {
ScaleToFitFrameProcessor scaleToFitFrameProcessor =
new ScaleToFitFrameProcessor(getApplicationContext(), scaleNarrowMatrix, C.LENGTH_UNSET);
Size outputDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = scaleToFitFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(scaleToFitFrameProcessor.getOutputRotationDegrees()).isEqualTo(0);
assertThat(scaleToFitFrameProcessor.shouldProcess()).isTrue();
assertThat(outputDimensions.getWidth()).isEqualTo(inputWidth * 2);
assertThat(outputDimensions.getHeight()).isEqualTo(inputHeight);
assertThat(outputSize.getWidth()).isEqualTo(inputWidth * 2);
assertThat(outputSize.getHeight()).isEqualTo(inputHeight);
}
@Test
@ -119,13 +116,12 @@ public final class ScaleToFitFrameProcessorTest {
ScaleToFitFrameProcessor scaleToFitFrameProcessor =
new ScaleToFitFrameProcessor(getApplicationContext(), rotate90Matrix, C.LENGTH_UNSET);
Size outputDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = scaleToFitFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(scaleToFitFrameProcessor.getOutputRotationDegrees()).isEqualTo(90);
assertThat(scaleToFitFrameProcessor.shouldProcess()).isTrue();
assertThat(outputDimensions.getWidth()).isEqualTo(inputWidth);
assertThat(outputDimensions.getHeight()).isEqualTo(inputHeight);
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
assertThat(outputSize.getHeight()).isEqualTo(inputHeight);
}
@Test
@ -138,13 +134,12 @@ public final class ScaleToFitFrameProcessorTest {
new ScaleToFitFrameProcessor(getApplicationContext(), rotate45Matrix, C.LENGTH_UNSET);
long expectedOutputWidthHeight = 247;
Size outputDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = scaleToFitFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(scaleToFitFrameProcessor.getOutputRotationDegrees()).isEqualTo(0);
assertThat(scaleToFitFrameProcessor.shouldProcess()).isTrue();
assertThat(outputDimensions.getWidth()).isEqualTo(expectedOutputWidthHeight);
assertThat(outputDimensions.getHeight()).isEqualTo(expectedOutputWidthHeight);
assertThat(outputSize.getWidth()).isEqualTo(expectedOutputWidthHeight);
assertThat(outputSize.getHeight()).isEqualTo(expectedOutputWidthHeight);
}
@Test
@ -156,12 +151,11 @@ public final class ScaleToFitFrameProcessorTest {
ScaleToFitFrameProcessor scaleToFitFrameProcessor =
new ScaleToFitFrameProcessor(getApplicationContext(), identityMatrix, requestedHeight);
Size outputDimensions =
scaleToFitFrameProcessor.configureOutputDimensions(inputWidth, inputHeight);
Size outputSize = scaleToFitFrameProcessor.configureOutputSize(inputWidth, inputHeight);
assertThat(scaleToFitFrameProcessor.getOutputRotationDegrees()).isEqualTo(0);
assertThat(scaleToFitFrameProcessor.shouldProcess()).isTrue();
assertThat(outputDimensions.getWidth()).isEqualTo(requestedHeight * inputWidth / inputHeight);
assertThat(outputDimensions.getHeight()).isEqualTo(requestedHeight);
assertThat(outputSize.getWidth()).isEqualTo(requestedHeight * inputWidth / inputHeight);
assertThat(outputSize.getHeight()).isEqualTo(requestedHeight);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 KiB

After

Width:  |  Height:  |  Size: 734 KiB