mirror of
https://github.com/androidx/media.git
synced 2025-05-09 08:30:43 +08:00
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:
parent
144a344b17
commit
cd16995877
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 |
Loading…
x
Reference in New Issue
Block a user