提交 ca2bfbc5 编写于 作者: O olly 提交者: Oliver Woodman

DashManifestParser: Move schemeType up to DrmInitData

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=167171407
上级 daafbb1f
......@@ -31,15 +31,15 @@ import junit.framework.TestCase;
*/
public class DrmInitDataTest extends TestCase {
private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, "cbc1", VIDEO_MP4,
private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
private static final SchemeData DATA_2 = new SchemeData(PLAYREADY_UUID, null, VIDEO_MP4,
private static final SchemeData DATA_2 = new SchemeData(PLAYREADY_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_1B = new SchemeData(WIDEVINE_UUID, "cbc1", VIDEO_MP4,
private static final SchemeData DATA_1B = new SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
private static final SchemeData DATA_2B = new SchemeData(PLAYREADY_UUID, null, VIDEO_MP4,
private static final SchemeData DATA_2B = new SchemeData(PLAYREADY_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, null, VIDEO_MP4,
private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, VIDEO_MP4,
TestUtil.buildTestData(128, 3 /* data seed */));
public void testParcelable() {
......
......@@ -153,7 +153,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
}
private static DrmInitData newDrmInitData() {
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "cenc", "mimeType",
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "mimeType",
new byte[] {1, 4, 7, 0, 3, 6}));
}
......
......@@ -278,7 +278,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
// No data for this manager's scheme.
return false;
}
String schemeType = schemeData.type;
String schemeType = drmInitData.schemeType;
if (schemeType == null || C.CENC_TYPE_cenc.equals(schemeType)) {
// If there is no scheme information, assume patternless AES-CTR.
return true;
......
......@@ -37,6 +37,11 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
// Lazily initialized hashcode.
private int hashCode;
/**
* The protection scheme type, or null if not applicable or unknown.
*/
@Nullable public final String schemeType;
/**
* Number of {@link SchemeData}s.
*/
......@@ -46,17 +51,19 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
*/
public DrmInitData(List<SchemeData> schemeDatas) {
this(false, schemeDatas.toArray(new SchemeData[schemeDatas.size()]));
this(null, false, schemeDatas.toArray(new SchemeData[schemeDatas.size()]));
}
/**
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
*/
public DrmInitData(SchemeData... schemeDatas) {
this(true, schemeDatas);
this(null, true, schemeDatas);
}
private DrmInitData(boolean cloneSchemeDatas, SchemeData... schemeDatas) {
private DrmInitData(@Nullable String schemeType, boolean cloneSchemeDatas,
SchemeData... schemeDatas) {
this.schemeType = schemeType;
if (cloneSchemeDatas) {
schemeDatas = schemeDatas.clone();
}
......@@ -74,6 +81,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
}
/* package */ DrmInitData(Parcel in) {
schemeType = in.readString();
schemeDatas = in.createTypedArray(SchemeData.CREATOR);
schemeDataCount = schemeDatas.length;
}
......@@ -104,36 +112,24 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
}
/**
* Returns a copy of the {@link DrmInitData} instance whose {@link SchemeData}s have been updated
* to have the specified scheme type.
* Returns a copy with the specified protection scheme type.
*
* @param schemeType A protection scheme type. May be null.
* @return A copy of the {@link DrmInitData} instance whose {@link SchemeData}s have been updated
* to have the specified scheme type.
* @return A copy with the specified protection scheme type.
*/
public DrmInitData copyWithSchemeType(@Nullable String schemeType) {
boolean isCopyRequired = false;
for (SchemeData schemeData : schemeDatas) {
if (!Util.areEqual(schemeData.type, schemeType)) {
isCopyRequired = true;
break;
}
}
if (isCopyRequired) {
SchemeData[] schemeDatas = new SchemeData[this.schemeDatas.length];
for (int i = 0; i < schemeDatas.length; i++) {
schemeDatas[i] = this.schemeDatas[i].copyWithSchemeType(schemeType);
}
return new DrmInitData(schemeDatas);
} else {
if (Util.areEqual(this.schemeType, schemeType)) {
return this;
}
return new DrmInitData(schemeType, false, schemeDatas);
}
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Arrays.hashCode(schemeDatas);
int result = (schemeType == null ? 0 : schemeType.hashCode());
result = 31 * result + Arrays.hashCode(schemeDatas);
hashCode = result;
}
return hashCode;
}
......@@ -146,7 +142,9 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return Arrays.equals(schemeDatas, ((DrmInitData) obj).schemeDatas);
DrmInitData other = (DrmInitData) obj;
return Util.areEqual(schemeType, other.schemeType)
&& Arrays.equals(schemeDatas, other.schemeDatas);
}
@Override
......@@ -164,6 +162,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(schemeType);
dest.writeTypedArray(schemeDatas, 0);
}
......@@ -195,10 +194,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* applies to all schemes).
*/
private final UUID uuid;
/**
* The protection scheme type, or null if not applicable or unknown.
*/
@Nullable public final String type;
/**
* The mimeType of {@link #data}.
*/
......@@ -215,26 +210,22 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
/**
* @param uuid The {@link UUID} of the DRM scheme, or {@link C#UUID_NIL} if the data is
* universal (i.e. applies to all schemes).
* @param type The type of the protection scheme, or null if not applicable or unknown.
* @param mimeType The mimeType of the initialization data.
* @param data The initialization data.
*/
public SchemeData(UUID uuid, @Nullable String type, String mimeType, byte[] data) {
this(uuid, type, mimeType, data, false);
public SchemeData(UUID uuid, String mimeType, byte[] data) {
this(uuid, mimeType, data, false);
}
/**
* @param uuid The {@link UUID} of the DRM scheme, or {@link C#UUID_NIL} if the data is
* universal (i.e. applies to all schemes).
* @param type The type of the protection scheme, or null if not applicable or unknown.
* @param mimeType The mimeType of the initialization data.
* @param data The initialization data.
* @param requiresSecureDecryption Whether secure decryption is required.
*/
public SchemeData(UUID uuid, @Nullable String type, String mimeType, byte[] data,
boolean requiresSecureDecryption) {
public SchemeData(UUID uuid, String mimeType, byte[] data, boolean requiresSecureDecryption) {
this.uuid = Assertions.checkNotNull(uuid);
this.type = type;
this.mimeType = Assertions.checkNotNull(mimeType);
this.data = Assertions.checkNotNull(data);
this.requiresSecureDecryption = requiresSecureDecryption;
......@@ -242,7 +233,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
/* package */ SchemeData(Parcel in) {
uuid = new UUID(in.readLong(), in.readLong());
type = in.readString();
mimeType = in.readString();
data = in.createByteArray();
requiresSecureDecryption = in.readByte() != 0;
......@@ -258,19 +248,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
return C.UUID_NIL.equals(uuid) || schemeUuid.equals(uuid);
}
/**
* Returns a copy of the {@link SchemeData} instance with the given scheme type.
*
* @param type A protection scheme type.
* @return A copy of the {@link SchemeData} instance with the given scheme type.
*/
public SchemeData copyWithSchemeType(String type) {
if (Util.areEqual(this.type, type)) {
return this;
}
return new SchemeData(uuid, type, mimeType, data, requiresSecureDecryption);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SchemeData)) {
......@@ -281,14 +258,13 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
}
SchemeData other = (SchemeData) obj;
return mimeType.equals(other.mimeType) && Util.areEqual(uuid, other.uuid)
&& Util.areEqual(type, other.type) && Arrays.equals(data, other.data);
&& Arrays.equals(data, other.data);
}
@Override
public int hashCode() {
if (hashCode == 0) {
int result = uuid.hashCode();
result = 31 * result + (type == null ? 0 : type.hashCode());
result = 31 * result + mimeType.hashCode();
result = 31 * result + Arrays.hashCode(data);
hashCode = result;
......@@ -307,7 +283,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(uuid.getMostSignificantBits());
dest.writeLong(uuid.getLeastSignificantBits());
dest.writeString(type);
dest.writeString(mimeType);
dest.writeByteArray(data);
dest.writeByte((byte) (requiresSecureDecryption ? 1 : 0));
......
......@@ -628,7 +628,7 @@ public final class MatroskaExtractor implements Extractor {
if (currentTrack.cryptoData == null) {
throw new ParserException("Encrypted Track found but ContentEncKeyID was not found");
}
currentTrack.drmInitData = new DrmInitData(new SchemeData(C.UUID_NIL, null,
currentTrack.drmInitData = new DrmInitData(new SchemeData(C.UUID_NIL,
MimeTypes.VIDEO_WEBM, currentTrack.cryptoData.encryptionKey));
}
break;
......
......@@ -1275,7 +1275,7 @@ public final class FragmentedMp4Extractor implements Extractor {
if (uuid == null) {
Log.w(TAG, "Skipped pssh atom (failed to extract uuid)");
} else {
schemeDatas.add(new SchemeData(uuid, null, MimeTypes.VIDEO_MP4, psshData));
schemeDatas.add(new SchemeData(uuid, MimeTypes.VIDEO_MP4, psshData));
}
}
}
......
......@@ -60,11 +60,11 @@ public final class FormatTest {
@Test
public void testParcelable() {
DrmInitData.SchemeData DRM_DATA_1 = new DrmInitData.SchemeData(WIDEVINE_UUID, "cenc", VIDEO_MP4,
DrmInitData.SchemeData drmData1 = new DrmInitData.SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData.SchemeData DRM_DATA_2 = new DrmInitData.SchemeData(C.UUID_NIL, null, VIDEO_WEBM,
DrmInitData.SchemeData drmData2 = new DrmInitData.SchemeData(C.UUID_NIL, VIDEO_WEBM,
TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData drmInitData = new DrmInitData(DRM_DATA_1, DRM_DATA_2);
DrmInitData drmInitData = new DrmInitData(drmData1, drmData2);
byte[] projectionData = new byte[] {1, 2, 3};
Metadata metadata = new Metadata(
new TextInformationFrame("id1", "description1", "value1"),
......
......@@ -75,7 +75,7 @@ public final class DashUtilTest extends TestCase {
}
private static DrmInitData newDrmInitData() {
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, null, "mimeType",
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "mimeType",
new byte[] {1, 4, 7, 0, 3, 6}));
}
......
......@@ -238,6 +238,7 @@ public class DashManifestParser extends DefaultHandler
int audioChannels = Format.NO_VALUE;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE);
String language = xpp.getAttributeValue(null, "lang");
String drmSchemeType = null;
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
ArrayList<Descriptor> accessibilityDescriptors = new ArrayList<>();
......@@ -254,9 +255,12 @@ public class DashManifestParser extends DefaultHandler
seenFirstBaseUrl = true;
}
} else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) {
SchemeData contentProtection = parseContentProtection(xpp);
if (contentProtection != null) {
drmSchemeDatas.add(contentProtection);
Pair<String, SchemeData> contentProtection = parseContentProtection(xpp);
if (contentProtection.first != null) {
drmSchemeType = contentProtection.first;
}
if (contentProtection.second != null) {
drmSchemeDatas.add(contentProtection.second);
}
} else if (XmlPullParserUtil.isStartTag(xpp, "ContentComponent")) {
language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang"));
......@@ -293,7 +297,7 @@ public class DashManifestParser extends DefaultHandler
List<Representation> representations = new ArrayList<>(representationInfos.size());
for (int i = 0; i < representationInfos.size(); i++) {
representations.add(buildRepresentation(representationInfos.get(i), contentId,
drmSchemeDatas, inbandEventStreams));
drmSchemeType, drmSchemeDatas, inbandEventStreams));
}
return buildAdaptationSet(id, contentType, representations, accessibilityDescriptors,
......@@ -311,9 +315,9 @@ public class DashManifestParser extends DefaultHandler
String contentType = xpp.getAttributeValue(null, "contentType");
return TextUtils.isEmpty(contentType) ? C.TRACK_TYPE_UNKNOWN
: MimeTypes.BASE_TYPE_AUDIO.equals(contentType) ? C.TRACK_TYPE_AUDIO
: MimeTypes.BASE_TYPE_VIDEO.equals(contentType) ? C.TRACK_TYPE_VIDEO
: MimeTypes.BASE_TYPE_TEXT.equals(contentType) ? C.TRACK_TYPE_TEXT
: C.TRACK_TYPE_UNKNOWN;
: MimeTypes.BASE_TYPE_VIDEO.equals(contentType) ? C.TRACK_TYPE_VIDEO
: MimeTypes.BASE_TYPE_TEXT.equals(contentType) ? C.TRACK_TYPE_TEXT
: C.TRACK_TYPE_UNKNOWN;
}
protected int getContentType(Format format) {
......@@ -336,19 +340,20 @@ public class DashManifestParser extends DefaultHandler
* @param xpp The parser from which to read.
* @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element.
* @return {@link SchemeData} parsed from the ContentProtection element, or null if the element is
* unsupported.
* @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
* Either or both may be null, depending on the ContentProtection element being parsed.
*/
protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullParserException,
IOException {
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
throws XmlPullParserException, IOException {
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
boolean isPlayReady = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95".equals(schemeIdUri);
String schemeType = xpp.getAttributeValue(null, "value");
String schemeType = null;
byte[] data = null;
UUID uuid = null;
boolean requiresSecureDecoder = false;
if ("urn:mpeg:dash:mp4protection:2011".equals(schemeIdUri)) {
schemeType = xpp.getAttributeValue(null, "value");
String defaultKid = xpp.getAttributeValue(null, "cenc:default_KID");
if (defaultKid != null) {
UUID keyId = UUID.fromString(defaultKid);
......@@ -379,8 +384,9 @@ public class DashManifestParser extends DefaultHandler
requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
}
} while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
return data != null
? new SchemeData(uuid, schemeType, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null;
SchemeData schemeData = data != null
? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null;
return Pair.create(schemeType, schemeData);
}
/**
......@@ -432,6 +438,7 @@ public class DashManifestParser extends DefaultHandler
float frameRate = parseFrameRate(xpp, adaptationSetFrameRate);
int audioChannels = adaptationSetAudioChannels;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", adaptationSetAudioSamplingRate);
String drmSchemeType = null;
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
......@@ -452,9 +459,12 @@ public class DashManifestParser extends DefaultHandler
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) {
SchemeData contentProtection = parseContentProtection(xpp);
if (contentProtection != null) {
drmSchemeDatas.add(contentProtection);
Pair<String, SchemeData> contentProtection = parseContentProtection(xpp);
if (contentProtection.first != null) {
drmSchemeType = contentProtection.first;
}
if (contentProtection.second != null) {
drmSchemeDatas.add(contentProtection.second);
}
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
......@@ -466,7 +476,8 @@ public class DashManifestParser extends DefaultHandler
adaptationSetAccessibilityDescriptors, codecs);
segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase();
return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas, inbandEventStreams);
return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeType, drmSchemeDatas,
inbandEventStreams);
}
protected Format buildFormat(String id, String containerMimeType, int width, int height,
......@@ -499,13 +510,19 @@ public class DashManifestParser extends DefaultHandler
}
protected Representation buildRepresentation(RepresentationInfo representationInfo,
String contentId, ArrayList<SchemeData> extraDrmSchemeDatas,
String contentId, String extraDrmSchemeType, ArrayList<SchemeData> extraDrmSchemeDatas,
ArrayList<Descriptor> extraInbandEventStreams) {
Format format = representationInfo.format;
String drmSchemeType = representationInfo.drmSchemeType != null
? representationInfo.drmSchemeType : extraDrmSchemeType;
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
drmSchemeDatas.addAll(extraDrmSchemeDatas);
if (!drmSchemeDatas.isEmpty()) {
format = format.copyWithDrmInitData(new DrmInitData(drmSchemeDatas));
DrmInitData drmInitData = new DrmInitData(drmSchemeDatas);
if (drmSchemeType != null) {
drmInitData = drmInitData.copyWithSchemeType(drmSchemeType);
}
format = format.copyWithDrmInitData(drmInitData);
}
ArrayList<Descriptor> inbandEventStremas = representationInfo.inbandEventStreams;
inbandEventStremas.addAll(extraInbandEventStreams);
......@@ -946,14 +963,17 @@ public class DashManifestParser extends DefaultHandler
public final Format format;
public final String baseUrl;
public final SegmentBase segmentBase;
public final String drmSchemeType;
public final ArrayList<SchemeData> drmSchemeDatas;
public final ArrayList<Descriptor> inbandEventStreams;
public RepresentationInfo(Format format, String baseUrl, SegmentBase segmentBase,
ArrayList<SchemeData> drmSchemeDatas, ArrayList<Descriptor> inbandEventStreams) {
String drmSchemeType, ArrayList<SchemeData> drmSchemeDatas,
ArrayList<Descriptor> inbandEventStreams) {
this.format = format;
this.baseUrl = baseUrl;
this.segmentBase = segmentBase;
this.drmSchemeType = drmSchemeType;
this.drmSchemeDatas = drmSchemeDatas;
this.inbandEventStreams = inbandEventStreams;
}
......
......@@ -375,7 +375,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
StreamElement[] streamElementArray = new StreamElement[streamElements.size()];
streamElements.toArray(streamElementArray);
if (protectionElement != null) {
DrmInitData drmInitData = new DrmInitData(new SchemeData(protectionElement.uuid, null,
DrmInitData drmInitData = new DrmInitData(new SchemeData(protectionElement.uuid,
MimeTypes.VIDEO_MP4, protectionElement.data));
for (StreamElement streamElement : streamElementArray) {
for (int i = 0; i < streamElement.formats.length; i++) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册