HDR: Fix ForceInterpretHdrVideoAsSdrTest, and expand to all APIs.

Previously, this was limited to API 29. Expand this to all API versions.

Also, update the test to:
(1) skip based on SDR format input instead of HDR format input
(2) Check the exception message in order to disambiguate between the decoder tone
mapping error, and general video format support error.

PiperOrigin-RevId: 511002218
This commit is contained in:
huangdarwin 2023-02-20 16:40:16 +00:00 committed by Andrew Lewis
parent 43b8859cb7
commit b206a1afec
4 changed files with 57 additions and 28 deletions

View File

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

View File

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

View File

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

View File

@ -88,13 +88,13 @@ public final class TransformationRequest {
/**
* Interpret HDR input as SDR, likely with a washed out look.
*
* <p>Supported on API 29+.
*
* <p>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.
*
* <p>Using this API may lead to codec errors before API 29, per b/269759013.
*
* <p>Use of this flag may result in {@code ERROR_CODE_DECODING_FORMAT_UNSUPPORTED}.
*
* <p>This field is experimental, and will be renamed or removed in a future release.