mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Fill manifest drm info with media files' pssh when needed
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=174185407
This commit is contained in:
parent
46172ffd0f
commit
8c424798c4
5 changed files with 144 additions and 47 deletions
|
|
@ -21,6 +21,7 @@ import android.media.MediaFormat;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||||
|
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||||
import com.google.android.exoplayer2.metadata.Metadata;
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
@ -464,8 +465,8 @@ public final class Format implements Parcelable {
|
||||||
float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate;
|
float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate;
|
||||||
@C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags;
|
@C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags;
|
||||||
String language = this.language == null ? manifestFormat.language : this.language;
|
String language = this.language == null ? manifestFormat.language : this.language;
|
||||||
DrmInitData drmInitData = manifestFormat.drmInitData != null ? manifestFormat.drmInitData
|
DrmInitData drmInitData = manifestFormat.drmInitData != null
|
||||||
: this.drmInitData;
|
? getFilledManifestDrmData(manifestFormat.drmInitData) : this.drmInitData;
|
||||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
||||||
height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
|
height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
|
||||||
colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
|
colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
|
||||||
|
|
@ -731,4 +732,42 @@ public final class Format implements Parcelable {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private DrmInitData getFilledManifestDrmData(DrmInitData manifestDrmData) {
|
||||||
|
// All exposed SchemeDatas must include key request information.
|
||||||
|
ArrayList<SchemeData> exposedSchemeDatas = new ArrayList<>();
|
||||||
|
ArrayList<SchemeData> emptySchemeDatas = new ArrayList<>();
|
||||||
|
for (int i = 0; i < manifestDrmData.schemeDataCount; i++) {
|
||||||
|
SchemeData schemeData = manifestDrmData.get(i);
|
||||||
|
if (schemeData.hasData()) {
|
||||||
|
exposedSchemeDatas.add(schemeData);
|
||||||
|
} else /* needs initialization data filling */ {
|
||||||
|
emptySchemeDatas.add(schemeData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emptySchemeDatas.isEmpty()) {
|
||||||
|
// Manifest DRM information is complete.
|
||||||
|
return manifestDrmData;
|
||||||
|
} else if (drmInitData == null) {
|
||||||
|
// The manifest DRM data needs filling but this format does not include enough information to
|
||||||
|
// do it. A subset of the manifest's scheme datas should not be exposed because a
|
||||||
|
// DrmSessionManager could decide it does not support the format, while the missing
|
||||||
|
// information comes in a format feed immediately after.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int needFillingCount = emptySchemeDatas.size();
|
||||||
|
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
|
||||||
|
SchemeData mediaSchemeData = drmInitData.get(i);
|
||||||
|
for (int j = 0; j < needFillingCount; j++) {
|
||||||
|
if (mediaSchemeData.canReplace(emptySchemeDatas.get(j))) {
|
||||||
|
exposedSchemeDatas.add(mediaSchemeData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exposedSchemeDatas.isEmpty() ? null : new DrmInitData(manifestDrmData.schemeType,
|
||||||
|
exposedSchemeDatas.toArray(new SchemeData[exposedSchemeDatas.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAcquireSession(@NonNull DrmInitData drmInitData) {
|
public boolean canAcquireSession(@NonNull DrmInitData drmInitData) {
|
||||||
SchemeData schemeData = getSchemeData(drmInitData, uuid);
|
SchemeData schemeData = getSchemeData(drmInitData, uuid, true);
|
||||||
if (schemeData == null) {
|
if (schemeData == null) {
|
||||||
// No data for this manager's scheme.
|
// No data for this manager's scheme.
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -371,7 +371,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||||
byte[] initData = null;
|
byte[] initData = null;
|
||||||
String mimeType = null;
|
String mimeType = null;
|
||||||
if (offlineLicenseKeySetId == null) {
|
if (offlineLicenseKeySetId == null) {
|
||||||
SchemeData data = getSchemeData(drmInitData, uuid);
|
SchemeData data = getSchemeData(drmInitData, uuid, false);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
final IllegalStateException error = new IllegalStateException(
|
final IllegalStateException error = new IllegalStateException(
|
||||||
"Media does not support uuid: " + uuid);
|
"Media does not support uuid: " + uuid);
|
||||||
|
|
@ -467,15 +467,19 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||||
*
|
*
|
||||||
* @param drmInitData The {@link DrmInitData} from which to extract the {@link SchemeData}.
|
* @param drmInitData The {@link DrmInitData} from which to extract the {@link SchemeData}.
|
||||||
* @param uuid The UUID.
|
* @param uuid The UUID.
|
||||||
|
* @param allowMissingData Whether a {@link SchemeData} with null {@link SchemeData#data} may be
|
||||||
|
* returned.
|
||||||
* @return The extracted {@link SchemeData}, or null if no suitable data is present.
|
* @return The extracted {@link SchemeData}, or null if no suitable data is present.
|
||||||
*/
|
*/
|
||||||
private static SchemeData getSchemeData(DrmInitData drmInitData, UUID uuid) {
|
private static SchemeData getSchemeData(DrmInitData drmInitData, UUID uuid,
|
||||||
|
boolean allowMissingData) {
|
||||||
// Look for matching scheme data (matching the Common PSSH box for ClearKey).
|
// Look for matching scheme data (matching the Common PSSH box for ClearKey).
|
||||||
List<SchemeData> matchingSchemeDatas = new ArrayList<>(drmInitData.schemeDataCount);
|
List<SchemeData> matchingSchemeDatas = new ArrayList<>(drmInitData.schemeDataCount);
|
||||||
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
|
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
|
||||||
SchemeData schemeData = drmInitData.get(i);
|
SchemeData schemeData = drmInitData.get(i);
|
||||||
if (schemeData.matches(uuid)
|
boolean uuidMatches = schemeData.matches(uuid)
|
||||||
|| (C.CLEARKEY_UUID.equals(uuid) && schemeData.matches(C.COMMON_PSSH_UUID))) {
|
|| (C.CLEARKEY_UUID.equals(uuid) && schemeData.matches(C.COMMON_PSSH_UUID));
|
||||||
|
if (uuidMatches && (schemeData.data != null || allowMissingData)) {
|
||||||
matchingSchemeDatas.add(schemeData);
|
matchingSchemeDatas.add(schemeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -488,7 +492,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||||
if (C.WIDEVINE_UUID.equals(uuid)) {
|
if (C.WIDEVINE_UUID.equals(uuid)) {
|
||||||
for (int i = 0; i < matchingSchemeDatas.size(); i++) {
|
for (int i = 0; i < matchingSchemeDatas.size(); i++) {
|
||||||
SchemeData matchingSchemeData = matchingSchemeDatas.get(i);
|
SchemeData matchingSchemeData = matchingSchemeDatas.get(i);
|
||||||
int version = PsshAtomUtil.parseVersion(matchingSchemeData.data);
|
int version = matchingSchemeData.hasData()
|
||||||
|
? PsshAtomUtil.parseVersion(matchingSchemeData.data) : -1;
|
||||||
if (Util.SDK_INT < 23 && version == 0) {
|
if (Util.SDK_INT < 23 && version == 0) {
|
||||||
return matchingSchemeData;
|
return matchingSchemeData;
|
||||||
} else if (Util.SDK_INT >= 23 && version == 1) {
|
} else if (Util.SDK_INT >= 23 && version == 1) {
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,14 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||||
this(null, false, schemeDatas.toArray(new SchemeData[schemeDatas.size()]));
|
this(null, false, schemeDatas.toArray(new SchemeData[schemeDatas.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param schemeType See {@link #schemeType}.
|
||||||
|
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
|
||||||
|
*/
|
||||||
|
public DrmInitData(String schemeType, List<SchemeData> schemeDatas) {
|
||||||
|
this(schemeType, false, schemeDatas.toArray(new SchemeData[schemeDatas.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
|
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
|
||||||
*/
|
*/
|
||||||
|
|
@ -62,7 +70,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param schemeType The protection scheme type, or null if not applicable or unknown.
|
* @param schemeType See {@link #schemeType}.
|
||||||
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
|
* @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
|
||||||
*/
|
*/
|
||||||
public DrmInitData(@Nullable String schemeType, SchemeData... schemeDatas) {
|
public DrmInitData(@Nullable String schemeType, SchemeData... schemeDatas) {
|
||||||
|
|
@ -203,7 +211,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||||
*/
|
*/
|
||||||
public final String mimeType;
|
public final String mimeType;
|
||||||
/**
|
/**
|
||||||
* The initialization data.
|
* The initialization data. May be null for scheme support checks only.
|
||||||
*/
|
*/
|
||||||
public final byte[] data;
|
public final byte[] data;
|
||||||
/**
|
/**
|
||||||
|
|
@ -214,8 +222,8 @@ 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
|
* @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).
|
* universal (i.e. applies to all schemes).
|
||||||
* @param mimeType The mimeType of the initialization data.
|
* @param mimeType See {@link #mimeType}.
|
||||||
* @param data The initialization data.
|
* @param data See {@link #data}.
|
||||||
*/
|
*/
|
||||||
public SchemeData(UUID uuid, String mimeType, byte[] data) {
|
public SchemeData(UUID uuid, String mimeType, byte[] data) {
|
||||||
this(uuid, mimeType, data, false);
|
this(uuid, mimeType, data, false);
|
||||||
|
|
@ -224,14 +232,14 @@ 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
|
* @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).
|
* universal (i.e. applies to all schemes).
|
||||||
* @param mimeType The mimeType of the initialization data.
|
* @param mimeType See {@link #mimeType}.
|
||||||
* @param data The initialization data.
|
* @param data See {@link #data}.
|
||||||
* @param requiresSecureDecryption Whether secure decryption is required.
|
* @param requiresSecureDecryption See {@link #requiresSecureDecryption}.
|
||||||
*/
|
*/
|
||||||
public SchemeData(UUID uuid, String mimeType, byte[] data, boolean requiresSecureDecryption) {
|
public SchemeData(UUID uuid, String mimeType, byte[] data, boolean requiresSecureDecryption) {
|
||||||
this.uuid = Assertions.checkNotNull(uuid);
|
this.uuid = Assertions.checkNotNull(uuid);
|
||||||
this.mimeType = Assertions.checkNotNull(mimeType);
|
this.mimeType = Assertions.checkNotNull(mimeType);
|
||||||
this.data = Assertions.checkNotNull(data);
|
this.data = data;
|
||||||
this.requiresSecureDecryption = requiresSecureDecryption;
|
this.requiresSecureDecryption = requiresSecureDecryption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,6 +260,23 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
|
||||||
return C.UUID_NIL.equals(uuid) || schemeUuid.equals(uuid);
|
return C.UUID_NIL.equals(uuid) || schemeUuid.equals(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this {@link SchemeData} can be used to replace {@code other}.
|
||||||
|
*
|
||||||
|
* @param other A {@link SchemeData}.
|
||||||
|
* @return Whether this {@link SchemeData} can be used to replace {@code other}.
|
||||||
|
*/
|
||||||
|
public boolean canReplace(SchemeData other) {
|
||||||
|
return hasData() && !other.hasData() && matches(other.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether {@link #data} is non-null.
|
||||||
|
*/
|
||||||
|
public boolean hasData() {
|
||||||
|
return data != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof SchemeData)) {
|
if (!(obj instanceof SchemeData)) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.drm;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages a DRM session.
|
* Manages a DRM session.
|
||||||
|
|
@ -39,7 +40,8 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
|
||||||
* must be returned to {@link #releaseSession(DrmSession)} when it is no longer required.
|
* must be returned to {@link #releaseSession(DrmSession)} when it is no longer required.
|
||||||
*
|
*
|
||||||
* @param playbackLooper The looper associated with the media playback thread.
|
* @param playbackLooper The looper associated with the media playback thread.
|
||||||
* @param drmInitData DRM initialization data.
|
* @param drmInitData DRM initialization data. All contained {@link SchemeData}s must contain
|
||||||
|
* non-null {@link SchemeData#data}.
|
||||||
* @return The DRM session.
|
* @return The DRM session.
|
||||||
*/
|
*/
|
||||||
DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData);
|
DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData);
|
||||||
|
|
|
||||||
|
|
@ -346,45 +346,54 @@ public class DashManifestParser extends DefaultHandler
|
||||||
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
|
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
|
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
|
||||||
boolean isPlayReady = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95".equals(schemeIdUri);
|
|
||||||
String schemeType = null;
|
String schemeType = null;
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
UUID uuid = null;
|
UUID uuid = null;
|
||||||
boolean requiresSecureDecoder = false;
|
boolean requiresSecureDecoder = false;
|
||||||
|
|
||||||
if ("urn:mpeg:dash:mp4protection:2011".equals(schemeIdUri)) {
|
switch (schemeIdUri) {
|
||||||
schemeType = xpp.getAttributeValue(null, "value");
|
case "urn:mpeg:dash:mp4protection:2011":
|
||||||
String defaultKid = xpp.getAttributeValue(null, "cenc:default_KID");
|
schemeType = xpp.getAttributeValue(null, "value");
|
||||||
if (defaultKid != null && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
|
String defaultKid = xpp.getAttributeValue(null, "cenc:default_KID");
|
||||||
UUID keyId = UUID.fromString(defaultKid);
|
if (defaultKid != null && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
|
||||||
data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, new UUID[] {keyId}, null);
|
UUID keyId = UUID.fromString(defaultKid);
|
||||||
uuid = C.COMMON_PSSH_UUID;
|
data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, new UUID[] {keyId}, null);
|
||||||
}
|
uuid = C.COMMON_PSSH_UUID;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
|
||||||
|
uuid = C.PLAYREADY_UUID;
|
||||||
|
break;
|
||||||
|
case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
|
||||||
|
uuid = C.WIDEVINE_UUID;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
xpp.next();
|
xpp.next();
|
||||||
if (data == null && XmlPullParserUtil.isStartTag(xpp, "cenc:pssh")
|
if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
|
||||||
&& xpp.next() == XmlPullParser.TEXT) {
|
|
||||||
// The cenc:pssh element is defined in 23001-7:2015.
|
|
||||||
data = Base64.decode(xpp.getText(), Base64.DEFAULT);
|
|
||||||
uuid = PsshAtomUtil.parseUuid(data);
|
|
||||||
if (uuid == null) {
|
|
||||||
Log.w(TAG, "Skipping malformed cenc:pssh data");
|
|
||||||
data = null;
|
|
||||||
}
|
|
||||||
} else if (data == null && isPlayReady && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
|
|
||||||
&& xpp.next() == XmlPullParser.TEXT) {
|
|
||||||
// The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
|
|
||||||
data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID,
|
|
||||||
Base64.decode(xpp.getText(), Base64.DEFAULT));
|
|
||||||
uuid = C.PLAYREADY_UUID;
|
|
||||||
} else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
|
|
||||||
String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
|
String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
|
||||||
requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
|
requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
|
||||||
|
} else if (data == null) {
|
||||||
|
if (XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) {
|
||||||
|
// The cenc:pssh element is defined in 23001-7:2015.
|
||||||
|
data = Base64.decode(xpp.getText(), Base64.DEFAULT);
|
||||||
|
uuid = PsshAtomUtil.parseUuid(data);
|
||||||
|
if (uuid == null) {
|
||||||
|
Log.w(TAG, "Skipping malformed cenc:pssh data");
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
} else if (uuid == C.PLAYREADY_UUID && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
|
||||||
|
&& xpp.next() == XmlPullParser.TEXT) {
|
||||||
|
// The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
|
||||||
|
data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID,
|
||||||
|
Base64.decode(xpp.getText(), Base64.DEFAULT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
|
} while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
|
||||||
SchemeData schemeData = data != null
|
SchemeData schemeData = uuid != null
|
||||||
? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null;
|
? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null;
|
||||||
return Pair.create(schemeType, schemeData);
|
return Pair.create(schemeType, schemeData);
|
||||||
}
|
}
|
||||||
|
|
@ -518,10 +527,8 @@ public class DashManifestParser extends DefaultHandler
|
||||||
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
|
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
|
||||||
drmSchemeDatas.addAll(extraDrmSchemeDatas);
|
drmSchemeDatas.addAll(extraDrmSchemeDatas);
|
||||||
if (!drmSchemeDatas.isEmpty()) {
|
if (!drmSchemeDatas.isEmpty()) {
|
||||||
DrmInitData drmInitData = new DrmInitData(drmSchemeDatas);
|
filterRedundantIncompleteSchemeDatas(drmSchemeDatas);
|
||||||
if (drmSchemeType != null) {
|
DrmInitData drmInitData = new DrmInitData(drmSchemeType, drmSchemeDatas);
|
||||||
drmInitData = drmInitData.copyWithSchemeType(drmSchemeType);
|
|
||||||
}
|
|
||||||
format = format.copyWithDrmInitData(drmInitData);
|
format = format.copyWithDrmInitData(drmInitData);
|
||||||
}
|
}
|
||||||
ArrayList<Descriptor> inbandEventStreams = representationInfo.inbandEventStreams;
|
ArrayList<Descriptor> inbandEventStreams = representationInfo.inbandEventStreams;
|
||||||
|
|
@ -728,6 +735,25 @@ public class DashManifestParser extends DefaultHandler
|
||||||
|
|
||||||
// Utility methods.
|
// Utility methods.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes unnecessary {@link SchemeData}s with null {@link SchemeData#data}.
|
||||||
|
*/
|
||||||
|
private static void filterRedundantIncompleteSchemeDatas(ArrayList<SchemeData> schemeDatas) {
|
||||||
|
for (int i = schemeDatas.size() - 1; i >= 0; i--) {
|
||||||
|
SchemeData schemeData = schemeDatas.get(i);
|
||||||
|
if (!schemeData.hasData()) {
|
||||||
|
for (int j = 0; j < schemeDatas.size(); j++) {
|
||||||
|
if (schemeDatas.get(j).canReplace(schemeData)) {
|
||||||
|
// schemeData is incomplete, but there is another matching SchemeData which does contain
|
||||||
|
// data, so we remove the incomplete one.
|
||||||
|
schemeDatas.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derives a sample mimeType from a container mimeType and codecs attribute.
|
* Derives a sample mimeType from a container mimeType and codecs attribute.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue