mirror of
https://github.com/samsonjs/media.git
synced 2026-04-08 11:45:51 +00:00
Add DRM format support checks for MediaSource provided DRM
PiperOrigin-RevId: 256161522
This commit is contained in:
parent
16bf7f9106
commit
7408b4355a
12 changed files with 184 additions and 30 deletions
|
|
@ -77,12 +77,17 @@ public final class LibopusAudioRenderer extends SimpleDecoderAudioRenderer {
|
|||
@Override
|
||||
protected int supportsFormatInternal(DrmSessionManager<ExoMediaCrypto> drmSessionManager,
|
||||
Format format) {
|
||||
boolean drmIsSupported =
|
||||
format.drmInitData == null
|
||||
|| OpusLibrary.matchesExpectedExoMediaCryptoType(format.exoMediaCryptoType)
|
||||
|| (format.exoMediaCryptoType == null
|
||||
&& supportsFormatDrm(drmSessionManager, format.drmInitData));
|
||||
if (!OpusLibrary.isAvailable()
|
||||
|| !MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)) {
|
||||
return FORMAT_UNSUPPORTED_TYPE;
|
||||
} else if (!supportsOutput(format.channelCount, C.ENCODING_PCM_16BIT)) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||
} else if (!drmIsSupported) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
} else {
|
||||
return FORMAT_HANDLED;
|
||||
|
|
@ -110,5 +115,4 @@ public final class LibopusAudioRenderer extends SimpleDecoderAudioRenderer {
|
|||
Format.NO_VALUE, decoder.getChannelCount(), decoder.getSampleRate(), C.ENCODING_PCM_16BIT,
|
||||
null, null, 0, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
package com.google.android.exoplayer2.ext.opus;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||
import com.google.android.exoplayer2.util.LibraryLoader;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/**
|
||||
* Configures and queries the underlying native library.
|
||||
|
|
@ -28,6 +30,7 @@ public final class OpusLibrary {
|
|||
}
|
||||
|
||||
private static final LibraryLoader LOADER = new LibraryLoader("opusV2JNI");
|
||||
private static Class<? extends ExoMediaCrypto> exoMediaCryptoType;
|
||||
|
||||
private OpusLibrary() {}
|
||||
|
||||
|
|
@ -36,10 +39,14 @@ public final class OpusLibrary {
|
|||
* it must do so before calling any other method defined by this class, and before instantiating a
|
||||
* {@link LibopusAudioRenderer} instance.
|
||||
*
|
||||
* @param exoMediaCryptoType The {@link ExoMediaCrypto} type expected for decoding protected
|
||||
* content.
|
||||
* @param libraries The names of the Opus native libraries.
|
||||
*/
|
||||
public static void setLibraries(String... libraries) {
|
||||
public static void setLibraries(
|
||||
Class<? extends ExoMediaCrypto> exoMediaCryptoType, String... libraries) {
|
||||
LOADER.setLibraries(libraries);
|
||||
OpusLibrary.exoMediaCryptoType = exoMediaCryptoType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -56,6 +63,15 @@ public final class OpusLibrary {
|
|||
return isAvailable() ? opusGetVersion() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link ExoMediaCrypto} type matches the one required for decoding
|
||||
* protected content.
|
||||
*/
|
||||
public static boolean matchesExpectedExoMediaCryptoType(
|
||||
Class<? extends ExoMediaCrypto> exoMediaCryptoType) {
|
||||
return Util.areEqual(OpusLibrary.exoMediaCryptoType, exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public static native String opusGetVersion();
|
||||
public static native boolean opusIsSecureDecodeSupported();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,7 +284,13 @@ public class LibvpxVideoRenderer extends BaseRenderer {
|
|||
public int supportsFormat(Format format) {
|
||||
if (!VpxLibrary.isAvailable() || !MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)) {
|
||||
return FORMAT_UNSUPPORTED_TYPE;
|
||||
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||
}
|
||||
boolean drmIsSupported =
|
||||
format.drmInitData == null
|
||||
|| VpxLibrary.matchesExpectedExoMediaCryptoType(format.exoMediaCryptoType)
|
||||
|| (format.exoMediaCryptoType == null
|
||||
&& supportsFormatDrm(drmSessionManager, format.drmInitData));
|
||||
if (!drmIsSupported) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
}
|
||||
return FORMAT_HANDLED | ADAPTIVE_SEAMLESS;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
package com.google.android.exoplayer2.ext.vp9;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||
import com.google.android.exoplayer2.util.LibraryLoader;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/**
|
||||
* Configures and queries the underlying native library.
|
||||
|
|
@ -28,6 +30,7 @@ public final class VpxLibrary {
|
|||
}
|
||||
|
||||
private static final LibraryLoader LOADER = new LibraryLoader("vpx", "vpxV2JNI");
|
||||
private static Class<? extends ExoMediaCrypto> exoMediaCryptoType;
|
||||
|
||||
private VpxLibrary() {}
|
||||
|
||||
|
|
@ -36,10 +39,14 @@ public final class VpxLibrary {
|
|||
* it must do so before calling any other method defined by this class, and before instantiating a
|
||||
* {@link LibvpxVideoRenderer} instance.
|
||||
*
|
||||
* @param exoMediaCryptoType The {@link ExoMediaCrypto} type required for decoding protected
|
||||
* content.
|
||||
* @param libraries The names of the Vpx native libraries.
|
||||
*/
|
||||
public static void setLibraries(String... libraries) {
|
||||
public static void setLibraries(
|
||||
Class<? extends ExoMediaCrypto> exoMediaCryptoType, String... libraries) {
|
||||
LOADER.setLibraries(libraries);
|
||||
VpxLibrary.exoMediaCryptoType = exoMediaCryptoType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,6 +81,15 @@ public final class VpxLibrary {
|
|||
return indexHbd >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link ExoMediaCrypto} type matches the one required for decoding
|
||||
* protected content.
|
||||
*/
|
||||
public static boolean matchesExpectedExoMediaCryptoType(
|
||||
Class<? extends ExoMediaCrypto> exoMediaCryptoType) {
|
||||
return Util.areEqual(VpxLibrary.exoMediaCryptoType, exoMediaCryptoType);
|
||||
}
|
||||
|
||||
private static native String vpxGetVersion();
|
||||
private static native String vpxGetBuildConfig();
|
||||
public static native boolean vpxIsSecureDecodeSupported();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ import android.os.Parcel;
|
|||
import android.os.Parcelable;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
import com.google.android.exoplayer2.drm.DrmSession;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -163,6 +165,15 @@ public final class Format implements Parcelable {
|
|||
*/
|
||||
public final int accessibilityChannel;
|
||||
|
||||
// Provided by source.
|
||||
|
||||
/**
|
||||
* The type of the {@link ExoMediaCrypto} provided by the media source, if the media source can
|
||||
* acquire a {@link DrmSession} for {@link #drmInitData}. Null if the media source cannot acquire
|
||||
* a session for {@link #drmInitData}, or if not applicable.
|
||||
*/
|
||||
@Nullable public final Class<? extends ExoMediaCrypto> exoMediaCryptoType;
|
||||
|
||||
// Lazily initialized hashcode.
|
||||
private int hashCode;
|
||||
|
||||
|
|
@ -236,7 +247,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
/* language= */ null,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
public static Format createVideoSampleFormat(
|
||||
|
|
@ -340,7 +352,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
/* language= */ null,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
// Audio.
|
||||
|
|
@ -413,7 +426,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
language,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
public static Format createAudioSampleFormat(
|
||||
|
|
@ -518,7 +532,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
// Text.
|
||||
|
|
@ -585,7 +600,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
public static Format createTextSampleFormat(
|
||||
|
|
@ -698,7 +714,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
// Image.
|
||||
|
|
@ -740,7 +757,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
language,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
// Generic.
|
||||
|
|
@ -804,7 +822,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
language,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
public static Format createSampleFormat(
|
||||
|
|
@ -837,7 +856,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
/* language= */ null,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
public static Format createSampleFormat(
|
||||
|
|
@ -874,7 +894,8 @@ public final class Format implements Parcelable {
|
|||
/* encoderDelay= */ NO_VALUE,
|
||||
/* encoderPadding= */ NO_VALUE,
|
||||
/* language= */ null,
|
||||
/* accessibilityChannel= */ NO_VALUE);
|
||||
/* accessibilityChannel= */ NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
}
|
||||
|
||||
/* package */ Format(
|
||||
|
|
@ -910,7 +931,9 @@ public final class Format implements Parcelable {
|
|||
int encoderPadding,
|
||||
// Audio and text specific.
|
||||
@Nullable String language,
|
||||
int accessibilityChannel) {
|
||||
int accessibilityChannel,
|
||||
// Provided by source.
|
||||
@Nullable Class<? extends ExoMediaCrypto> exoMediaCryptoType) {
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
this.selectionFlags = selectionFlags;
|
||||
|
|
@ -946,6 +969,8 @@ public final class Format implements Parcelable {
|
|||
// Audio and text specific.
|
||||
this.language = Util.normalizeLanguageCode(language);
|
||||
this.accessibilityChannel = accessibilityChannel;
|
||||
// Provided by source.
|
||||
this.exoMediaCryptoType = exoMediaCryptoType;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResourceType")
|
||||
|
|
@ -988,6 +1013,8 @@ public final class Format implements Parcelable {
|
|||
// Audio and text specific.
|
||||
language = in.readString();
|
||||
accessibilityChannel = in.readInt();
|
||||
// Provided by source.
|
||||
exoMediaCryptoType = null;
|
||||
}
|
||||
|
||||
public Format copyWithMaxInputSize(int maxInputSize) {
|
||||
|
|
@ -1019,7 +1046,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithSubsampleOffsetUs(long subsampleOffsetUs) {
|
||||
|
|
@ -1051,7 +1079,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithContainerInfo(
|
||||
|
|
@ -1099,7 +1128,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
|
|
@ -1178,7 +1208,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithGaplessInfo(int encoderDelay, int encoderPadding) {
|
||||
|
|
@ -1210,7 +1241,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithFrameRate(float frameRate) {
|
||||
|
|
@ -1242,7 +1274,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithDrmInitData(@Nullable DrmInitData drmInitData) {
|
||||
|
|
@ -1274,7 +1307,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithMetadata(@Nullable Metadata metadata) {
|
||||
|
|
@ -1306,7 +1340,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithRotationDegrees(int rotationDegrees) {
|
||||
|
|
@ -1338,7 +1373,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithBitrate(int bitrate) {
|
||||
|
|
@ -1370,7 +1406,8 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithVideoSize(int width, int height) {
|
||||
|
|
@ -1402,7 +1439,41 @@ public final class Format implements Parcelable {
|
|||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel);
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
public Format copyWithExoMediaCryptoType(Class<? extends ExoMediaCrypto> exoMediaCryptoType) {
|
||||
return new Format(
|
||||
id,
|
||||
label,
|
||||
selectionFlags,
|
||||
roleFlags,
|
||||
bitrate,
|
||||
codecs,
|
||||
metadata,
|
||||
containerMimeType,
|
||||
sampleMimeType,
|
||||
maxInputSize,
|
||||
initializationData,
|
||||
drmInitData,
|
||||
subsampleOffsetUs,
|
||||
width,
|
||||
height,
|
||||
frameRate,
|
||||
rotationDegrees,
|
||||
pixelWidthHeightRatio,
|
||||
projectionData,
|
||||
stereoMode,
|
||||
colorInfo,
|
||||
channelCount,
|
||||
sampleRate,
|
||||
pcmEncoding,
|
||||
encoderDelay,
|
||||
encoderPadding,
|
||||
language,
|
||||
accessibilityChannel,
|
||||
exoMediaCryptoType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1481,6 +1552,8 @@ public final class Format implements Parcelable {
|
|||
// Audio and text specific.
|
||||
result = 31 * result + (language == null ? 0 : language.hashCode());
|
||||
result = 31 * result + accessibilityChannel;
|
||||
// Provided by source.
|
||||
result = 31 * result + (exoMediaCryptoType == null ? 0 : exoMediaCryptoType.hashCode());
|
||||
hashCode = result;
|
||||
}
|
||||
return hashCode;
|
||||
|
|
@ -1516,6 +1589,7 @@ public final class Format implements Parcelable {
|
|||
&& accessibilityChannel == other.accessibilityChannel
|
||||
&& Float.compare(frameRate, other.frameRate) == 0
|
||||
&& Float.compare(pixelWidthHeightRatio, other.pixelWidthHeightRatio) == 0
|
||||
&& Util.areEqual(exoMediaCryptoType, other.exoMediaCryptoType)
|
||||
&& Util.areEqual(id, other.id)
|
||||
&& Util.areEqual(label, other.label)
|
||||
&& Util.areEqual(codecs, other.codecs)
|
||||
|
|
|
|||
|
|
@ -308,7 +308,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||
return FORMAT_UNSUPPORTED_TYPE;
|
||||
}
|
||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||
boolean supportsFormatDrm = supportsFormatDrm(drmSessionManager, format.drmInitData);
|
||||
boolean supportsFormatDrm =
|
||||
format.drmInitData == null
|
||||
|| FrameworkMediaCrypto.class.equals(format.exoMediaCryptoType)
|
||||
|| (format.exoMediaCryptoType == null
|
||||
&& supportsFormatDrm(drmSessionManager, format.drmInitData));
|
||||
if (supportsFormatDrm
|
||||
&& allowPassthrough(format.channelCount, mimeType)
|
||||
&& mediaCodecSelector.getPassthroughDecoderInfo() != null) {
|
||||
|
|
|
|||
|
|
@ -436,6 +436,12 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto>
|
|||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<T> getExoMediaCryptoType(DrmInitData drmInitData) {
|
||||
return canAcquireSession(drmInitData) ? mediaDrm.getExoMediaCryptoType() : null;
|
||||
}
|
||||
|
||||
// ProvisioningManager implementation.
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.drm;
|
|||
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
|
|
@ -49,6 +50,12 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
|
|||
new DrmSession.DrmSessionException(
|
||||
new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<ExoMediaCrypto> getExoMediaCryptoType(DrmInitData drmInitData) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/** Flags that control the handling of DRM protected content. */
|
||||
|
|
@ -99,4 +106,11 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
|
|||
default int getFlags() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ExoMediaCrypto} type returned by sessions acquired using the given {@link
|
||||
* DrmInitData}, or null if a session cannot be acquired with the given {@link DrmInitData}.
|
||||
*/
|
||||
@Nullable
|
||||
Class<? extends ExoMediaCrypto> getExoMediaCryptoType(DrmInitData drmInitData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,4 +271,7 @@ public interface ExoMediaDrm<T extends ExoMediaCrypto> {
|
|||
* @throws MediaCryptoException If the instance can't be created.
|
||||
*/
|
||||
T createMediaCrypto(byte[] sessionId) throws MediaCryptoException;
|
||||
|
||||
/** Returns the {@link ExoMediaCrypto} type created by {@link #createMediaCrypto(byte[])}. */
|
||||
Class<T> getExoMediaCryptoType();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,6 +225,11 @@ public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto
|
|||
adjustUuid(uuid), initData, forceAllowInsecureDecoderComponents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<FrameworkMediaCrypto> getExoMediaCryptoType() {
|
||||
return FrameworkMediaCrypto.class;
|
||||
}
|
||||
|
||||
private static SchemeData getSchemeData(UUID uuid, List<SchemeData> schemeDatas) {
|
||||
if (!C.WIDEVINE_UUID.equals(uuid)) {
|
||||
// For non-Widevine CDMs always use the first scheme data.
|
||||
|
|
|
|||
|
|
@ -336,7 +336,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
if (decoderInfos.isEmpty()) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
}
|
||||
if (!supportsFormatDrm(drmSessionManager, drmInitData)) {
|
||||
boolean supportsFormatDrm =
|
||||
format.drmInitData == null
|
||||
|| FrameworkMediaCrypto.class.equals(format.exoMediaCryptoType)
|
||||
|| (format.exoMediaCryptoType == null
|
||||
&& supportsFormatDrm(drmSessionManager, format.drmInitData));
|
||||
if (!supportsFormatDrm) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
}
|
||||
// Check capabilities for the first decoder in the list, which takes priority.
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ public final class FormatTest {
|
|||
/* encoderDelay= */ 1001,
|
||||
/* encoderPadding= */ 1002,
|
||||
"language",
|
||||
/* accessibilityChannel= */ Format.NO_VALUE);
|
||||
/* accessibilityChannel= */ Format.NO_VALUE,
|
||||
/* exoMediaCryptoType= */ null);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
formatToParcel.writeToParcel(parcel, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue