Allow changing input pixelWidthHeightRatio for GlEffectsFrameProcessor.

pixelWidthHeightRatio is now passed to setInputFrameInfo instead of
the factory.

PiperOrigin-RevId: 457696703
This commit is contained in:
hschlueter 2022-06-28 11:22:45 +00:00 committed by Marc Baechinger
parent b7241d4eb3
commit b7b5f20e59
5 changed files with 35 additions and 41 deletions

View File

@ -366,7 +366,6 @@ public final class GlEffectsFrameProcessorPixelTest {
frameProcessingEnded = true;
}
},
pixelWidthHeightRatio,
/* streamOffsetUs= */ 0L,
effects,
/* outputSurfaceProvider= */ (requestedWidth, requestedHeight) -> {
@ -381,7 +380,8 @@ public final class GlEffectsFrameProcessorPixelTest {
},
Transformer.DebugViewProvider.NONE,
/* enableExperimentalHdrEditing= */ false));
glEffectsFrameProcessor.setInputFrameInfo(new FrameInfo(inputWidth, inputHeight));
glEffectsFrameProcessor.setInputFrameInfo(
new FrameInfo(inputWidth, inputHeight, pixelWidthHeightRatio));
glEffectsFrameProcessor.registerInputFrame();
// Queue the first video frame from the extractor.

View File

@ -23,15 +23,17 @@ import static androidx.media3.common.util.Assertions.checkArgument;
public final int width;
/** The height of the frame, in pixels. */
public final int height;
/** The ratio of width over height for each pixel. */
public final float pixelWidthHeightRatio;
// TODO(b/227625423): Add pixelWidthHeightRatio.
// TODO(b/227624622): Add color space information for HDR.
public FrameInfo(int width, int height) {
public FrameInfo(int width, int height, float pixelWidthHeightRatio) {
checkArgument(width > 0, "width must be positive, but is: " + width);
checkArgument(height > 0, "height must be positive, but is: " + height);
this.width = width;
this.height = height;
this.pixelWidthHeightRatio = pixelWidthHeightRatio;
}
}

View File

@ -46,6 +46,9 @@ import android.view.Surface;
*
* <p>The new input information is applied from the next frame {@linkplain #registerInputFrame()
* registered} onwards.
*
* <p>Pixels are expanded using the {@link FrameInfo#pixelWidthHeightRatio} so that the output
* frames' pixels have a ratio of 1.
*/
void setInputFrameInfo(FrameInfo inputFrameInfo);

View File

@ -50,8 +50,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
*
* @param context A {@link Context}.
* @param listener A {@link Listener}.
* @param pixelWidthHeightRatio The ratio of width over height for each pixel. Pixels are expanded
* by this ratio so that the output frame's pixels have a ratio of 1.
* @param effects The {@link GlEffect GlEffects} to apply to each frame.
* @param outputSurfaceProvider A {@link SurfaceInfo.Provider} managing the output {@link
* Surface}.
@ -64,7 +62,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public static GlEffectsFrameProcessor create(
Context context,
FrameProcessor.Listener listener,
float pixelWidthHeightRatio,
long streamOffsetUs,
List<GlEffect> effects,
SurfaceInfo.Provider outputSurfaceProvider,
@ -80,7 +77,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
createOpenGlObjectsAndFrameProcessor(
context,
listener,
pixelWidthHeightRatio,
streamOffsetUs,
effects,
outputSurfaceProvider,
@ -110,7 +106,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private static GlEffectsFrameProcessor createOpenGlObjectsAndFrameProcessor(
Context context,
FrameProcessor.Listener listener,
float pixelWidthHeightRatio,
long streamOffsetUs,
List<GlEffect> effects,
SurfaceInfo.Provider outputSurfaceProvider,
@ -136,20 +131,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
GlUtil.focusPlaceholderEglSurface(eglContext, eglDisplay);
}
ImmutableList.Builder<GlMatrixTransformation> matrixTransformationListBuilder =
new ImmutableList.Builder<>();
if (pixelWidthHeightRatio != 1f) {
matrixTransformationListBuilder.add(
createPixelWidthHeightRatioTransformation(pixelWidthHeightRatio));
}
ImmutableList<GlTextureProcessor> textureProcessors =
getGlTextureProcessorsForGlEffects(
context,
effects,
eglDisplay,
eglContext,
matrixTransformationListBuilder,
outputSurfaceProvider,
streamOffsetUs,
listener,
@ -173,26 +160,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
textureProcessors);
}
/**
* Returns a new {@link GlMatrixTransformation} to expand or shrink the frame based on the {@code
* pixelWidthHeightRatio}.
*
* <p>If {@code pixelWidthHeightRatio} is 1, this method returns an identity transformation that
* can be ignored.
*/
private static GlMatrixTransformation createPixelWidthHeightRatioTransformation(
float pixelWidthHeightRatio) {
if (pixelWidthHeightRatio > 1f) {
return new ScaleToFitTransformation.Builder()
.setScale(/* scaleX= */ pixelWidthHeightRatio, /* scaleY= */ 1f)
.build();
} else {
return new ScaleToFitTransformation.Builder()
.setScale(/* scaleX= */ 1f, /* scaleY= */ 1f / pixelWidthHeightRatio)
.build();
}
}
/**
* Combines consecutive {@link GlMatrixTransformation} instances into a single {@link
* MatrixTransformationProcessor} and converts all other {@link GlEffect} instances to separate
@ -207,7 +174,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
List<GlEffect> effects,
EGLDisplay eglDisplay,
EGLContext eglContext,
ImmutableList.Builder<GlMatrixTransformation> matrixTransformationListBuilder,
SurfaceInfo.Provider outputSurfaceProvider,
long streamOffsetUs,
FrameProcessor.Listener listener,
@ -216,6 +182,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
throws FrameProcessingException {
ImmutableList.Builder<GlTextureProcessor> textureProcessorListBuilder =
new ImmutableList.Builder<>();
ImmutableList.Builder<GlMatrixTransformation> matrixTransformationListBuilder =
new ImmutableList.Builder<>();
for (int i = 0; i < effects.size(); i++) {
GlEffect effect = effects.get(i);
if (effect instanceof GlMatrixTransformation) {
@ -396,7 +364,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
long presentationTimeUs = inputFrameTimeNs / 1000 - streamOffsetUs;
inputSurfaceTexture.getTransformMatrix(inputSurfaceTextureTransformMatrix);
inputExternalTextureProcessor.setTextureTransformMatrix(inputSurfaceTextureTransformMatrix);
FrameInfo inputFrameInfo = pendingInputFrames.remove();
FrameInfo inputFrameInfo = adjustForPixelWidthHeightRatio(pendingInputFrames.remove());
checkState(
inputExternalTextureProcessor.maybeQueueInputFrame(
new TextureInfo(
@ -409,6 +377,27 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// asynchronously by the texture processors chained after it.
}
/**
* Expands or shrinks the frame based on the {@link FrameInfo#pixelWidthHeightRatio} and returns a
* new {@link FrameInfo} instance with scaled dimensions and {@link
* FrameInfo#pixelWidthHeightRatio} 1.
*/
private FrameInfo adjustForPixelWidthHeightRatio(FrameInfo frameInfo) {
if (frameInfo.pixelWidthHeightRatio > 1f) {
return new FrameInfo(
(int) (frameInfo.width * frameInfo.pixelWidthHeightRatio),
frameInfo.height,
/* pixelWidthHeightRatio= */ 1);
} else if (frameInfo.pixelWidthHeightRatio < 1f) {
return new FrameInfo(
frameInfo.width,
(int) (frameInfo.height / frameInfo.pixelWidthHeightRatio),
/* pixelWidthHeightRatio= */ 1);
} else {
return frameInfo;
}
}
/**
* Propagates the end-of-stream signal through the texture processors once no more input frames
* are pending.

View File

@ -119,7 +119,6 @@ import org.checkerframework.dataflow.qual.Pure;
}
}
},
inputFormat.pixelWidthHeightRatio,
streamOffsetUs,
effectsListBuilder.build(),
/* outputSurfaceProvider= */ encoderWrapper,
@ -129,7 +128,8 @@ import org.checkerframework.dataflow.qual.Pure;
throw TransformationException.createForFrameProcessingException(
e, TransformationException.ERROR_CODE_GL_INIT_FAILED);
}
frameProcessor.setInputFrameInfo(new FrameInfo(decodedWidth, decodedHeight));
frameProcessor.setInputFrameInfo(
new FrameInfo(decodedWidth, decodedHeight, inputFormat.pixelWidthHeightRatio));
decoder =
decoderFactory.createForVideoDecoding(