diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java index ab6aefda35..8140f3a045 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java @@ -123,6 +123,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video private PreviewingVideoGraph.@MonotonicNonNull Factory previewingVideoGraphFactory; private List compositionEffects; private Clock clock; + private boolean requestOpenGlToneMapping; private boolean built; /** Creates a builder. */ @@ -192,6 +193,20 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video return this; } + /** + * Sets whether to tone map the input video with OpenGL. + * + *

By default, the input is not tone mapped. + * + * @param requestOpenGlToneMapping Whether tone mapping is requested. + * @return This builder, for convenience. + */ + @CanIgnoreReturnValue + public Builder setRequestOpenGlToneMapping(boolean requestOpenGlToneMapping) { + this.requestOpenGlToneMapping = requestOpenGlToneMapping; + return this; + } + /** * Builds the {@link PlaybackVideoGraphWrapper}. * @@ -241,6 +256,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video private final VideoSink.VideoFrameHandler videoFrameHandler; private final Clock clock; private final CopyOnWriteArraySet listeners; + private final boolean requestOpenGlToneMapping; private Format videoGraphOutputFormat; private @MonotonicNonNull HandlerWrapper handler; @@ -291,6 +307,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video }; listeners = new CopyOnWriteArraySet<>(); listeners.add(inputVideoSink); + requestOpenGlToneMapping = builder.requestOpenGlToneMapping; videoGraphOutputFormat = new Format.Builder().build(); state = STATE_CREATED; lastOutputBufferPresentationTimeUs = C.TIME_UNSET; @@ -425,13 +442,18 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video checkState(state == STATE_CREATED); ColorInfo inputColorInfo = getAdjustedInputColorInfo(sourceFormat.colorInfo); - ColorInfo outputColorInfo = inputColorInfo; - if (inputColorInfo.colorTransfer == C.COLOR_TRANSFER_HLG && Util.SDK_INT < 34) { - // PQ SurfaceView output is supported from API 33, but HLG output is supported from API 34. - // Therefore, convert HLG to PQ below API 34, so that HLG input can be displayed properly on - // API 33. - outputColorInfo = - inputColorInfo.buildUpon().setColorTransfer(C.COLOR_TRANSFER_ST2084).build(); + ColorInfo outputColorInfo; + if (requestOpenGlToneMapping) { + outputColorInfo = ColorInfo.SDR_BT709_LIMITED; + } else { + outputColorInfo = inputColorInfo; + if (outputColorInfo.colorTransfer == C.COLOR_TRANSFER_HLG && Util.SDK_INT < 34) { + // PQ SurfaceView output is supported from API 33, but HLG output is supported from API 34. + // Therefore, convert HLG to PQ below API 34, so that HLG input can be displayed properly on + // API 33. + outputColorInfo = + outputColorInfo.buildUpon().setColorTransfer(C.COLOR_TRANSFER_ST2084).build(); + } } handler = clock.createHandler(checkStateNotNull(Looper.myLooper()), /* callback= */ null); try { diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java index da9fa6fe0e..9ea37a89cd 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java @@ -674,6 +674,8 @@ public final class CompositionPlayer extends SimpleBasePlayer .setPreviewingVideoGraphFactory(checkNotNull(previewingVideoGraphFactory)) .setCompositionEffects(composition.effects.videoEffects) .setClock(clock) + .setRequestOpenGlToneMapping( + composition.hdrMode == Composition.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL) .build(); playbackVideoGraphWrapper.addListener(this);