mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add Dolby Vision Transcoding and Editing Support
This commit is contained in:
parent
563f4d845a
commit
a5524c09c5
@ -135,6 +135,9 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
|||||||
if (SDK_INT >= 31 && requestSdrToneMapping) {
|
if (SDK_INT >= 31 && requestSdrToneMapping) {
|
||||||
mediaFormat.setInteger(
|
mediaFormat.setInteger(
|
||||||
MediaFormat.KEY_COLOR_TRANSFER_REQUEST, MediaFormat.COLOR_TRANSFER_SDR_VIDEO);
|
MediaFormat.KEY_COLOR_TRANSFER_REQUEST, MediaFormat.COLOR_TRANSFER_SDR_VIDEO);
|
||||||
|
} else if (SDK_INT >= 31 && MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)) {
|
||||||
|
mediaFormat.setInteger(
|
||||||
|
MediaFormat.KEY_COLOR_TRANSFER_REQUEST, MediaFormat.COLOR_TRANSFER_HLG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -150,6 +150,13 @@ public final class EncoderUtil {
|
|||||||
return ImmutableList.of(MediaCodecInfo.CodecProfileLevel.AV1ProfileMain10HDR10);
|
return ImmutableList.of(MediaCodecInfo.CodecProfileLevel.AV1ProfileMain10HDR10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MimeTypes.VIDEO_DOLBY_VISION:
|
||||||
|
if (colorTransfer == C.COLOR_TRANSFER_HLG) {
|
||||||
|
return ImmutableList.of(
|
||||||
|
MediaCodecInfo.CodecProfileLevel.DolbyVisionProfileDvheSt);
|
||||||
|
}
|
||||||
|
// CodecProfileLevel does not support PQ for Dolby Vision.
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,12 @@ import static androidx.media3.common.util.Util.castNonNull;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
|
import android.media.MediaCodecInfo;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.media.MediaMuxer;
|
import android.media.MediaMuxer;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.SparseLongArray;
|
import android.util.SparseLongArray;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.Metadata;
|
import androidx.media3.common.Metadata;
|
||||||
@ -108,6 +111,11 @@ import java.nio.ByteBuffer;
|
|||||||
if (isVideo) {
|
if (isVideo) {
|
||||||
mediaFormat = MediaFormat.createVideoFormat(sampleMimeType, format.width, format.height);
|
mediaFormat = MediaFormat.createVideoFormat(sampleMimeType, format.width, format.height);
|
||||||
MediaFormatUtil.maybeSetColorInfo(mediaFormat, format.colorInfo);
|
MediaFormatUtil.maybeSetColorInfo(mediaFormat, format.colorInfo);
|
||||||
|
if (sampleMimeType.equals(MimeTypes.VIDEO_DOLBY_VISION) &&
|
||||||
|
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_PROFILE, getDvProfile(format));
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_LEVEL, getDvLevel(format));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
mediaMuxer.setOrientationHint(format.rotationDegrees);
|
mediaMuxer.setOrientationHint(format.rotationDegrees);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
@ -276,9 +284,64 @@ import java.nio.ByteBuffer;
|
|||||||
if (SDK_INT >= 24) {
|
if (SDK_INT >= 24) {
|
||||||
supportedMimeTypes.add(MimeTypes.VIDEO_H265);
|
supportedMimeTypes.add(MimeTypes.VIDEO_H265);
|
||||||
}
|
}
|
||||||
|
if (SDK_INT >= 33) {
|
||||||
|
supportedMimeTypes.add(MimeTypes.VIDEO_DOLBY_VISION);
|
||||||
|
}
|
||||||
if (SDK_INT >= 34) {
|
if (SDK_INT >= 34) {
|
||||||
supportedMimeTypes.add(MimeTypes.VIDEO_AV1);
|
supportedMimeTypes.add(MimeTypes.VIDEO_AV1);
|
||||||
}
|
}
|
||||||
return supportedMimeTypes.build();
|
return supportedMimeTypes.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get Dolby Vision profile
|
||||||
|
// Refer to https://professionalsupport.dolby.com/s/article/What-is-Dolby-Vision-Profile
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
|
||||||
|
private static int getDvProfile(Format format) {
|
||||||
|
// Currently, only profile 8 is supported for encoding
|
||||||
|
// TODO: set profile ID based on format.
|
||||||
|
return MediaCodecInfo.CodecProfileLevel.DolbyVisionProfileDvheSt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Dolby Vision level
|
||||||
|
// Refer to https://professionalsupport.dolby.com/s/article/What-is-Dolby-Vision-Profile
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
|
||||||
|
private static int getDvLevel(Format format) {
|
||||||
|
int level = -1;
|
||||||
|
int maxWidthHeight = Math.max(format.width, format.height);
|
||||||
|
float pps = format.width * format.height * format.frameRate;
|
||||||
|
|
||||||
|
if (maxWidthHeight <= 1280) {
|
||||||
|
if (pps <= 22118400) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelHd24; // Level 01
|
||||||
|
} else if (pps <= 27648000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelHd30; // Level 02
|
||||||
|
}
|
||||||
|
} else if (maxWidthHeight <= 1920 && pps <= 49766400) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd24; // Level 03
|
||||||
|
} else if (maxWidthHeight <= 2560 && pps <= 62208000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd30; // Level 04
|
||||||
|
} else if (maxWidthHeight <= 3840) {
|
||||||
|
if (pps <= 124416000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd60; // Level 05
|
||||||
|
} else if (pps <= 199065600) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelUhd24; // Level 06
|
||||||
|
} else if (pps <= 248832000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelUhd30; // Level 07
|
||||||
|
} else if (pps <= 398131200) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelUhd48; // Level 08
|
||||||
|
} else if (pps <= 497664000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelUhd60; // Level 09
|
||||||
|
} else if (pps <= 995328000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelUhd120; // Level 10
|
||||||
|
}
|
||||||
|
} else if (maxWidthHeight <= 7680) {
|
||||||
|
if (pps <= 995328000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevel8k30; // Level 11
|
||||||
|
} else if (pps <= 1990656000) {
|
||||||
|
level = MediaCodecInfo.CodecProfileLevel.DolbyVisionLevel8k60; // Level 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return level;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user