diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/FileUtil.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/FileUtil.java index 8c7eeb781a..af8dbe07f9 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/FileUtil.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/FileUtil.java @@ -16,70 +16,57 @@ package androidx.media3.transformer.mh; -import static androidx.media3.common.util.Assertions.checkNotNull; import static com.google.common.truth.Truth.assertThat; -import android.media.MediaFormat; +import android.content.Context; import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.ColorInfo; -import androidx.media3.common.util.MediaFormatUtil; -import androidx.media3.common.util.Util; -import androidx.media3.test.utils.DecodeOneFrameUtil; -import java.io.IOException; +import androidx.media3.common.Format; +import androidx.media3.common.MediaItem; +import androidx.media3.common.TrackGroup; +import androidx.media3.exoplayer.MetadataRetriever; +import androidx.media3.exoplayer.source.TrackGroupArray; +import java.util.concurrent.ExecutionException; /** Utilities for accessing details of media files. */ /* package */ class FileUtil { /** - * Assert that the file has a certain color transfer, if supported on this device. - * - *

This will silently pass if under API 24, or if decoding this file is not supported on this - * device. + * Asserts that the file has a certain color transfer. * + * @param context The current context. * @param filePath The path of the input file. * @param expectedColorTransfer The expected {@link C.ColorTransfer} for the input file. - * @throws IOException If extractor or codec creation fails. */ - public static void maybeAssertFileHasColorTransfer( - @Nullable String filePath, @C.ColorTransfer int expectedColorTransfer) throws IOException { - if (Util.SDK_INT < 24) { - // MediaFormat#KEY_COLOR_TRANSFER unsupported before API 24. - return; - } - DecodeOneFrameUtil.Listener listener = - new DecodeOneFrameUtil.Listener() { - @Override - public void onContainerExtracted(MediaFormat mediaFormat) { - @Nullable ColorInfo extractedColorInfo = MediaFormatUtil.getColorInfo(mediaFormat); - assertColorInfoHasTransfer(extractedColorInfo, expectedColorTransfer); - } - - @Override - public void onFrameDecoded(MediaFormat mediaFormat) { - @Nullable ColorInfo decodedColorInfo = MediaFormatUtil.getColorInfo(mediaFormat); - assertColorInfoHasTransfer(decodedColorInfo, expectedColorTransfer); - } - }; - + public static void assertFileHasColorTransfer( + Context context, @Nullable String filePath, @C.ColorTransfer int expectedColorTransfer) { + TrackGroupArray trackGroupArray; try { - DecodeOneFrameUtil.decodeOneCacheFileFrame( - checkNotNull(filePath), listener, /* surface= */ null); - } catch (UnsupportedOperationException e) { - if (e.getMessage() != null - && e.getMessage().equals(DecodeOneFrameUtil.NO_DECODER_SUPPORT_ERROR_STRING)) { + trackGroupArray = + MetadataRetriever.retrieveMetadata(context, MediaItem.fromUri("file://" + filePath)) + .get(); + } catch (ExecutionException | InterruptedException e) { + throw new IllegalStateException(e); + } + + int trackGroupCount = trackGroupArray.length; + assertThat(trackGroupCount).isEqualTo(2); + for (int i = 0; i < trackGroupCount; i++) { + TrackGroup trackGroup = trackGroupArray.get(i); + if (trackGroup.type == C.TRACK_TYPE_VIDEO) { + assertThat(trackGroup.length).isEqualTo(1); + @Nullable ColorInfo colorInfo = trackGroup.getFormat(0).colorInfo; + @C.ColorTransfer + int actualColorTransfer = + colorInfo == null || colorInfo.colorTransfer == Format.NO_VALUE + ? C.COLOR_TRANSFER_SDR + : colorInfo.colorTransfer; + assertThat(actualColorTransfer).isEqualTo(expectedColorTransfer); return; - } else { - throw e; } } - } - - private static void assertColorInfoHasTransfer( - @Nullable ColorInfo colorInfo, @C.ColorTransfer int expectedColorTransfer) { - @C.ColorTransfer - int actualColorTransfer = colorInfo == null ? C.COLOR_TRANSFER_SDR : colorInfo.colorTransfer; - assertThat(actualColorTransfer).isEqualTo(expectedColorTransfer); + throw new IllegalStateException("Couldn't find video track"); } private FileUtil() {} diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java index 02b28ba133..49c41b9a64 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ForceInterpretHdrVideoAsSdrTest.java @@ -22,7 +22,7 @@ import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECON import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECOND_HDR10_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.recordTestSkipped; import static androidx.media3.transformer.AndroidTestUtil.skipAndLogIfFormatsUnsupported; -import static androidx.media3.transformer.mh.FileUtil.maybeAssertFileHasColorTransfer; +import static androidx.media3.transformer.mh.FileUtil.assertFileHasColorTransfer; import android.content.Context; import android.net.Uri; @@ -46,7 +46,6 @@ import org.junit.runner.RunWith; */ @RunWith(AndroidJUnit4.class) public class ForceInterpretHdrVideoAsSdrTest { - public static final String TAG = "ForceInterpretHdrVideoAsSdrTest"; @Test public void forceInterpretHdrVideoAsSdrTest_hdr10File_transformsOrThrows() throws Exception { @@ -85,7 +84,7 @@ public class ForceInterpretHdrVideoAsSdrTest { .build() .run(testId, mediaItem); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } @Test @@ -125,6 +124,6 @@ public class ForceInterpretHdrVideoAsSdrTest { .build() .run(testId, mediaItem); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java index ff0c9270eb..8df7721c9a 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java @@ -16,13 +16,15 @@ package androidx.media3.transformer.mh; import static androidx.media3.common.MimeTypes.VIDEO_H265; -import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.transformer.AndroidTestUtil.FORCE_TRANSCODE_VIDEO_EFFECTS; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECOND_HLG10; +import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECOND_HDR10; +import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECOND_HDR10_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_DOLBY_VISION_HDR; +import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_DOLBY_VISION_HDR_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.recordTestSkipped; -import static androidx.media3.transformer.mh.FileUtil.maybeAssertFileHasColorTransfer; +import static androidx.media3.transformer.mh.FileUtil.assertFileHasColorTransfer; import static com.google.common.truth.Truth.assertThat; import android.content.Context; @@ -30,7 +32,8 @@ import android.net.Uri; import androidx.media3.common.C; import androidx.media3.common.ColorInfo; import androidx.media3.common.MediaItem; -import androidx.media3.common.util.Log; +import androidx.media3.common.util.Util; +import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.EditedMediaItem; import androidx.media3.transformer.EncoderUtil; import androidx.media3.transformer.ExportException; @@ -40,6 +43,7 @@ import androidx.media3.transformer.Transformer; import androidx.media3.transformer.TransformerAndroidTestRunner; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Test; import org.junit.runner.RunWith; @@ -49,8 +53,7 @@ import org.junit.runner.RunWith; * TransformationRequest#HDR_MODE_KEEP_HDR HDR frame edit}. */ @RunWith(AndroidJUnit4.class) -public class HdrEditingTest { - public static final String TAG = "HdrEditingTest"; +public final class HdrEditingTest { private static final ColorInfo HDR10_DEFAULT_COLOR_INFO = new ColorInfo.Builder() .setColorSpace(C.COLOR_SPACE_BT2020) @@ -65,64 +68,80 @@ public class HdrEditingTest { .build(); @Test - public void export_noRequestedTranscode_hdr10File_exportsOrThrows() throws Exception { - String testId = "export_noRequestedTranscode_hdr10File_exportsOrThrows"; + public void export_transmuxHdr10File() throws Exception { + String testId = "export_transmuxHdr10File"; Context context = ApplicationProvider.getApplicationContext(); + if (Util.SDK_INT < 24) { + // TODO: b/285543404 - Remove suppression once we can transmux H.265/HEVC before API 24. + recordTestSkipped(context, testId, /* reason= */ "Can't transmux H.265/HEVC before API 24"); + return; + } + + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT, + /* outputFormat= */ null)) { + return; + } + Transformer transformer = new Transformer.Builder(context).build(); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_720P_4_SECOND_HDR10)); - try { - ExportTestResult exportTestResult = - new TransformerAndroidTestRunner.Builder(context, transformer) - .build() - .run(testId, mediaItem); - Log.i(TAG, "Exported."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_ST2084); - } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isAnyOf( - ExportException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED, - ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - } + ExportTestResult exportTestResult = + new TransformerAndroidTestRunner.Builder(context, transformer) + .build() + .run(testId, mediaItem); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_ST2084); } @Test - public void export_noRequestedTranscode_hlg10File_exportsOrThrows() throws Exception { - String testId = "export_noRequestedTranscode_hlg10File_exportsOrThrows"; + public void export_transmuxHlg10File() throws Exception { + String testId = "export_transmuxHlg10File"; Context context = ApplicationProvider.getApplicationContext(); + if (Util.SDK_INT < 24) { + // TODO: b/285543404 - Remove suppression once we can transmux H.265/HEVC before API 24. + recordTestSkipped(context, testId, /* reason= */ "Can't transmux H.265/HEVC before API 24"); + return; + } + + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT, + /* outputFormat= */ null)) { + return; + } + Transformer transformer = new Transformer.Builder(context).build(); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)); - try { - ExportTestResult exportTestResult = - new TransformerAndroidTestRunner.Builder(context, transformer) - .build() - .run(testId, mediaItem); - Log.i(TAG, "Exported."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_HLG); - } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isAnyOf( - ExportException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED, - ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - } + ExportTestResult exportTestResult = + new TransformerAndroidTestRunner.Builder(context, transformer) + .build() + .run(testId, mediaItem); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_HLG); } @Test - public void exportAndTranscode_hdr10File_whenHdrEditingIsSupported_exports() throws Exception { - String testId = "exportAndTranscode_hdr10File_whenHdrEditingIsSupported_exports"; + public void exportAndTranscode_hdr10File_whenHdrEditingIsSupported() throws Exception { + String testId = "exportAndTranscode_hdr10File_whenHdrEditingIsSupported"; Context context = ApplicationProvider.getApplicationContext(); if (!deviceSupportsHdrEditing(VIDEO_H265, HDR10_DEFAULT_COLOR_INFO)) { recordTestSkipped(context, testId, /* reason= */ "Device lacks HDR10 editing support."); return; } + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT, + /* outputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT)) { + return; + } + Transformer transformer = new Transformer.Builder(context).build(); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_720P_4_SECOND_HDR10)); EditedMediaItem editedMediaItem = @@ -132,18 +151,26 @@ public class HdrEditingTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_ST2084); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_ST2084); } @Test - public void exportAndTranscode_hlg10File_whenHdrEditingIsSupported_exports() throws Exception { - String testId = "exportAndTranscode_hlg10File_whenHdrEditingIsSupported_exports"; + public void exportAndTranscode_hlg10File_whenHdrEditingIsSupported() throws Exception { + String testId = "exportAndTranscode_hlg10File_whenHdrEditingIsSupported"; Context context = ApplicationProvider.getApplicationContext(); if (!deviceSupportsHdrEditing(VIDEO_H265, HLG10_DEFAULT_COLOR_INFO)) { recordTestSkipped(context, testId, /* reason= */ "Device lacks HLG10 editing support."); return; } + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT, + /* outputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT)) { + return; + } + Transformer transformer = new Transformer.Builder(context).build(); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)); EditedMediaItem editedMediaItem = @@ -153,13 +180,12 @@ public class HdrEditingTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_HLG); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_HLG); } @Test - public void exportAndTranscode_dolbyVisionFile_whenHdrEditingIsSupported_exports() - throws Exception { - String testId = "exportAndTranscode_dolbyVisionFile_whenHdrEditingIsSupported_exports"; + public void exportAndTranscode_dolbyVisionFile_whenHdrEditingIsSupported() throws Exception { + String testId = "exportAndTranscode_dolbyVisionFile_whenHdrEditingIsSupported"; Context context = ApplicationProvider.getApplicationContext(); // This dolby vision file has a ColorInfo identical to HLG10. if (!deviceSupportsHdrEditing(VIDEO_H265, HLG10_DEFAULT_COLOR_INFO)) { @@ -167,6 +193,14 @@ public class HdrEditingTest { return; } + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_DOLBY_VISION_HDR_FORMAT, + /* outputFormat= */ MP4_ASSET_DOLBY_VISION_HDR_FORMAT)) { + return; + } + Transformer transformer = new Transformer.Builder(context).build(); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_DOLBY_VISION_HDR)); EditedMediaItem editedMediaItem = @@ -176,7 +210,7 @@ public class HdrEditingTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_HLG); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_HLG); } @Test @@ -189,6 +223,17 @@ public class HdrEditingTest { return; } + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT, + /* outputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build())) { + return; + } + AtomicBoolean isFallbackListenerInvoked = new AtomicBoolean(); AtomicBoolean isToneMappingFallbackApplied = new AtomicBoolean(); Transformer transformer = @@ -218,15 +263,20 @@ public class HdrEditingTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - Log.i(TAG, "Tone mapped."); assertThat(isToneMappingFallbackApplied.get()).isTrue(); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isEqualTo(ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - assertThat(isFallbackListenerInvoked.get()).isFalse(); + if (exception.getCause() != null + && (Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping HDR is not supported on this device.") + || Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping requested but not supported by the decoder."))) { + // Expected on devices without a tone-mapping plugin for the this codec. + return; + } + throw exception; } } @@ -240,6 +290,17 @@ public class HdrEditingTest { return; } + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT, + /* outputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build())) { + return; + } + AtomicBoolean isFallbackListenerInvoked = new AtomicBoolean(); AtomicBoolean isToneMappingFallbackApplied = new AtomicBoolean(); Transformer transformer = @@ -269,15 +330,20 @@ public class HdrEditingTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - Log.i(TAG, "Tone mapped."); assertThat(isToneMappingFallbackApplied.get()).isTrue(); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isEqualTo(ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - assertThat(isFallbackListenerInvoked.get()).isFalse(); + if (exception.getCause() != null + && (Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping HDR is not supported on this device.") + || Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping requested but not supported by the decoder."))) { + // Expected on devices without a tone-mapping plugin for this codec. + return; + } + throw exception; } } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java index 5f4b4619e2..a07d08d514 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java @@ -15,18 +15,20 @@ */ package androidx.media3.transformer.mh; -import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.transformer.AndroidTestUtil.FORCE_TRANSCODE_VIDEO_EFFECTS; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECOND_HLG10; +import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECOND_HDR10; -import static androidx.media3.transformer.mh.FileUtil.maybeAssertFileHasColorTransfer; +import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECOND_HDR10_FORMAT; +import static androidx.media3.transformer.mh.FileUtil.assertFileHasColorTransfer; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.net.Uri; import androidx.media3.common.C; +import androidx.media3.common.ColorInfo; import androidx.media3.common.MediaItem; -import androidx.media3.common.util.Log; +import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.EditedMediaItem; import androidx.media3.transformer.ExportException; import androidx.media3.transformer.ExportTestResult; @@ -35,6 +37,7 @@ import androidx.media3.transformer.Transformer; import androidx.media3.transformer.TransformerAndroidTestRunner; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import java.util.Objects; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,13 +48,23 @@ import org.junit.runner.RunWith; */ @RunWith(AndroidJUnit4.class) public class ToneMapHdrToSdrUsingMediaCodecTest { - public static final String TAG = "ToneMapHdrToSdrUsingMediaCodecTest"; @Test public void export_toneMapNoRequestedTranscode_hdr10File_toneMapsOrThrows() throws Exception { String testId = "export_toneMapNoRequestedTranscode_hdr10File_toneMapsOrThrows"; Context context = ApplicationProvider.getApplicationContext(); + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT, + /* outputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build())) { + return; + } + Transformer transformer = new Transformer.Builder(context) .setTransformationRequest( @@ -79,13 +92,19 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, mediaItem); - Log.i(TAG, "Tone mapped."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isEqualTo(ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); + if (exception.getCause() != null + && (Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping HDR is not supported on this device.") + || Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping requested but not supported by the decoder."))) { + // Expected on devices without a tone-mapping plugin for this codec. + return; + } + throw exception; } } @@ -94,6 +113,17 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { String testId = "export_toneMapNoRequestedTranscode_hlg10File_toneMapsOrThrows"; Context context = ApplicationProvider.getApplicationContext(); + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT, + /* outputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build())) { + return; + } + Transformer transformer = new Transformer.Builder(context) .setTransformationRequest( @@ -121,13 +151,19 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, mediaItem); - Log.i(TAG, "Tone mapped."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isEqualTo(ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); + if (exception.getCause() != null + && (Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping HDR is not supported on this device.") + || Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping requested but not supported by the decoder."))) { + // Expected on devices without a tone-mapping plugin for this codec. + return; + } + throw exception; } } @@ -136,6 +172,17 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { String testId = "export_toneMapAndTranscode_hdr10File_toneMapsOrThrows"; Context context = ApplicationProvider.getApplicationContext(); + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT, + /* outputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build())) { + return; + } + Transformer transformer = new Transformer.Builder(context) .setTransformationRequest( @@ -165,13 +212,19 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - Log.i(TAG, "Tone mapped."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isEqualTo(ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); + if (exception.getCause() != null + && (Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping HDR is not supported on this device.") + || Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping requested but not supported by the decoder."))) { + // Expected on devices without a tone-mapping plugin for this codec. + return; + } + throw exception; } } @@ -180,6 +233,17 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { String testId = "export_toneMapAndTranscode_hlg10File_toneMapsOrThrows"; Context context = ApplicationProvider.getApplicationContext(); + if (AndroidTestUtil.skipAndLogIfFormatsUnsupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT, + /* outputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build())) { + return; + } + Transformer transformer = new Transformer.Builder(context) .setTransformationRequest( @@ -209,13 +273,19 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { new TransformerAndroidTestRunner.Builder(context, transformer) .build() .run(testId, editedMediaItem); - Log.i(TAG, "Tone mapped."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } catch (ExportException exception) { - Log.i(TAG, checkNotNull(exception.getCause()).toString()); - assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); - assertThat(exception.errorCode) - .isEqualTo(ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); + if (exception.getCause() != null + && (Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping HDR is not supported on this device.") + || Objects.equals( + exception.getCause().getMessage(), + "Tone-mapping requested but not supported by the decoder."))) { + // Expected on devices without a tone-mapping plugin for this codec. + return; + } + throw exception; } } } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingOpenGlTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingOpenGlTest.java index 246a17fb0a..f3ecec4def 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingOpenGlTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingOpenGlTest.java @@ -22,19 +22,18 @@ import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_720P_4_SECON import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_DOLBY_VISION_HDR; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_DOLBY_VISION_HDR_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.recordTestSkipped; -import static androidx.media3.transformer.mh.FileUtil.maybeAssertFileHasColorTransfer; +import static androidx.media3.transformer.mh.FileUtil.assertFileHasColorTransfer; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import android.content.Context; import androidx.media3.common.C; +import androidx.media3.common.ColorInfo; import androidx.media3.common.Format; import androidx.media3.common.MediaItem; import androidx.media3.common.util.GlUtil; -import androidx.media3.common.util.Log; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.mediacodec.MediaCodecUtil; import androidx.media3.transformer.AndroidTestUtil; -import androidx.media3.transformer.ExportException; import androidx.media3.transformer.ExportTestResult; import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.Transformer; @@ -52,13 +51,12 @@ import org.junit.runner.RunWith; */ @RunWith(AndroidJUnit4.class) public class ToneMapHdrToSdrUsingOpenGlTest { - public static final String TAG = "ToneMapHdrToSdrUsingOpenGlTest"; private final Context context = ApplicationProvider.getApplicationContext(); @Test - public void export_toneMap_hlg10File_toneMapsOrThrows() throws Exception { - String testId = "export_glToneMap_hlg10File_toneMapsOrThrows"; + public void export_toneMap_hlg10File_toneMaps() throws Exception { + String testId = "export_glToneMap_hlg10File_toneMaps"; if (!deviceSupportsOpenGlToneMapping( testId, /* inputFormat= */ MP4_ASSET_1080P_5_SECOND_HLG10_FORMAT)) { return; @@ -68,8 +66,8 @@ public class ToneMapHdrToSdrUsingOpenGlTest { } @Test - public void export_toneMap_hdr10File_toneMapsOrThrows() throws Exception { - String testId = "export_glToneMap_hdr10File_toneMapsOrThrows"; + public void export_toneMap_hdr10File_toneMaps() throws Exception { + String testId = "export_glToneMap_hdr10File_toneMaps"; if (!deviceSupportsOpenGlToneMapping( testId, /* inputFormat= */ MP4_ASSET_720P_4_SECOND_HDR10_FORMAT)) { return; @@ -79,8 +77,8 @@ public class ToneMapHdrToSdrUsingOpenGlTest { } @Test - public void export_toneMap_dolbyVisionFile_toneMapsOrThrows() throws Exception { - String testId = "export_toneMap_dolbyVisionFile_toneMapsOrThrows"; + public void export_toneMap_dolbyVisionFile_toneMaps() throws Exception { + String testId = "export_toneMap_dolbyVisionFile_toneMaps"; if (!deviceSupportsOpenGlToneMapping( testId, /* inputFormat= */ MP4_ASSET_DOLBY_VISION_HDR_FORMAT)) { return; @@ -97,19 +95,11 @@ public class ToneMapHdrToSdrUsingOpenGlTest { .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL) .build()) .build(); - try { - ExportTestResult exportTestResult = - new TransformerAndroidTestRunner.Builder(context, transformer) - .build() - .run(testId, MediaItem.fromUri(fileUri)); - Log.i(TAG, "Tone mapped."); - maybeAssertFileHasColorTransfer(exportTestResult.filePath, C.COLOR_TRANSFER_SDR); - } catch (ExportException exception) { - Log.e(TAG, "Error during export.", exception); - if (exception.errorCode != ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED) { - throw exception; - } - } + ExportTestResult exportTestResult = + new TransformerAndroidTestRunner.Builder(context, transformer) + .build() + .run(testId, MediaItem.fromUri(fileUri)); + assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR); } private static boolean deviceSupportsOpenGlToneMapping(String testId, Format inputFormat) @@ -129,6 +119,12 @@ public class ToneMapHdrToSdrUsingOpenGlTest { } return !AndroidTestUtil.skipAndLogIfFormatsUnsupported( - getApplicationContext(), testId, /* inputFormat= */ inputFormat, /* outputFormat= */ null); + getApplicationContext(), + testId, + inputFormat, + /* outputFormat= */ inputFormat + .buildUpon() + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build()); } }