diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java index b7834b2f2c..01ebf7a03f 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java @@ -19,21 +19,25 @@ import static com.google.android.exoplayer2.transformer.AndroidTestUtil.MP4_ASSE import static com.google.android.exoplayer2.transformer.AndroidTestUtil.MP4_ASSET_1080P_4_SECOND_HDR10_FORMAT; import static com.google.android.exoplayer2.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECOND_HLG10; import static com.google.android.exoplayer2.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT; +import static com.google.android.exoplayer2.transformer.AndroidTestUtil.recordTestSkipped; +import static com.google.android.exoplayer2.transformer.AndroidTestUtil.skipAndLogIfFormatsUnsupported; import static com.google.android.exoplayer2.transformer.mh.FileUtil.maybeAssertFileHasColorTransfer; +import static com.google.android.exoplayer2.util.Util.SDK_INT; import android.content.Context; import android.net.Uri; +import android.util.Log; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.MediaItem; -import com.google.android.exoplayer2.transformer.AndroidTestUtil; import com.google.android.exoplayer2.transformer.ExportException; import com.google.android.exoplayer2.transformer.ExportTestResult; import com.google.android.exoplayer2.transformer.TransformationRequest; import com.google.android.exoplayer2.transformer.Transformer; import com.google.android.exoplayer2.transformer.TransformerAndroidTestRunner; -import com.google.android.exoplayer2.util.Log; +import com.google.android.exoplayer2.video.ColorInfo; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,11 +55,21 @@ public class ForceInterpretHdrVideoAsSdrTest { String testId = "forceInterpretHdrVideoAsSdrTest_hdr10File_transformsOrThrows"; Context context = ApplicationProvider.getApplicationContext(); - if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( - context, - testId, - /* inputFormat= */ MP4_ASSET_1080P_4_SECOND_HDR10_FORMAT, - /* outputFormat= */ null)) { + if (SDK_INT < 29) { + // TODO(b/269759013): Fix failures under API 29 to expand confidence on all API versions. + recordTestSkipped( + context, testId, /* reason= */ "Under API 29, this API is considered best-effort."); + return; + } + + // Force interpret HDR as SDR signals SDR input to the decoder, even if the actual input is HDR. + Format decoderInputFormat = + MP4_ASSET_1080P_4_SECOND_HDR10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build(); + if (skipAndLogIfFormatsUnsupported( + context, testId, decoderInputFormat, /* outputFormat= */ null)) { return; } @@ -76,7 +90,9 @@ public class ForceInterpretHdrVideoAsSdrTest { maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); Log.i(TAG, "Transformed."); } catch (ExportException exception) { - if (exception.errorCode != ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED) { + String message = getMessageOrEmptyString(exception); + Log.i(TAG, "Exception: " + message); + if (!message.equals("The requested video decoding format is not supported.")) { throw exception; } } @@ -87,11 +103,21 @@ public class ForceInterpretHdrVideoAsSdrTest { String testId = "forceInterpretHdrVideoAsSdrTest_hlg10File_transformsOrThrows"; Context context = ApplicationProvider.getApplicationContext(); - if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( - context, - testId, - /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT, - /* outputFormat= */ null)) { + if (SDK_INT < 29) { + // TODO(b/269759013): Fix failures under API 29 to expand confidence on all API versions. + recordTestSkipped( + context, testId, /* reason= */ "Under API 29, this API is considered best-effort."); + return; + } + + // Force interpret HDR as SDR signals SDR input to the decoder, even if the actual input is HDR. + Format decoderInputFormat = + MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build(); + if (skipAndLogIfFormatsUnsupported( + context, testId, decoderInputFormat, /* outputFormat= */ null)) { return; } @@ -112,9 +138,22 @@ public class ForceInterpretHdrVideoAsSdrTest { maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); Log.i(TAG, "Transformed."); } catch (ExportException exception) { - if (exception.errorCode != ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED) { + String message = getMessageOrEmptyString(exception); + Log.i(TAG, "Exception: " + message); + if (!message.equals("The requested video decoding format is not supported.")) { throw exception; } } } + + private String getMessageOrEmptyString(Exception exception) { + if (exception.getCause() == null) { + return ""; + } + String message = exception.getCause().getMessage(); + if (message == null) { + return ""; + } + return message; + } } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderBaseRenderer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderBaseRenderer.java index c6d0c5e48c..01c1f646bb 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderBaseRenderer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderBaseRenderer.java @@ -136,7 +136,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } /** Overrides the {@code inputFormat}. */ - protected Format overrideFormat(Format inputFormat) throws ExportException { + protected Format overrideFormat(Format inputFormat) { return inputFormat; } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderVideoRenderer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderVideoRenderer.java index e212bdd855..baa57ccf6c 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderVideoRenderer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoAssetLoaderVideoRenderer.java @@ -16,7 +16,6 @@ package com.google.android.exoplayer2.transformer; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; -import static com.google.android.exoplayer2.util.Util.SDK_INT; import android.media.MediaCodec; import androidx.annotation.Nullable; @@ -61,17 +60,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } @Override - protected Format overrideFormat(Format inputFormat) throws ExportException { + protected Format overrideFormat(Format inputFormat) { if (forceInterpretHdrAsSdr && ColorInfo.isTransferHdr(inputFormat.colorInfo)) { - if (SDK_INT < 29) { - throw ExportException.createForCodec( - new IllegalArgumentException( - "Interpreting HDR video as SDR is not supported on this device."), - ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED, - /* isVideo= */ true, - /* isDecoder= */ true, - inputFormat); - } return inputFormat.buildUpon().setColorInfo(ColorInfo.SDR_BT709_LIMITED).build(); } return inputFormat; diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java index 9d0cd7db2f..516f4b7f51 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java @@ -88,13 +88,13 @@ public final class TransformationRequest { /** * Interpret HDR input as SDR, likely with a washed out look. * - *

Supported on API 29+. - * *

This is much more widely supported than {@link #HDR_MODE_KEEP_HDR} and {@link * #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}. However, as HDR transfer functions and * metadata will be ignored, contents will be displayed incorrectly, likely with a washed out * look. * + *

Using this API may lead to codec errors before API 29, per b/269759013. + * *

Use of this flag may result in {@code ERROR_CODE_DECODING_FORMAT_UNSUPPORTED}. * *

This field is experimental, and will be renamed or removed in a future release.