The setting has no effect if the input is already in SDR, or if tone-mapping is not + * supported. Currently tone-mapping is only guaranteed to be supported from Android T onwards. + * + * @param enableRequestSdrToneMapping Whether to request tone-mapping down to SDR. + * @return This builder. + */ + public Builder setEnableRequestSdrToneMapping(boolean enableRequestSdrToneMapping) { + this.enableRequestSdrToneMapping = enableRequestSdrToneMapping; + return this; + } + /** * Sets whether to attempt to process any input video stream as a high dynamic range (HDR) * signal. * *
This method is experimental, and will be renamed or removed in a future release. The HDR * editing feature is under development and is intended for developing/testing HDR processing - * and encoding support. + * and encoding support. HDR editing can't be enabled at the same time as {@link + * #setEnableRequestSdrToneMapping(boolean) SDR tone-mapping}. * * @param enableHdrEditing Whether to attempt to process any input video stream as a high * dynamic range (HDR) signal. @@ -221,6 +240,7 @@ public final class TransformationRequest { outputHeight, audioMimeType, videoMimeType, + enableRequestSdrToneMapping, enableHdrEditing); } } @@ -271,6 +291,9 @@ public final class TransformationRequest { * @see Builder#setVideoMimeType(String) */ @Nullable public final String videoMimeType; + /** Whether to request tone-mapping to standard dynamic range (SDR). */ + public final boolean enableRequestSdrToneMapping; + /** * Whether to attempt to process any input video stream as a high dynamic range (HDR) signal. * @@ -286,7 +309,9 @@ public final class TransformationRequest { int outputHeight, @Nullable String audioMimeType, @Nullable String videoMimeType, + boolean enableRequestSdrToneMapping, boolean enableHdrEditing) { + checkArgument(!enableHdrEditing || !enableRequestSdrToneMapping); this.flattenForSlowMotion = flattenForSlowMotion; this.scaleX = scaleX; this.scaleY = scaleY; @@ -294,6 +319,7 @@ public final class TransformationRequest { this.outputHeight = outputHeight; this.audioMimeType = audioMimeType; this.videoMimeType = videoMimeType; + this.enableRequestSdrToneMapping = enableRequestSdrToneMapping; this.enableHdrEditing = enableHdrEditing; } @@ -313,6 +339,7 @@ public final class TransformationRequest { && outputHeight == that.outputHeight && Util.areEqual(audioMimeType, that.audioMimeType) && Util.areEqual(videoMimeType, that.videoMimeType) + && enableRequestSdrToneMapping == that.enableRequestSdrToneMapping && enableHdrEditing == that.enableHdrEditing; } @@ -325,6 +352,7 @@ public final class TransformationRequest { result = 31 * result + outputHeight; result = 31 * result + (audioMimeType != null ? audioMimeType.hashCode() : 0); result = 31 * result + (videoMimeType != null ? videoMimeType.hashCode() : 0); + result = 31 * result + (enableRequestSdrToneMapping ? 1 : 0); result = 31 * result + (enableHdrEditing ? 1 : 0); return result; } diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerVideoRenderer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerVideoRenderer.java index b3042a922b..d8789fc382 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerVideoRenderer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerVideoRenderer.java @@ -107,6 +107,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; if (encoderFactory.videoNeedsEncoding()) { return false; } + if (transformationRequest.enableRequestSdrToneMapping) { + return false; + } if (transformationRequest.enableHdrEditing) { return false; } diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/VideoTranscodingSamplePipeline.java b/libraries/transformer/src/main/java/androidx/media3/transformer/VideoTranscodingSamplePipeline.java index 5b4da873c7..068495d5e2 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/VideoTranscodingSamplePipeline.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/VideoTranscodingSamplePipeline.java @@ -124,7 +124,10 @@ import org.checkerframework.dataflow.qual.Pure; encoderSupportedFormat.width, encoderSupportedFormat.height)); decoder = - decoderFactory.createForVideoDecoding(inputFormat, frameProcessorChain.getInputSurface()); + decoderFactory.createForVideoDecoding( + inputFormat, + frameProcessorChain.getInputSurface(), + transformationRequest.enableRequestSdrToneMapping); maxPendingFrameCount = getMaxPendingFrameCount(); }