Tidy color info checking tests

ExoPlayer extractors (backing `MetadataRetriever`) now parse the color format
from the bitstream so using `MetadataRetriever` should be an equivalent but
more lightweight way to verify the color info.

Also remove try/catch blocks in test code calling into these methods, and add
skipping based on decoder capabilities in the cases where it was missing.

PiperOrigin-RevId: 537789483
(cherry picked from commit 74478f2478)
This commit is contained in:
andrewlewis 2023-06-05 07:12:50 +00:00 committed by Tofunmi Adigun-Hameed
parent 4bb00d5e2e
commit 3ef7bc291c
5 changed files with 283 additions and 165 deletions

View file

@ -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.
*
* <p>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() {}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}

View file

@ -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());
}
}