Commit 317a9944 by aquilescanta Committed by Oliver Woodman

Add type to DrmInitData.SchemeData

At the moment, only CENC-defined scheme types are known values.
This will allow having more information about the encryption
scheme through the format, which in turn will allow more informed
decisions on format support.

Issue:#1661
Issue:#1989
Issue:#2089

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=159538907
parent 2c09f8e0
......@@ -53,9 +53,9 @@ public final class FormatTest extends TestCase {
}
public void testParcelable() {
DrmInitData.SchemeData DRM_DATA_1 = new DrmInitData.SchemeData(WIDEVINE_UUID, VIDEO_MP4,
DrmInitData.SchemeData DRM_DATA_1 = new DrmInitData.SchemeData(WIDEVINE_UUID, "cenc", VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData.SchemeData DRM_DATA_2 = new DrmInitData.SchemeData(C.UUID_NIL, VIDEO_WEBM,
DrmInitData.SchemeData DRM_DATA_2 = new DrmInitData.SchemeData(C.UUID_NIL, null, VIDEO_WEBM,
TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData drmInitData = new DrmInitData(DRM_DATA_1, DRM_DATA_2);
byte[] projectionData = new byte[] {1, 2, 3};
......
......@@ -31,16 +31,16 @@ import junit.framework.TestCase;
*/
public class DrmInitDataTest extends TestCase {
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, VIDEO_MP4, TestUtil.buildTestData(128, 2 /* data seed */));
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, VIDEO_MP4, TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_UNIVERSAL =
new SchemeData(C.UUID_NIL, VIDEO_MP4, TestUtil.buildTestData(128, 3 /* data seed */));
private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, "cbc1", VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
private static final SchemeData DATA_2 = new SchemeData(PLAYREADY_UUID, null, VIDEO_MP4,
TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_1B = new SchemeData(WIDEVINE_UUID, "cens", VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
private static final SchemeData DATA_2B = new SchemeData(PLAYREADY_UUID, null, VIDEO_MP4,
TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, null, VIDEO_MP4,
TestUtil.buildTestData(128, 3 /* data seed */));
public void testParcelable() {
DrmInitData drmInitDataToParcel = new DrmInitData(DATA_1, DATA_2);
......
......@@ -154,7 +154,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
}
private static DrmInitData newDrmInitData() {
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "mimeType",
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "cenc", "mimeType",
new byte[] {1, 4, 7, 0, 3, 6}));
}
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.drm;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.util.Assertions;
......@@ -102,6 +103,33 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
return schemeDatas[index];
}
/**
* Returns a copy of the {@link DrmInitData} instance whose {@link SchemeData}s have been updated
* to have the specified 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.
*/
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 {
return this;
}
}
@Override
public int hashCode() {
if (hashCode == 0) {
......@@ -168,6 +196,10 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
*/
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}.
*/
public final String mimeType;
......@@ -183,22 +215,26 @@ 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, String mimeType, byte[] data) {
this(uuid, mimeType, data, false);
public SchemeData(UUID uuid, @Nullable String type, String mimeType, byte[] data) {
this(uuid, type, 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, String mimeType, byte[] data, boolean requiresSecureDecryption) {
public SchemeData(UUID uuid, @Nullable String type, 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;
......@@ -206,6 +242,7 @@ 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;
......@@ -221,6 +258,19 @@ 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)) {
......@@ -231,13 +281,14 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
}
SchemeData other = (SchemeData) obj;
return mimeType.equals(other.mimeType) && Util.areEqual(uuid, other.uuid)
&& Arrays.equals(data, other.data);
&& Util.areEqual(type, other.type) && 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;
......@@ -256,6 +307,7 @@ 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));
......
......@@ -586,7 +586,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,
currentTrack.drmInitData = new DrmInitData(new SchemeData(C.UUID_NIL, null,
MimeTypes.VIDEO_WEBM, currentTrack.cryptoData.encryptionKey));
}
break;
......
......@@ -615,10 +615,10 @@ import java.util.List;
|| childAtomType == Atom.TYPE_wvtt || childAtomType == Atom.TYPE_stpp
|| childAtomType == Atom.TYPE_c608) {
parseTextSampleEntry(stsd, childAtomType, childStartPosition, childAtomSize, trackId,
language, drmInitData, out);
language, out);
} else if (childAtomType == Atom.TYPE_camm) {
out.format = Format.createSampleFormat(Integer.toString(trackId),
MimeTypes.APPLICATION_CAMERA_MOTION, null, Format.NO_VALUE, drmInitData);
MimeTypes.APPLICATION_CAMERA_MOTION, null, Format.NO_VALUE, null);
}
stsd.setPosition(childStartPosition + childAtomSize);
}
......@@ -626,8 +626,7 @@ import java.util.List;
}
private static void parseTextSampleEntry(ParsableByteArray parent, int atomType, int position,
int atomSize, int trackId, String language, DrmInitData drmInitData, StsdData out)
throws ParserException {
int atomSize, int trackId, String language, StsdData out) throws ParserException {
parent.setPosition(position + Atom.HEADER_SIZE + StsdData.STSD_HEADER_SIZE);
// Default values.
......@@ -658,8 +657,7 @@ import java.util.List;
}
out.format = Format.createTextSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, 0, language, Format.NO_VALUE, drmInitData, subsampleOffsetUs,
initializationData);
Format.NO_VALUE, 0, language, Format.NO_VALUE, null, subsampleOffsetUs, initializationData);
}
private static void parseVideoSampleEntry(ParsableByteArray parent, int atomType, int position,
......@@ -677,7 +675,14 @@ import java.util.List;
int childPosition = parent.getPosition();
if (atomType == Atom.TYPE_encv) {
atomType = parseSampleEntryEncryptionData(parent, position, size, out, entryIndex);
TrackEncryptionBox encryptionBox = out.trackEncryptionBoxes[entryIndex];
String schemeType = encryptionBox != null ? encryptionBox.schemeType : null;
if (schemeType != null) {
drmInitData = drmInitData.copyWithSchemeType(schemeType);
}
parent.setPosition(childPosition);
} else {
drmInitData = null;
}
List<byte[]> initializationData = null;
......@@ -846,7 +851,14 @@ import java.util.List;
int childPosition = parent.getPosition();
if (atomType == Atom.TYPE_enca) {
atomType = parseSampleEntryEncryptionData(parent, position, size, out, entryIndex);
TrackEncryptionBox encryptionBox = out.trackEncryptionBoxes[entryIndex];
String schemeType = encryptionBox != null ? encryptionBox.schemeType : null;
if (schemeType != null) {
drmInitData = drmInitData.copyWithSchemeType(schemeType);
}
parent.setPosition(childPosition);
} else {
drmInitData = null;
}
// If the atom type determines a MIME type, set it immediately.
......@@ -1051,9 +1063,9 @@ import java.util.List;
private static Pair<Integer, TrackEncryptionBox> parseSinfFromParent(ParsableByteArray parent,
int position, int size) {
int childPosition = position + Atom.HEADER_SIZE;
boolean isCencScheme = false;
TrackEncryptionBox trackEncryptionBox = null;
int schemeInformationBoxPosition = C.POSITION_UNSET;
int schemeInformationBoxSize = 0;
String schemeType = null;
Integer dataFormat = null;
while (childPosition - position < size) {
parent.setPosition(childPosition);
......@@ -1063,24 +1075,30 @@ import java.util.List;
dataFormat = parent.readInt();
} else if (childAtomType == Atom.TYPE_schm) {
parent.skipBytes(4);
isCencScheme = parent.readInt() == TYPE_cenc;
// scheme_type field. Defined in ISO/IEC 23001-7:2016, section 4.1.
schemeType = parent.readString(4);
} else if (childAtomType == Atom.TYPE_schi) {
trackEncryptionBox = parseSchiFromParent(parent, childPosition, childAtomSize);
schemeInformationBoxPosition = childPosition;
schemeInformationBoxSize = childAtomSize;
}
childPosition += childAtomSize;
}
if (isCencScheme) {
if (schemeType != null) {
Assertions.checkArgument(dataFormat != null, "frma atom is mandatory");
Assertions.checkArgument(trackEncryptionBox != null, "schi->tenc atom is mandatory");
return Pair.create(dataFormat, trackEncryptionBox);
Assertions.checkArgument(schemeInformationBoxPosition != C.POSITION_UNSET,
"schi atom is mandatory");
TrackEncryptionBox encryptionBox = parseSchiFromParent(parent, schemeInformationBoxPosition,
schemeInformationBoxSize, schemeType);
Assertions.checkArgument(encryptionBox != null, "tenc atom is mandatory");
return Pair.create(dataFormat, encryptionBox);
} else {
return null;
}
}
private static TrackEncryptionBox parseSchiFromParent(ParsableByteArray parent, int position,
int size) {
int size, String schemeType) {
int childPosition = position + Atom.HEADER_SIZE;
while (childPosition - position < size) {
parent.setPosition(childPosition);
......@@ -1092,7 +1110,8 @@ import java.util.List;
int defaultInitVectorSize = parent.readUnsignedByte();
byte[] defaultKeyId = new byte[16];
parent.readBytes(defaultKeyId, 0, defaultKeyId.length);
return new TrackEncryptionBox(defaultIsEncrypted, defaultInitVectorSize, defaultKeyId);
return new TrackEncryptionBox(defaultIsEncrypted, schemeType, defaultInitVectorSize,
defaultKeyId);
}
childPosition += childAtomSize;
}
......
......@@ -559,11 +559,12 @@ public final class FragmentedMp4Extractor implements Extractor {
parseTruns(traf, trackBundle, decodeTime, flags);
TrackEncryptionBox encryptionBox = trackBundle.track
.getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex);
LeafAtom saiz = traf.getLeafAtomOfType(Atom.TYPE_saiz);
if (saiz != null) {
TrackEncryptionBox trackEncryptionBox = trackBundle.track
.sampleDescriptionEncryptionBoxes[fragment.header.sampleDescriptionIndex];
parseSaiz(trackEncryptionBox, saiz.data, fragment);
parseSaiz(encryptionBox, saiz.data, fragment);
}
LeafAtom saio = traf.getLeafAtomOfType(Atom.TYPE_saio);
......@@ -579,7 +580,8 @@ public final class FragmentedMp4Extractor implements Extractor {
LeafAtom sbgp = traf.getLeafAtomOfType(Atom.TYPE_sbgp);
LeafAtom sgpd = traf.getLeafAtomOfType(Atom.TYPE_sgpd);
if (sbgp != null && sgpd != null) {
parseSgpd(sbgp.data, sgpd.data, fragment);
parseSgpd(sbgp.data, sgpd.data, encryptionBox != null ? encryptionBox.schemeType : null,
fragment);
}
int leafChildrenSize = traf.leafChildren.size();
......@@ -868,8 +870,8 @@ public final class FragmentedMp4Extractor implements Extractor {
out.fillEncryptionData(senc);
}
private static void parseSgpd(ParsableByteArray sbgp, ParsableByteArray sgpd, TrackFragment out)
throws ParserException {
private static void parseSgpd(ParsableByteArray sbgp, ParsableByteArray sgpd, String schemeType,
TrackFragment out) throws ParserException {
sbgp.setPosition(Atom.HEADER_SIZE);
int sbgpFullAtom = sbgp.readInt();
if (sbgp.readInt() != SAMPLE_GROUP_TYPE_seig) {
......@@ -910,7 +912,7 @@ public final class FragmentedMp4Extractor implements Extractor {
byte[] keyId = new byte[16];
sgpd.readBytes(keyId, 0, keyId.length);
out.definesEncryptionData = true;
out.trackEncryptionBox = new TrackEncryptionBox(isProtected, initVectorSize, keyId);
out.trackEncryptionBox = new TrackEncryptionBox(isProtected, schemeType, initVectorSize, keyId);
}
/**
......@@ -1135,7 +1137,7 @@ public final class FragmentedMp4Extractor implements Extractor {
if (fragment.definesEncryptionData) {
encryptionBox = fragment.trackEncryptionBox != null
? fragment.trackEncryptionBox
: track.sampleDescriptionEncryptionBoxes[fragment.header.sampleDescriptionIndex];
: track.getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex);
if (encryptionBox != currentTrackBundle.cachedEncryptionBox) {
cryptoData = new TrackOutput.CryptoData(C.CRYPTO_MODE_AES_CTR, encryptionBox.keyId);
} else {
......@@ -1205,7 +1207,7 @@ public final class FragmentedMp4Extractor implements Extractor {
int sampleDescriptionIndex = trackFragment.header.sampleDescriptionIndex;
TrackEncryptionBox encryptionBox = trackFragment.trackEncryptionBox != null
? trackFragment.trackEncryptionBox
: trackBundle.track.sampleDescriptionEncryptionBoxes[sampleDescriptionIndex];
: trackBundle.track.getSampleDescriptionEncryptionBox(sampleDescriptionIndex);
int vectorSize = encryptionBox.initializationVectorSize;
boolean subsampleEncryption = trackFragment
.sampleHasSubsampleEncryptionTable[trackBundle.currentSampleIndex];
......@@ -1245,7 +1247,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, MimeTypes.VIDEO_MP4, psshData));
schemeDatas.add(new SchemeData(uuid, null, MimeTypes.VIDEO_MP4, psshData));
}
}
}
......@@ -1325,8 +1327,12 @@ public final class FragmentedMp4Extractor implements Extractor {
}
public void updateDrmInitData(DrmInitData drmInitData) {
output.format(track.format.copyWithDrmInitData(drmInitData));
TrackEncryptionBox encryptionBox =
track.getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex);
String schemeType = encryptionBox != null ? encryptionBox.schemeType : null;
output.format(track.format.copyWithDrmInitData(drmInitData.copyWithSchemeType(schemeType)));
}
}
}
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.extractor.mp4;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import java.lang.annotation.Retention;
......@@ -78,11 +79,6 @@ public final class Track {
@Transformation public final int sampleTransformation;
/**
* Track encryption boxes for the different track sample descriptions. Entries may be null.
*/
public final TrackEncryptionBox[] sampleDescriptionEncryptionBoxes;
/**
* Durations of edit list segments in the movie timescale. Null if there is no edit list.
*/
public final long[] editListDurations;
......@@ -98,9 +94,11 @@ public final class Track {
*/
public final int nalUnitLengthFieldLength;
@Nullable private final TrackEncryptionBox[] sampleDescriptionEncryptionBoxes;
public Track(int id, int type, long timescale, long movieTimescale, long durationUs,
Format format, @Transformation int sampleTransformation,
TrackEncryptionBox[] sampleDescriptionEncryptionBoxes, int nalUnitLengthFieldLength,
@Nullable TrackEncryptionBox[] sampleDescriptionEncryptionBoxes, int nalUnitLengthFieldLength,
long[] editListDurations, long[] editListMediaTimes) {
this.id = id;
this.type = type;
......@@ -115,4 +113,16 @@ public final class Track {
this.editListMediaTimes = editListMediaTimes;
}
/**
* Returns the {@link TrackEncryptionBox} for the given sample description index.
*
* @param sampleDescriptionIndex The given sample description index
* @return The {@link TrackEncryptionBox} for the given sample description index. Maybe null if no
* such entry exists.
*/
public TrackEncryptionBox getSampleDescriptionEncryptionBox(int sampleDescriptionIndex) {
return sampleDescriptionEncryptionBoxes == null ? null
: sampleDescriptionEncryptionBoxes[sampleDescriptionIndex];
}
}
......@@ -15,6 +15,8 @@
*/
package com.google.android.exoplayer2.extractor.mp4;
import android.support.annotation.Nullable;
/**
* Encapsulates information parsed from a track encryption (tenc) box or sample group description
* (sgpd) box in an MP4 stream.
......@@ -27,6 +29,11 @@ public final class TrackEncryptionBox {
public final boolean isEncrypted;
/**
* The protection scheme type, as defined by the 'schm' box, or null if unknown.
*/
@Nullable public final String schemeType;
/**
* The initialization vector size in bytes for the samples in the corresponding sample group.
*/
public final int initializationVectorSize;
......@@ -37,13 +44,15 @@ public final class TrackEncryptionBox {
public final byte[] keyId;
/**
* @param isEncrypted Indicates the encryption state of the samples in the sample group.
* @param initializationVectorSize The initialization vector size in bytes for the samples in the
* corresponding sample group.
* @param keyId The key identifier for the samples in the corresponding sample group.
* @param isEncrypted See {@link #isEncrypted}.
* @param schemeType See {@link #schemeType}.
* @param initializationVectorSize See {@link #initializationVectorSize}.
* @param keyId See {@link #keyId}.
*/
public TrackEncryptionBox(boolean isEncrypted, int initializationVectorSize, byte[] keyId) {
public TrackEncryptionBox(boolean isEncrypted, @Nullable String schemeType,
int initializationVectorSize, byte[] keyId) {
this.isEncrypted = isEncrypted;
this.schemeType = schemeType;
this.initializationVectorSize = initializationVectorSize;
this.keyId = keyId;
}
......
......@@ -75,7 +75,7 @@ public final class DashUtilTest extends TestCase {
}
private static DrmInitData newDrmInitData() {
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "mimeType",
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, null, "mimeType",
new byte[]{1, 4, 7, 0, 3, 6}));
}
......
......@@ -343,6 +343,7 @@ public class DashManifestParser extends DefaultHandler
IOException {
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
boolean isPlayReady = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95".equals(schemeIdUri);
String schemeType = xpp.getAttributeValue(null, "value");
byte[] data = null;
UUID uuid = null;
boolean requiresSecureDecoder = false;
......@@ -368,8 +369,8 @@ public class DashManifestParser extends DefaultHandler
requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
}
} while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
return data != null ? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
: null;
return data != null
? new SchemeData(uuid, schemeType, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null;
}
/**
......
......@@ -69,7 +69,7 @@ import java.util.ArrayList;
if (protectionElement != null) {
byte[] keyId = getProtectionElementKeyId(protectionElement.data);
trackEncryptionBoxes = new TrackEncryptionBox[] {
new TrackEncryptionBox(true, INITIALIZATION_VECTOR_SIZE, keyId)};
new TrackEncryptionBox(true, null, INITIALIZATION_VECTOR_SIZE, keyId)};
} else {
trackEncryptionBoxes = null;
}
......
......@@ -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,
DrmInitData drmInitData = new DrmInitData(new SchemeData(protectionElement.uuid, null,
MimeTypes.VIDEO_MP4, protectionElement.data));
for (StreamElement streamElement : streamElementArray) {
for (int i = 0; i < streamElement.formats.length; i++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment