mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Make all renderers DRM aware
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=166852758
This commit is contained in:
parent
b2c245281a
commit
44dc3c3ab3
12 changed files with 123 additions and 64 deletions
|
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.audio.AudioProcessor;
|
import com.google.android.exoplayer2.audio.AudioProcessor;
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer;
|
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer;
|
||||||
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
|
||||||
|
|
@ -58,13 +59,18 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(DrmSessionManager<ExoMediaCrypto> drmSessionManager,
|
||||||
if (!FfmpegLibrary.isAvailable()) {
|
Format format) {
|
||||||
|
String sampleMimeType = format.sampleMimeType;
|
||||||
|
if (!FfmpegLibrary.isAvailable() || !MimeTypes.isAudio(sampleMimeType)) {
|
||||||
return FORMAT_UNSUPPORTED_TYPE;
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
|
} else if (!FfmpegLibrary.supportsFormat(sampleMimeType)) {
|
||||||
|
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||||
|
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||||
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
|
} else {
|
||||||
|
return FORMAT_HANDLED;
|
||||||
}
|
}
|
||||||
String mimeType = format.sampleMimeType;
|
|
||||||
return FfmpegLibrary.supportsFormat(mimeType) ? FORMAT_HANDLED
|
|
||||||
: MimeTypes.isAudio(mimeType) ? FORMAT_UNSUPPORTED_SUBTYPE : FORMAT_UNSUPPORTED_TYPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.audio.AudioProcessor;
|
import com.google.android.exoplayer2.audio.AudioProcessor;
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer;
|
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer;
|
||||||
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
|
||||||
|
|
@ -46,9 +47,16 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(DrmSessionManager<ExoMediaCrypto> drmSessionManager,
|
||||||
return FlacLibrary.isAvailable() && MimeTypes.AUDIO_FLAC.equalsIgnoreCase(format.sampleMimeType)
|
Format format) {
|
||||||
? FORMAT_HANDLED : FORMAT_UNSUPPORTED_TYPE;
|
if (!FlacLibrary.isAvailable()
|
||||||
|
|| !MimeTypes.AUDIO_FLAC.equalsIgnoreCase(format.sampleMimeType)) {
|
||||||
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
|
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||||
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
|
} else {
|
||||||
|
return FORMAT_HANDLED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,16 @@ public final class LibopusAudioRenderer extends SimpleDecoderAudioRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(DrmSessionManager<ExoMediaCrypto> drmSessionManager,
|
||||||
return OpusLibrary.isAvailable() && MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)
|
Format format) {
|
||||||
? FORMAT_HANDLED : FORMAT_UNSUPPORTED_TYPE;
|
if (!OpusLibrary.isAvailable()
|
||||||
|
|| !MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)) {
|
||||||
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
|
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||||
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
|
} else {
|
||||||
|
return FORMAT_HANDLED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -194,8 +194,12 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
return VpxLibrary.isAvailable() && MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)
|
if (!VpxLibrary.isAvailable() || !MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)) {
|
||||||
? (FORMAT_HANDLED | ADAPTIVE_SEAMLESS) : FORMAT_UNSUPPORTED_TYPE;
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
|
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||||
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
|
}
|
||||||
|
return FORMAT_HANDLED | ADAPTIVE_SEAMLESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
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.source.SampleStream;
|
import com.google.android.exoplayer2.source.SampleStream;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.MediaClock;
|
import com.google.android.exoplayer2.util.MediaClock;
|
||||||
|
|
@ -309,4 +312,25 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
||||||
return readEndOfStream ? streamIsFinal : stream.isReady();
|
return readEndOfStream ? streamIsFinal : stream.isReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether {@code drmSessionManager} supports the specified {@code drmInitData}, or true
|
||||||
|
* if {@code drmInitData} is null.
|
||||||
|
*
|
||||||
|
* @param drmSessionManager The drm session manager.
|
||||||
|
* @param drmInitData {@link DrmInitData} of the format to check for support.
|
||||||
|
* @return Whether {@code drmSessionManager} supports the specified {@code drmInitData}, or
|
||||||
|
* true if {@code drmInitData} is null.
|
||||||
|
*/
|
||||||
|
protected static boolean supportsFormatDrm(@Nullable DrmSessionManager<?> drmSessionManager,
|
||||||
|
@Nullable DrmInitData drmInitData) {
|
||||||
|
if (drmInitData == null) {
|
||||||
|
// Content is unencrypted.
|
||||||
|
return true;
|
||||||
|
} else if (drmSessionManager == null) {
|
||||||
|
// Content is encrypted, but no drm session manager is available.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return drmSessionManager.canAcquireSession(drmInitData);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@ public interface RendererCapabilities {
|
||||||
int FORMAT_HANDLED = 0b100;
|
int FORMAT_HANDLED = 0b100;
|
||||||
/**
|
/**
|
||||||
* The {@link Renderer} is capable of rendering formats with the same mime type, but the
|
* The {@link Renderer} is capable of rendering formats with the same mime type, but the
|
||||||
* properties of the format exceed the renderer's capability.
|
* properties of the format exceed the renderer's capabilities. There is a chance the renderer
|
||||||
|
* will be able to play the format in practice because some renderers report their capabilities
|
||||||
|
* conservatively, but the expected outcome is that playback will fail.
|
||||||
* <p>
|
* <p>
|
||||||
* Example: The {@link Renderer} is capable of rendering H264 and the format's mime type is
|
* Example: The {@link Renderer} is capable of rendering H264 and the format's mime type is
|
||||||
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
|
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
|
||||||
|
|
@ -42,12 +44,12 @@ public interface RendererCapabilities {
|
||||||
*/
|
*/
|
||||||
int FORMAT_EXCEEDS_CAPABILITIES = 0b011;
|
int FORMAT_EXCEEDS_CAPABILITIES = 0b011;
|
||||||
/**
|
/**
|
||||||
* The {@link Renderer} is capable of rendering formats with the same mime type, but the
|
* The {@link Renderer} is capable of rendering formats with the same mime type, but is not
|
||||||
* drm scheme used is not supported.
|
* capable of rendering the format because the format's drm protection is not supported.
|
||||||
* <p>
|
* <p>
|
||||||
* Example: The {@link Renderer} is capable of rendering H264 and the format's mime type is
|
* Example: The {@link Renderer} is capable of rendering H264 and the format's mime type is
|
||||||
* {@link MimeTypes#VIDEO_H264}, but the format indicates cbcs encryption, which is not supported
|
* {@link MimeTypes#VIDEO_H264}, but the format indicates PlayReady drm protection where-as the
|
||||||
* by the underlying content decryption module.
|
* renderer only supports Widevine.
|
||||||
*/
|
*/
|
||||||
int FORMAT_UNSUPPORTED_DRM = 0b010;
|
int FORMAT_UNSUPPORTED_DRM = 0b010;
|
||||||
/**
|
/**
|
||||||
|
|
@ -121,9 +123,11 @@ public interface RendererCapabilities {
|
||||||
* {@link #FORMAT_UNSUPPORTED_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
|
* {@link #FORMAT_UNSUPPORTED_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
|
||||||
* <li>The level of support for adapting from the format to another format of the same mime type.
|
* <li>The level of support for adapting from the format to another format of the same mime type.
|
||||||
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
|
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
|
||||||
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
|
* {@link #ADAPTIVE_NOT_SUPPORTED}. Only set if the level of support for the format itself is
|
||||||
|
* {@link #FORMAT_HANDLED} or {@link #FORMAT_EXCEEDS_CAPABILITIES}.</li>
|
||||||
* <li>The level of support for tunneling. One of {@link #TUNNELING_SUPPORTED} and
|
* <li>The level of support for tunneling. One of {@link #TUNNELING_SUPPORTED} and
|
||||||
* {@link #TUNNELING_NOT_SUPPORTED}.</li>
|
* {@link #TUNNELING_NOT_SUPPORTED}. Only set if the level of support for the format itself is
|
||||||
|
* {@link #FORMAT_HANDLED} or {@link #FORMAT_EXCEEDS_CAPABILITIES}.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* The individual properties can be retrieved by performing a bitwise AND with
|
* The individual properties can be retrieved by performing a bitwise AND with
|
||||||
* {@link #FORMAT_SUPPORT_MASK}, {@link #ADAPTIVE_SUPPORT_MASK} and
|
* {@link #FORMAT_SUPPORT_MASK}, {@link #ADAPTIVE_SUPPORT_MASK} and
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher;
|
||||||
|
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;
|
||||||
|
|
@ -138,19 +139,34 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format)
|
protected int supportsFormat(MediaCodecSelector mediaCodecSelector,
|
||||||
|
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, Format format)
|
||||||
throws DecoderQueryException {
|
throws DecoderQueryException {
|
||||||
String mimeType = format.sampleMimeType;
|
String mimeType = format.sampleMimeType;
|
||||||
if (!MimeTypes.isAudio(mimeType)) {
|
if (!MimeTypes.isAudio(mimeType)) {
|
||||||
return FORMAT_UNSUPPORTED_TYPE;
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
}
|
}
|
||||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||||
if (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderInfo() != null) {
|
boolean supportsFormatDrm = supportsFormatDrm(drmSessionManager, format.drmInitData);
|
||||||
|
if (supportsFormatDrm && allowPassthrough(mimeType)
|
||||||
|
&& mediaCodecSelector.getPassthroughDecoderInfo() != null) {
|
||||||
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | FORMAT_HANDLED;
|
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | FORMAT_HANDLED;
|
||||||
}
|
}
|
||||||
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, false);
|
boolean requiresSecureDecryption = false;
|
||||||
|
DrmInitData drmInitData = format.drmInitData;
|
||||||
|
if (drmInitData != null) {
|
||||||
|
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
|
||||||
|
requiresSecureDecryption |= drmInitData.get(i).requiresSecureDecryption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
|
||||||
|
requiresSecureDecryption);
|
||||||
if (decoderInfo == null) {
|
if (decoderInfo == null) {
|
||||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
return requiresSecureDecryption && mediaCodecSelector.getDecoderInfo(mimeType, false) != null
|
||||||
|
? FORMAT_UNSUPPORTED_DRM : FORMAT_UNSUPPORTED_SUBTYPE;
|
||||||
|
}
|
||||||
|
if (!supportsFormatDrm) {
|
||||||
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
}
|
}
|
||||||
// Note: We assume support for unknown sampleRate and channelCount.
|
// Note: We assume support for unknown sampleRate and channelCount.
|
||||||
boolean decoderCapable = Util.SDK_INT < 21
|
boolean decoderCapable = Util.SDK_INT < 21
|
||||||
|
|
|
||||||
|
|
@ -159,8 +159,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int supportsFormat(Format format) {
|
public final int supportsFormat(Format format) {
|
||||||
int formatSupport = supportsFormatInternal(format);
|
int formatSupport = supportsFormatInternal(drmSessionManager, format);
|
||||||
if (formatSupport == FORMAT_UNSUPPORTED_TYPE || formatSupport == FORMAT_UNSUPPORTED_SUBTYPE) {
|
if (formatSupport <= FORMAT_UNSUPPORTED_DRM) {
|
||||||
return formatSupport;
|
return formatSupport;
|
||||||
}
|
}
|
||||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||||
|
|
@ -171,10 +171,12 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
|
||||||
* Returns the {@link #FORMAT_SUPPORT_MASK} component of the return value for
|
* Returns the {@link #FORMAT_SUPPORT_MASK} component of the return value for
|
||||||
* {@link #supportsFormat(Format)}.
|
* {@link #supportsFormat(Format)}.
|
||||||
*
|
*
|
||||||
|
* @param drmSessionManager The renderer's {@link DrmSessionManager}.
|
||||||
* @param format The format.
|
* @param format The format.
|
||||||
* @return The extent to which the renderer supports the format itself.
|
* @return The extent to which the renderer supports the format itself.
|
||||||
*/
|
*/
|
||||||
protected abstract int supportsFormatInternal(Format format);
|
protected abstract int supportsFormatInternal(DrmSessionManager<ExoMediaCrypto> drmSessionManager,
|
||||||
|
Format format);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
|
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.FormatHolder;
|
import com.google.android.exoplayer2.FormatHolder;
|
||||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||||
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.DrmSession;
|
import com.google.android.exoplayer2.drm.DrmSession;
|
||||||
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
|
|
@ -169,7 +168,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
private static final int ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT = 32;
|
private static final int ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT = 32;
|
||||||
|
|
||||||
private final MediaCodecSelector mediaCodecSelector;
|
private final MediaCodecSelector mediaCodecSelector;
|
||||||
@Nullable private final DrmSessionManager<FrameworkMediaCrypto> drmSessionManager;
|
@Nullable
|
||||||
|
private final DrmSessionManager<FrameworkMediaCrypto> drmSessionManager;
|
||||||
private final boolean playClearSamplesWithoutKeys;
|
private final boolean playClearSamplesWithoutKeys;
|
||||||
private final DecoderInputBuffer buffer;
|
private final DecoderInputBuffer buffer;
|
||||||
private final DecoderInputBuffer flagsOnlyBuffer;
|
private final DecoderInputBuffer flagsOnlyBuffer;
|
||||||
|
|
@ -247,14 +247,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
@Override
|
@Override
|
||||||
public final int supportsFormat(Format format) throws ExoPlaybackException {
|
public final int supportsFormat(Format format) throws ExoPlaybackException {
|
||||||
try {
|
try {
|
||||||
int formatSupport = supportsFormat(mediaCodecSelector, format);
|
return supportsFormat(mediaCodecSelector, drmSessionManager, format);
|
||||||
if ((formatSupport & FORMAT_SUPPORT_MASK) > FORMAT_UNSUPPORTED_DRM
|
|
||||||
&& !isDrmSchemeSupported(drmSessionManager, format.drmInitData)) {
|
|
||||||
// The renderer advertises higher support than FORMAT_UNSUPPORTED_DRM but the DRM scheme is
|
|
||||||
// not supported. The format support is truncated to reflect this.
|
|
||||||
formatSupport = (formatSupport & ~FORMAT_SUPPORT_MASK) | FORMAT_UNSUPPORTED_DRM;
|
|
||||||
}
|
|
||||||
return formatSupport;
|
|
||||||
} catch (DecoderQueryException e) {
|
} catch (DecoderQueryException e) {
|
||||||
throw ExoPlaybackException.createForRenderer(e, getIndex());
|
throw ExoPlaybackException.createForRenderer(e, getIndex());
|
||||||
}
|
}
|
||||||
|
|
@ -264,12 +257,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
* Returns the extent to which the renderer is capable of supporting a given format.
|
* Returns the extent to which the renderer is capable of supporting a given format.
|
||||||
*
|
*
|
||||||
* @param mediaCodecSelector The decoder selector.
|
* @param mediaCodecSelector The decoder selector.
|
||||||
|
* @param drmSessionManager The renderer's {@link DrmSessionManager}.
|
||||||
* @param format The format.
|
* @param format The format.
|
||||||
* @return The extent to which the renderer is capable of supporting the given format. See
|
* @return The extent to which the renderer is capable of supporting the given format. See
|
||||||
* {@link #supportsFormat(Format)} for more detail.
|
* {@link #supportsFormat(Format)} for more detail.
|
||||||
* @throws DecoderQueryException If there was an error querying decoders.
|
* @throws DecoderQueryException If there was an error querying decoders.
|
||||||
*/
|
*/
|
||||||
protected abstract int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format)
|
protected abstract int supportsFormat(MediaCodecSelector mediaCodecSelector,
|
||||||
|
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, Format format)
|
||||||
throws DecoderQueryException;
|
throws DecoderQueryException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1083,25 +1078,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the encryption scheme is supported, or true if {@code drmInitData} is null.
|
|
||||||
*
|
|
||||||
* @param drmSessionManager The drm session manager associated with the renderer.
|
|
||||||
* @param drmInitData {@link DrmInitData} of the format to check for support.
|
|
||||||
* @return Whether the encryption scheme is supported, or true if {@code drmInitData} is null.
|
|
||||||
*/
|
|
||||||
private static boolean isDrmSchemeSupported(@Nullable DrmSessionManager drmSessionManager,
|
|
||||||
@Nullable DrmInitData drmInitData) {
|
|
||||||
if (drmInitData == null) {
|
|
||||||
// Content is unencrypted.
|
|
||||||
return true;
|
|
||||||
} else if (drmSessionManager == null) {
|
|
||||||
// Content is encrypted, but no drm session manager is available.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return drmSessionManager.canAcquireSession(drmInitData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the decoder is known to fail when flushed.
|
* Returns whether the decoder is known to fail when flushed.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,11 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
return decoderFactory.supportsFormat(format) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_TYPE;
|
if (decoderFactory.supportsFormat(format)) {
|
||||||
|
return supportsFormatDrm(null, format.drmInitData) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_DRM;
|
||||||
|
} else {
|
||||||
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -117,9 +117,13 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
return decoderFactory.supportsFormat(format) ? FORMAT_HANDLED
|
if (decoderFactory.supportsFormat(format)) {
|
||||||
: (MimeTypes.isText(format.sampleMimeType) ? FORMAT_UNSUPPORTED_SUBTYPE
|
return supportsFormatDrm(null, format.drmInitData) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_DRM;
|
||||||
: FORMAT_UNSUPPORTED_TYPE);
|
} else if (MimeTypes.isText(format.sampleMimeType)) {
|
||||||
|
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||||
|
} else {
|
||||||
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format)
|
protected int supportsFormat(MediaCodecSelector mediaCodecSelector,
|
||||||
|
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, Format format)
|
||||||
throws DecoderQueryException {
|
throws DecoderQueryException {
|
||||||
String mimeType = format.sampleMimeType;
|
String mimeType = format.sampleMimeType;
|
||||||
if (!MimeTypes.isVideo(mimeType)) {
|
if (!MimeTypes.isVideo(mimeType)) {
|
||||||
|
|
@ -202,9 +203,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
||||||
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
|
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
|
||||||
requiresSecureDecryption);
|
requiresSecureDecryption);
|
||||||
if (decoderInfo == null) {
|
if (decoderInfo == null) {
|
||||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
return requiresSecureDecryption && mediaCodecSelector.getDecoderInfo(mimeType, false) != null
|
||||||
|
? FORMAT_UNSUPPORTED_DRM : FORMAT_UNSUPPORTED_SUBTYPE;
|
||||||
|
}
|
||||||
|
if (!supportsFormatDrm(drmSessionManager, drmInitData)) {
|
||||||
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean decoderCapable = decoderInfo.isCodecSupported(format.codecs);
|
boolean decoderCapable = decoderInfo.isCodecSupported(format.codecs);
|
||||||
if (decoderCapable && format.width > 0 && format.height > 0) {
|
if (decoderCapable && format.width > 0 && format.height > 0) {
|
||||||
if (Util.SDK_INT >= 21) {
|
if (Util.SDK_INT >= 21) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue