blob: b88c644b8ab4336d79fb9daf85b172a5c9d1804f [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.media;
import android.media.MediaCodecInfo.CodecProfileLevel;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import java.util.ArrayList;
import java.util.List;
@JNINamespace("media")
@MainDex
class CodecProfileLevelList {
private static final String TAG = "CodecProfileLevelList";
private final List<CodecProfileLevelAdapter> mList;
public CodecProfileLevelList() {
mList = new ArrayList<CodecProfileLevelAdapter>();
}
public boolean addCodecProfileLevel(String mime, CodecProfileLevel codecProfileLevel) {
try {
int codec = getCodecFromMime(mime);
mList.add(new CodecProfileLevelAdapter(codec,
mediaCodecProfileToChromiumMediaProfile(codec, codecProfileLevel.profile),
mediaCodecLevelToChromiumMediaLevel(codec, codecProfileLevel.level)));
return true;
} catch (UnsupportedCodecProfileException e) {
return false;
}
}
public boolean addCodecProfileLevel(int codec, int profile, int level) {
mList.add(new CodecProfileLevelAdapter(codec, profile, level));
return true;
}
public Object[] toArray() {
return mList.toArray();
}
static class CodecProfileLevelAdapter {
private final int mCodec;
private final int mProfile;
private final int mLevel;
public CodecProfileLevelAdapter(int codec, int profile, int level) {
mCodec = codec;
mProfile = profile;
mLevel = level;
}
@CalledByNative("CodecProfileLevelAdapter")
public int getCodec() {
return mCodec;
}
@CalledByNative("CodecProfileLevelAdapter")
public int getProfile() {
return mProfile;
}
@CalledByNative("CodecProfileLevelAdapter")
public int getLevel() {
return mLevel;
}
}
private static class UnsupportedCodecProfileException extends RuntimeException {}
private static int getCodecFromMime(String mime) {
if (mime.endsWith("vp9")) return VideoCodec.VP9;
if (mime.endsWith("vp8")) return VideoCodec.VP8;
if (mime.endsWith("avc")) return VideoCodec.H264;
if (mime.endsWith("hevc")) return VideoCodec.HEVC;
if (mime.endsWith("dolby-vision")) return VideoCodec.DOLBY_VISION;
throw new UnsupportedCodecProfileException();
}
private static int mediaCodecProfileToChromiumMediaProfile(int codec, int profile) {
switch (codec) {
case VideoCodec.H264:
switch (profile) {
case CodecProfileLevel.AVCProfileBaseline:
return VideoCodecProfile.H264PROFILE_BASELINE;
case CodecProfileLevel.AVCProfileMain:
return VideoCodecProfile.H264PROFILE_MAIN;
case CodecProfileLevel.AVCProfileExtended:
return VideoCodecProfile.H264PROFILE_EXTENDED;
case CodecProfileLevel.AVCProfileHigh:
return VideoCodecProfile.H264PROFILE_HIGH;
case CodecProfileLevel.AVCProfileHigh10:
return VideoCodecProfile.H264PROFILE_HIGH10PROFILE;
case CodecProfileLevel.AVCProfileHigh422:
return VideoCodecProfile.H264PROFILE_HIGH422PROFILE;
case CodecProfileLevel.AVCProfileHigh444:
return VideoCodecProfile.H264PROFILE_HIGH444PREDICTIVEPROFILE;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.VP8:
switch (profile) {
case CodecProfileLevel.VP8ProfileMain:
return VideoCodecProfile.VP8PROFILE_ANY;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.VP9:
switch (profile) {
case CodecProfileLevel.VP9Profile0:
return VideoCodecProfile.VP9PROFILE_PROFILE0;
case CodecProfileLevel.VP9Profile1:
return VideoCodecProfile.VP9PROFILE_PROFILE1;
case CodecProfileLevel.VP9Profile2:
case CodecProfileLevel.VP9Profile2HDR:
return VideoCodecProfile.VP9PROFILE_PROFILE2;
case CodecProfileLevel.VP9Profile3:
case CodecProfileLevel.VP9Profile3HDR:
return VideoCodecProfile.VP9PROFILE_PROFILE3;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.HEVC:
switch (profile) {
case CodecProfileLevel.HEVCProfileMain:
return VideoCodecProfile.HEVCPROFILE_MAIN;
case CodecProfileLevel.HEVCProfileMain10:
case CodecProfileLevel.HEVCProfileMain10HDR10:
return VideoCodecProfile.HEVCPROFILE_MAIN10;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.DOLBY_VISION:
switch (profile) {
// Profile 0, 1, 2, 3, 6 are not supported for new applications.
case CodecProfileLevel.DolbyVisionProfileDvheDtr:
return VideoCodecProfile.DOLBYVISION_PROFILE4;
case CodecProfileLevel.DolbyVisionProfileDvheStn:
return VideoCodecProfile.DOLBYVISION_PROFILE5;
case CodecProfileLevel.DolbyVisionProfileDvheDtb:
return VideoCodecProfile.DOLBYVISION_PROFILE7;
case CodecProfileLevel.DolbyVisionProfileDvheSt:
return VideoCodecProfile.DOLBYVISION_PROFILE8;
case CodecProfileLevel.DolbyVisionProfileDvavSe:
return VideoCodecProfile.DOLBYVISION_PROFILE9;
default:
throw new UnsupportedCodecProfileException();
}
default:
throw new UnsupportedCodecProfileException();
}
}
private static int mediaCodecLevelToChromiumMediaLevel(int codec, int level) {
switch (codec) {
case VideoCodec.H264:
switch (level) {
case CodecProfileLevel.AVCLevel1:
return 10;
case CodecProfileLevel.AVCLevel11:
return 11;
case CodecProfileLevel.AVCLevel12:
return 12;
case CodecProfileLevel.AVCLevel13:
return 13;
case CodecProfileLevel.AVCLevel2:
return 20;
case CodecProfileLevel.AVCLevel21:
return 21;
case CodecProfileLevel.AVCLevel22:
return 22;
case CodecProfileLevel.AVCLevel3:
return 30;
case CodecProfileLevel.AVCLevel31:
return 31;
case CodecProfileLevel.AVCLevel32:
return 32;
case CodecProfileLevel.AVCLevel4:
return 40;
case CodecProfileLevel.AVCLevel41:
return 41;
case CodecProfileLevel.AVCLevel42:
return 42;
case CodecProfileLevel.AVCLevel5:
return 50;
case CodecProfileLevel.AVCLevel51:
return 51;
case CodecProfileLevel.AVCLevel52:
return 52;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.VP8:
switch (level) {
case CodecProfileLevel.VP8Level_Version0:
return 0;
case CodecProfileLevel.VP8Level_Version1:
return 1;
case CodecProfileLevel.VP8Level_Version2:
return 2;
case CodecProfileLevel.VP8Level_Version3:
return 3;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.VP9:
switch (level) {
case CodecProfileLevel.VP9Level1:
return 10;
case CodecProfileLevel.VP9Level11:
return 11;
case CodecProfileLevel.VP9Level2:
return 20;
case CodecProfileLevel.VP9Level21:
return 21;
case CodecProfileLevel.VP9Level3:
return 30;
case CodecProfileLevel.VP9Level31:
return 31;
case CodecProfileLevel.VP9Level4:
return 40;
case CodecProfileLevel.VP9Level41:
return 41;
case CodecProfileLevel.VP9Level5:
return 50;
case CodecProfileLevel.VP9Level51:
return 51;
case CodecProfileLevel.VP9Level52:
return 52;
case CodecProfileLevel.VP9Level6:
return 60;
case CodecProfileLevel.VP9Level61:
return 61;
case CodecProfileLevel.VP9Level62:
return 62;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.HEVC:
switch (level) {
case CodecProfileLevel.HEVCHighTierLevel1:
case CodecProfileLevel.HEVCMainTierLevel1:
return 30;
case CodecProfileLevel.HEVCHighTierLevel2:
case CodecProfileLevel.HEVCMainTierLevel2:
return 60;
case CodecProfileLevel.HEVCHighTierLevel21:
case CodecProfileLevel.HEVCMainTierLevel21:
return 63;
case CodecProfileLevel.HEVCHighTierLevel3:
case CodecProfileLevel.HEVCMainTierLevel3:
return 90;
case CodecProfileLevel.HEVCHighTierLevel31:
case CodecProfileLevel.HEVCMainTierLevel31:
return 93;
case CodecProfileLevel.HEVCHighTierLevel4:
case CodecProfileLevel.HEVCMainTierLevel4:
return 120;
case CodecProfileLevel.HEVCHighTierLevel41:
case CodecProfileLevel.HEVCMainTierLevel41:
return 123;
case CodecProfileLevel.HEVCHighTierLevel5:
case CodecProfileLevel.HEVCMainTierLevel5:
return 150;
case CodecProfileLevel.HEVCHighTierLevel51:
case CodecProfileLevel.HEVCMainTierLevel51:
return 153;
case CodecProfileLevel.HEVCHighTierLevel52:
case CodecProfileLevel.HEVCMainTierLevel52:
return 156;
case CodecProfileLevel.HEVCHighTierLevel6:
case CodecProfileLevel.HEVCMainTierLevel6:
return 180;
case CodecProfileLevel.HEVCHighTierLevel61:
case CodecProfileLevel.HEVCMainTierLevel61:
return 183;
case CodecProfileLevel.HEVCHighTierLevel62:
case CodecProfileLevel.HEVCMainTierLevel62:
return 186;
default:
throw new UnsupportedCodecProfileException();
}
case VideoCodec.DOLBY_VISION:
switch (level) {
case CodecProfileLevel.DolbyVisionLevelHd24:
return 1;
case CodecProfileLevel.DolbyVisionLevelHd30:
return 2;
case CodecProfileLevel.DolbyVisionLevelFhd24:
return 3;
case CodecProfileLevel.DolbyVisionLevelFhd30:
return 4;
case CodecProfileLevel.DolbyVisionLevelFhd60:
return 5;
case CodecProfileLevel.DolbyVisionLevelUhd24:
return 6;
case CodecProfileLevel.DolbyVisionLevelUhd30:
return 7;
case CodecProfileLevel.DolbyVisionLevelUhd48:
return 8;
case CodecProfileLevel.DolbyVisionLevelUhd60:
return 9;
default:
throw new UnsupportedCodecProfileException();
}
default:
throw new UnsupportedCodecProfileException();
}
}
}