Fallback to hevc transcoding for hdr AV1 files

PiperOrigin-RevId: 631362735
This commit is contained in:
tofunmi 2024-05-07 03:31:40 -07:00 committed by Copybara-Service
parent 4aa15e9463
commit b2d30a5722
4 changed files with 66 additions and 8 deletions

View file

@ -230,6 +230,21 @@ public final class AndroidTestUtil {
.setCodecs("hvc1.2.4.L153")
.build();
public static final String MP4_ASSET_AV1_2_SECOND_HDR10 = "asset:///media/mp4/hdr10-av1.mp4";
public static final Format MP4_ASSET_AV1_2_SECOND_HDR10_FORMAT =
new Format.Builder()
.setSampleMimeType(VIDEO_AV1)
.setWidth(1920)
.setHeight(1080)
.setFrameRate(59.94f)
.setColorInfo(
new ColorInfo.Builder()
.setColorSpace(C.COLOR_SPACE_BT2020)
.setColorRange(C.COLOR_RANGE_LIMITED)
.setColorTransfer(C.COLOR_TRANSFER_ST2084)
.build())
.build();
// This file needs alternative MIME type, meaning the decoder needs to be configured with
// video/hevc instead of video/dolby-vision.
public static final String MP4_ASSET_DOLBY_VISION_HDR = "asset:///media/mp4/dolbyVision-hdr.MOV";

View file

@ -22,6 +22,8 @@ import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_1080P_5_SECO
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_AV1_2_SECOND_HDR10;
import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_AV1_2_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.assumeFormatsSupported;
@ -30,6 +32,7 @@ import static androidx.media3.transformer.Composition.HDR_MODE_KEEP_HDR;
import static androidx.media3.transformer.Composition.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
import static androidx.media3.transformer.mh.HdrCapabilitiesUtil.assumeDeviceDoesNotSupportHdrEditing;
import static androidx.media3.transformer.mh.HdrCapabilitiesUtil.assumeDeviceSupportsHdrEditing;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@ -37,10 +40,12 @@ import android.net.Uri;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util;
import androidx.media3.effect.DefaultVideoFrameProcessor;
import androidx.media3.transformer.Composition;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.EncoderUtil;
import androidx.media3.transformer.ExportException;
import androidx.media3.transformer.ExportTestResult;
import androidx.media3.transformer.TransformationRequest;
@ -51,6 +56,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.junit.AssumptionViolatedException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -210,6 +216,46 @@ public final class HdrEditingTest {
assertThat(actualColorTransfer).isEqualTo(C.COLOR_TRANSFER_HLG);
}
@Test
public void
exportAndTranscode_av1FileWithAv1HdrEditingUnsupportedAndHevcHdrEditingSupported_fallsBackToH265()
throws Exception {
Context context = ApplicationProvider.getApplicationContext();
Format format = MP4_ASSET_AV1_2_SECOND_HDR10_FORMAT;
if (EncoderUtil.getSupportedEncodersForHdrEditing(MimeTypes.VIDEO_H265, format.colorInfo)
.isEmpty()) {
String skipReason = "No H265 HDR editing support for " + format.colorInfo;
recordTestSkipped(getApplicationContext(), testId, skipReason);
throw new AssumptionViolatedException(skipReason);
}
if (!EncoderUtil.getSupportedEncodersForHdrEditing(MimeTypes.VIDEO_AV1, format.colorInfo)
.isEmpty()) {
String skipReason = "AV1 HDR editing support for " + format.colorInfo;
recordTestSkipped(getApplicationContext(), testId, skipReason);
throw new AssumptionViolatedException(skipReason);
}
assumeFormatsSupported(
context,
testId,
/* inputFormat= */ format,
/* outputFormat= */ format.buildUpon().setSampleMimeType(MimeTypes.VIDEO_H265).build());
Transformer transformer = new Transformer.Builder(context).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_AV1_2_SECOND_HDR10));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(FORCE_TRANSCODE_VIDEO_EFFECTS).build();
ExportTestResult exportTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(testId, editedMediaItem);
Format outputFormat =
retrieveTrackFormat(context, exportTestResult.filePath, C.TRACK_TYPE_VIDEO);
assertThat(outputFormat.colorInfo.colorTransfer).isEqualTo(C.COLOR_TRANSFER_ST2084);
assertThat(outputFormat.sampleMimeType).isEqualTo(MimeTypes.VIDEO_H265);
}
@Test
public void exportAndTranscodeHdr_ignoringSdrWorkingColorSpace_whenHdrEditingIsSupported()
throws Exception {

View file

@ -50,7 +50,6 @@ import androidx.media3.common.util.Util;
import androidx.media3.decoder.DecoderInputBuffer;
import androidx.media3.effect.DebugTraceUtil;
import androidx.media3.effect.VideoCompositorSettings;
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.MoreExecutors;
import java.nio.ByteBuffer;
@ -275,16 +274,14 @@ import org.checkerframework.dataflow.qual.Pure;
ImmutableList<MediaCodecInfo> hdrEncoders =
getSupportedEncodersForHdrEditing(requestedOutputMimeType, inputFormat.colorInfo);
if (hdrEncoders.isEmpty()) {
@Nullable
String alternativeMimeType = MediaCodecUtil.getAlternativeCodecMimeType(inputFormat);
if (alternativeMimeType != null) {
requestedOutputMimeType = alternativeMimeType;
hdrEncoders =
getSupportedEncodersForHdrEditing(alternativeMimeType, inputFormat.colorInfo);
}
// Fallback H.265/HEVC codecs for HDR content to avoid tonemapping.
hdrEncoders =
getSupportedEncodersForHdrEditing(MimeTypes.VIDEO_H265, inputFormat.colorInfo);
}
if (hdrEncoders.isEmpty()) {
hdrMode = HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
} else {
requestedOutputMimeType = MimeTypes.VIDEO_H265;
}
}