Commit 50c9ae0e by aquilescanta Committed by Oliver Woodman

Assume that encrypted content requires secure decoders in renderer support checks

Issue:#5568
PiperOrigin-RevId: 247973411
parent 15688e3e
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
([#5868](https://github.com/google/ExoPlayer/issues/5868)). ([#5868](https://github.com/google/ExoPlayer/issues/5868)).
* Fix handling of line terminators in SHOUTcast ICY metadata * Fix handling of line terminators in SHOUTcast ICY metadata
([#5876](https://github.com/google/ExoPlayer/issues/5876)). ([#5876](https://github.com/google/ExoPlayer/issues/5876)).
* Assume that encrypted content requires secure decoders in renderer support
checks ([#5568](https://github.com/google/ExoPlayer/issues/5568)).
* Offline: Add option to remove all downloads. * Offline: Add option to remove all downloads.
* Decoders: * Decoders:
* Prefer codecs that advertise format support over ones that do not, even if * Prefer codecs that advertise format support over ones that do not, even if
......
...@@ -33,7 +33,6 @@ import com.google.android.exoplayer2.PlaybackParameters; ...@@ -33,7 +33,6 @@ import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo; import com.google.android.exoplayer2.mediacodec.MediaCodecInfo;
...@@ -283,25 +282,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -283,25 +282,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
// Assume the decoder outputs 16-bit PCM, unless the input is raw. // Assume the decoder outputs 16-bit PCM, unless the input is raw.
return FORMAT_UNSUPPORTED_SUBTYPE; return FORMAT_UNSUPPORTED_SUBTYPE;
} }
boolean requiresSecureDecryption = false;
DrmInitData drmInitData = format.drmInitData;
if (drmInitData != null) {
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
requiresSecureDecryption |= drmInitData.get(i).requiresSecureDecryption;
}
}
List<MediaCodecInfo> decoderInfos = List<MediaCodecInfo> decoderInfos =
getDecoderInfos(mediaCodecSelector, format, requiresSecureDecryption); getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */ false);
if (decoderInfos.isEmpty()) { if (decoderInfos.isEmpty()) {
return requiresSecureDecryption return FORMAT_UNSUPPORTED_SUBTYPE;
&& !mediaCodecSelector
.getDecoderInfos(
format.sampleMimeType,
/* requiresSecureDecoder= */ false,
/* requiresTunnelingDecoder= */ false)
.isEmpty()
? FORMAT_UNSUPPORTED_DRM
: FORMAT_UNSUPPORTED_SUBTYPE;
} }
if (!supportsFormatDrm) { if (!supportsFormatDrm) {
return FORMAT_UNSUPPORTED_DRM; return FORMAT_UNSUPPORTED_DRM;
......
...@@ -291,10 +291,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable { ...@@ -291,10 +291,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
public final String mimeType; public final String mimeType;
/** The initialization data. May be null for scheme support checks only. */ /** The initialization data. May be null for scheme support checks only. */
public final @Nullable byte[] data; public final @Nullable byte[] data;
/**
* Whether secure decryption is required.
*/
public final boolean requiresSecureDecryption;
/** /**
* @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
...@@ -303,19 +299,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable { ...@@ -303,19 +299,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* @param data See {@link #data}. * @param data See {@link #data}.
*/ */
public SchemeData(UUID uuid, String mimeType, @Nullable byte[] data) { public SchemeData(UUID uuid, String mimeType, @Nullable byte[] data) {
this(uuid, mimeType, data, false); this(uuid, /* licenseServerUrl= */ null, mimeType, data);
}
/**
* @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 mimeType See {@link #mimeType}.
* @param data See {@link #data}.
* @param requiresSecureDecryption See {@link #requiresSecureDecryption}.
*/
public SchemeData(
UUID uuid, String mimeType, @Nullable byte[] data, boolean requiresSecureDecryption) {
this(uuid, /* licenseServerUrl= */ null, mimeType, data, requiresSecureDecryption);
} }
/** /**
...@@ -324,19 +308,13 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable { ...@@ -324,19 +308,13 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* @param licenseServerUrl See {@link #licenseServerUrl}. * @param licenseServerUrl See {@link #licenseServerUrl}.
* @param mimeType See {@link #mimeType}. * @param mimeType See {@link #mimeType}.
* @param data See {@link #data}. * @param data See {@link #data}.
* @param requiresSecureDecryption See {@link #requiresSecureDecryption}.
*/ */
public SchemeData( public SchemeData(
UUID uuid, UUID uuid, @Nullable String licenseServerUrl, String mimeType, @Nullable byte[] data) {
@Nullable String licenseServerUrl,
String mimeType,
@Nullable byte[] data,
boolean requiresSecureDecryption) {
this.uuid = Assertions.checkNotNull(uuid); this.uuid = Assertions.checkNotNull(uuid);
this.licenseServerUrl = licenseServerUrl; this.licenseServerUrl = licenseServerUrl;
this.mimeType = Assertions.checkNotNull(mimeType); this.mimeType = Assertions.checkNotNull(mimeType);
this.data = data; this.data = data;
this.requiresSecureDecryption = requiresSecureDecryption;
} }
/* package */ SchemeData(Parcel in) { /* package */ SchemeData(Parcel in) {
...@@ -344,7 +322,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable { ...@@ -344,7 +322,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
licenseServerUrl = in.readString(); licenseServerUrl = in.readString();
mimeType = Util.castNonNull(in.readString()); mimeType = Util.castNonNull(in.readString());
data = in.createByteArray(); data = in.createByteArray();
requiresSecureDecryption = in.readByte() != 0;
} }
/** /**
...@@ -381,7 +358,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable { ...@@ -381,7 +358,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* @return The new instance. * @return The new instance.
*/ */
public SchemeData copyWithData(@Nullable byte[] data) { public SchemeData copyWithData(@Nullable byte[] data) {
return new SchemeData(uuid, licenseServerUrl, mimeType, data, requiresSecureDecryption); return new SchemeData(uuid, licenseServerUrl, mimeType, data);
} }
@Override @Override
...@@ -425,7 +402,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable { ...@@ -425,7 +402,6 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
dest.writeString(licenseServerUrl); dest.writeString(licenseServerUrl);
dest.writeString(mimeType); dest.writeString(mimeType);
dest.writeByteArray(data); dest.writeByteArray(data);
dest.writeByte((byte) (requiresSecureDecryption ? 1 : 0));
} }
public static final Parcelable.Creator<SchemeData> CREATOR = public static final Parcelable.Creator<SchemeData> CREATOR =
......
...@@ -242,8 +242,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto ...@@ -242,8 +242,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
for (int i = 0; i < schemeDatas.size(); i++) { for (int i = 0; i < schemeDatas.size(); i++) {
SchemeData schemeData = schemeDatas.get(i); SchemeData schemeData = schemeDatas.get(i);
byte[] schemeDataData = Util.castNonNull(schemeData.data); byte[] schemeDataData = Util.castNonNull(schemeData.data);
if (schemeData.requiresSecureDecryption == firstSchemeData.requiresSecureDecryption if (Util.areEqual(schemeData.mimeType, firstSchemeData.mimeType)
&& Util.areEqual(schemeData.mimeType, firstSchemeData.mimeType)
&& Util.areEqual(schemeData.licenseServerUrl, firstSchemeData.licenseServerUrl) && Util.areEqual(schemeData.licenseServerUrl, firstSchemeData.licenseServerUrl)
&& PsshAtomUtil.isPsshAtom(schemeDataData)) { && PsshAtomUtil.isPsshAtom(schemeDataData)) {
concatenatedDataLength += schemeDataData.length; concatenatedDataLength += schemeDataData.length;
......
...@@ -298,29 +298,26 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -298,29 +298,26 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (!MimeTypes.isVideo(mimeType)) { if (!MimeTypes.isVideo(mimeType)) {
return FORMAT_UNSUPPORTED_TYPE; return FORMAT_UNSUPPORTED_TYPE;
} }
boolean requiresSecureDecryption = false;
DrmInitData drmInitData = format.drmInitData; DrmInitData drmInitData = format.drmInitData;
if (drmInitData != null) { // Assume encrypted content requires secure decoders.
for (int i = 0; i < drmInitData.schemeDataCount; i++) { boolean requiresSecureDecryption = drmInitData != null;
requiresSecureDecryption |= drmInitData.get(i).requiresSecureDecryption;
}
}
List<MediaCodecInfo> decoderInfos = List<MediaCodecInfo> decoderInfos =
getDecoderInfos( getDecoderInfos(
mediaCodecSelector, mediaCodecSelector,
format, format,
requiresSecureDecryption, requiresSecureDecryption,
/* requiresTunnelingDecoder= */ false); /* requiresTunnelingDecoder= */ false);
if (requiresSecureDecryption && decoderInfos.isEmpty()) {
// No secure decoders are available. Fall back to non-secure decoders.
decoderInfos =
getDecoderInfos(
mediaCodecSelector,
format,
/* requiresSecureDecoder= */ false,
/* requiresTunnelingDecoder= */ false);
}
if (decoderInfos.isEmpty()) { if (decoderInfos.isEmpty()) {
return requiresSecureDecryption return FORMAT_UNSUPPORTED_SUBTYPE;
&& !getDecoderInfos(
mediaCodecSelector,
format,
/* requiresSecureDecoder= */ false,
/* requiresTunnelingDecoder= */ false)
.isEmpty()
? FORMAT_UNSUPPORTED_DRM
: FORMAT_UNSUPPORTED_SUBTYPE;
} }
if (!supportsFormatDrm(drmSessionManager, drmInitData)) { if (!supportsFormatDrm(drmSessionManager, drmInitData)) {
return FORMAT_UNSUPPORTED_DRM; return FORMAT_UNSUPPORTED_DRM;
......
...@@ -397,7 +397,6 @@ public class DashManifestParser extends DefaultHandler ...@@ -397,7 +397,6 @@ public class DashManifestParser extends DefaultHandler
String licenseServerUrl = null; String licenseServerUrl = null;
byte[] data = null; byte[] data = null;
UUID uuid = null; UUID uuid = null;
boolean requiresSecureDecoder = false;
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri"); String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
if (schemeIdUri != null) { if (schemeIdUri != null) {
...@@ -431,9 +430,6 @@ public class DashManifestParser extends DefaultHandler ...@@ -431,9 +430,6 @@ public class DashManifestParser extends DefaultHandler
xpp.next(); xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) { if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl"); licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
} else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
} else if (data == null } else if (data == null
&& XmlPullParserUtil.isStartTagIgnorePrefix(xpp, "pssh") && XmlPullParserUtil.isStartTagIgnorePrefix(xpp, "pssh")
&& xpp.next() == XmlPullParser.TEXT) { && xpp.next() == XmlPullParser.TEXT) {
...@@ -457,10 +453,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -457,10 +453,7 @@ public class DashManifestParser extends DefaultHandler
} }
} while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection")); } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
SchemeData schemeData = SchemeData schemeData =
uuid != null uuid != null ? new SchemeData(uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data) : null;
? new SchemeData(
uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
: null;
return Pair.create(schemeType, schemeData); return Pair.create(schemeType, schemeData);
} }
......
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