diff --git a/library/effect/src/main/java/com/google/android/exoplayer2/effect/FinalMatrixTextureProcessorWrapper.java b/library/effect/src/main/java/com/google/android/exoplayer2/effect/FinalMatrixTextureProcessorWrapper.java index 6b6fc50d41..bd2467d824 100644 --- a/library/effect/src/main/java/com/google/android/exoplayer2/effect/FinalMatrixTextureProcessorWrapper.java +++ b/library/effect/src/main/java/com/google/android/exoplayer2/effect/FinalMatrixTextureProcessorWrapper.java @@ -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); diff --git a/library/effect/src/main/java/com/google/android/exoplayer2/effect/MatrixTextureProcessor.java b/library/effect/src/main/java/com/google/android/exoplayer2/effect/MatrixTextureProcessor.java index c284bd3b4e..aa948a683f 100644 --- a/library/effect/src/main/java/com/google/android/exoplayer2/effect/MatrixTextureProcessor.java +++ b/library/effect/src/main/java/com/google/android/exoplayer2/effect/MatrixTextureProcessor.java @@ -125,6 +125,7 @@ import java.util.List; private ImmutableList 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 matrixTransformations, ImmutableList 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}. + * + *

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.