Render PQ to DebugSurface in transformer.

For HLG input in transformer, FinalWrapper is configured to only output HLG to
encoder. But since DebugPreview is configured to take PQ for HDR content, the
color will not look correct.

This CL allows overriding the MatrixTP output transfer function, so
that FinalWrapper can output

- HLG to encoder
- PQ to debug preview

PiperOrigin-RevId: 506022840
This commit is contained in:
claincly 2023-01-31 17:16:29 +00:00 committed by christosts
parent b57d5dd3fa
commit 6ce23f6eee
2 changed files with 34 additions and 7 deletions

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.effect;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
@ -422,7 +423,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
debugSurfaceViewWrapper.maybeRenderToSurfaceView(
() -> {
GlUtil.clearOutputFrame();
@C.ColorTransfer
int configuredColorTransfer = matrixTextureProcessor.getOutputColorTransfer();
matrixTextureProcessor.setOutputColorTransfer(
checkNotNull(debugSurfaceViewWrapper).outputColorTransfer);
matrixTextureProcessor.drawFrame(inputTexture.texId, presentationTimeUs);
matrixTextureProcessor.setOutputColorTransfer(configuredColorTransfer);
});
} catch (FrameProcessingException | GlUtil.GlException e) {
Log.d(TAG, "Error rendering to debug preview", e);
@ -434,9 +440,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* and makes rendering a no-op if not.
*/
private static final class SurfaceViewWrapper implements SurfaceHolder.Callback {
public final @C.ColorTransfer int outputColorTransfer;
private final EGLDisplay eglDisplay;
private final EGLContext eglContext;
private final boolean useHdr;
@GuardedBy("this")
@Nullable
@ -453,7 +459,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
EGLDisplay eglDisplay, EGLContext eglContext, boolean useHdr, SurfaceView surfaceView) {
this.eglDisplay = eglDisplay;
this.eglContext = eglContext;
this.useHdr = useHdr;
// Screen output supports only BT.2020 PQ (ST2084) for HDR.
this.outputColorTransfer = useHdr ? C.COLOR_TRANSFER_ST2084 : C.COLOR_TRANSFER_SDR;
surfaceView.getHolder().addCallback(this);
surface = surfaceView.getHolder().getSurface();
width = surfaceView.getWidth();
@ -473,13 +480,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
if (eglSurface == null) {
// Screen output supports only BT.2020 PQ (ST2084).
eglSurface =
GlUtil.createEglSurface(
eglDisplay,
surface,
useHdr ? C.COLOR_TRANSFER_ST2084 : C.COLOR_TRANSFER_SDR,
/* isEncoderInputSurface= */ false);
eglDisplay, surface, outputColorTransfer, /* isEncoderInputSurface= */ false);
}
EGLSurface eglSurface = this.eglSurface;
GlUtil.focusEglSurface(eglDisplay, eglContext, eglSurface, width, height);

View File

@ -125,6 +125,7 @@ import java.util.List;
private ImmutableList<float[]> visiblePolygon;
private final GlProgram glProgram;
private @C.ColorTransfer int outputColorTransfer;
/**
* Creates a new instance.
@ -156,6 +157,7 @@ import java.util.List;
glProgram,
ImmutableList.copyOf(matrixTransformations),
ImmutableList.copyOf(rgbMatrices),
/* outputColorTransfer= */ C.COLOR_TRANSFER_LINEAR,
useHdr);
}
@ -242,6 +244,7 @@ import java.util.List;
glProgram,
ImmutableList.copyOf(matrixTransformations),
ImmutableList.copyOf(rgbMatrices),
outputColorInfo.colorTransfer,
isInputTransferHdr);
}
@ -296,6 +299,7 @@ import java.util.List;
glProgram,
ImmutableList.copyOf(matrixTransformations),
ImmutableList.copyOf(rgbMatrices),
outputColorInfo.colorTransfer,
outputIsHdr);
}
@ -307,6 +311,7 @@ import java.util.List;
* apply to each frame in order. Can be empty to apply no vertex transformations.
* @param rgbMatrices The {@link RgbMatrix RgbMatrices} to apply to each frame in order. Can be
* empty to apply no color transformations.
* @param outputColorTransfer The output {@link C.ColorTransfer}.
* @param useHdr Whether to process the input as an HDR signal. Using HDR requires the {@code
* EXT_YUV_target} OpenGL extension.
*/
@ -314,9 +319,11 @@ import java.util.List;
GlProgram glProgram,
ImmutableList<GlMatrixTransformation> matrixTransformations,
ImmutableList<RgbMatrix> rgbMatrices,
int outputColorTransfer,
boolean useHdr) {
super(useHdr);
this.glProgram = glProgram;
this.outputColorTransfer = outputColorTransfer;
this.matrixTransformations = matrixTransformations;
this.rgbMatrices = rgbMatrices;
this.useHdr = useHdr;
@ -391,6 +398,23 @@ import java.util.List;
}
}
/**
* Sets the output {@link C.ColorTransfer}.
*
* <p>This method must not be called on {@code MatrixTextureProcessor} instances that output
* {@linkplain C#COLOR_TRANSFER_LINEAR linear colors}.
*/
public void setOutputColorTransfer(@C.ColorTransfer int colorTransfer) {
checkState(outputColorTransfer != C.COLOR_TRANSFER_LINEAR);
outputColorTransfer = colorTransfer;
glProgram.setIntUniform("uOutputColorTransfer", colorTransfer);
}
/** Returns the output {@link C.ColorTransfer}. */
public @C.ColorTransfer int getOutputColorTransfer() {
return outputColorTransfer;
}
/**
* Updates {@link #compositeTransformationMatrixArray} and {@link #visiblePolygon} based on the
* given frame timestamp.