下面列出了android.media.MediaCrypto#com.google.android.exoplayer2.drm.DrmSession.DrmSessionException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns the remaining license and playback durations in seconds, for an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license.
* @return The remaining license and playback durations, in seconds.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
drmSessionManager.prepare();
DrmSession<T> drmSession =
openBlockingKeyRequest(
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSession.release();
drmSessionManager.release();
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
}
throw error;
}
return Assertions.checkNotNull(licenseDurationRemainingSec);
}
/**
* Returns the remaining license and playback durations in seconds, for an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license.
* @return The remaining license and playback durations, in seconds.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
DrmSession<T> drmSession = openBlockingKeyRequest(DefaultDrmSessionManager.MODE_QUERY,
offlineLicenseKeySetId, null);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSessionManager.releaseSession(drmSession);
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
}
throw error;
}
return licenseDurationRemainingSec;
}
/**
* Returns the remaining license and playback durations in seconds, for an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license.
* @return The remaining license and playback durations, in seconds.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
DrmSession<T> drmSession = openBlockingKeyRequest(DefaultDrmSessionManager.MODE_QUERY,
offlineLicenseKeySetId, null);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSessionManager.releaseSession(drmSession);
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
}
throw error;
}
return licenseDurationRemainingSec;
}
/**
* Returns the remaining license and playback durations in seconds, for an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license.
* @return The remaining license and playback durations, in seconds.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
DrmSession<T> drmSession =
openBlockingKeyRequest(
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSessionManager.releaseSession(drmSession);
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
}
throw error;
}
return Assertions.checkNotNull(licenseDurationRemainingSec);
}
/**
* Returns the remaining license and playback durations in seconds, for an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license.
* @return The remaining license and playback durations, in seconds.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
DrmSession<T> drmSession =
openBlockingKeyRequest(
DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSessionManager.releaseSession(drmSession);
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
}
throw error;
}
return Assertions.checkNotNull(licenseDurationRemainingSec);
}
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
assertExpectedPlaybackLooper(playbackLooper);
maybeCreateMediaDrmHandler(playbackLooper);
@Nullable List<SchemeData> schemeDatas = null;
if (offlineLicenseKeySetId == null) {
schemeDatas = getSchemeDatas(drmInitData, uuid, false);
if (schemeDatas.isEmpty()) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
return new ErrorStateDrmSession<>(new DrmSessionException(error));
}
}
@Nullable DefaultDrmSession<T> session;
if (!multiSession) {
session = noMultiSessionDrmSession;
} else {
// Only use an existing session if it has matching init data.
session = null;
for (DefaultDrmSession<T> existingSession : sessions) {
if (Util.areEqual(existingSession.schemeDatas, schemeDatas)) {
session = existingSession;
break;
}
}
}
if (session == null) {
// Create a new session.
session = createNewDefaultSession(schemeDatas, /* isPlaceholderSession= */ false);
if (!multiSession) {
noMultiSessionDrmSession = session;
}
sessions.add(session);
}
session.acquire();
return session;
}
/**
* Releases an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license to be released.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized void releaseLicense(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
blockingKeyRequest(
DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
}
private byte[] blockingKeyRequest(
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
throws DrmSessionException {
drmSessionManager.prepare();
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSession.release();
drmSessionManager.release();
if (error != null) {
throw error;
}
return Assertions.checkNotNull(keySetId);
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
setDecoderDrmSession(sourceDrmSession);
ExoMediaCrypto mediaCrypto = null;
if (decoderDrmSession != null) {
mediaCrypto = decoderDrmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = decoderDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createAudioDecoder");
decoder = createDecoder(inputFormat, mediaCrypto);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (AudioDecoderException e) {
throw createRendererException(e, inputFormat);
}
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
setDecoderDrmSession(sourceDrmSession);
ExoMediaCrypto mediaCrypto = null;
if (decoderDrmSession != null) {
mediaCrypto = decoderDrmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = decoderDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long decoderInitializingTimestamp = SystemClock.elapsedRealtime();
decoder = createDecoder(inputFormat, mediaCrypto);
setDecoderOutputMode(outputMode);
long decoderInitializedTimestamp = SystemClock.elapsedRealtime();
onDecoderInitialized(
decoder.getName(),
decoderInitializedTimestamp,
decoderInitializedTimestamp - decoderInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (VideoDecoderException e) {
throw createRendererException(e, inputFormat);
}
}
private byte[] blockingKeyRequest(@Mode int licenseMode, byte[] offlineLicenseKeySetId,
DrmInitData drmInitData) throws DrmSessionException {
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSessionManager.releaseSession(drmSession);
if (error != null) {
throw error;
}
return keySetId;
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
drmSession = pendingDrmSession;
ExoMediaCrypto mediaCrypto = null;
if (drmSession != null) {
mediaCrypto = drmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = drmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createAudioDecoder");
decoder = createDecoder(inputFormat, mediaCrypto);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (AudioDecoderException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
private byte[] blockingKeyRequest(@Mode int licenseMode, byte[] offlineLicenseKeySetId,
DrmInitData drmInitData) throws DrmSessionException {
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSessionManager.releaseSession(drmSession);
if (error != null) {
throw error;
}
return keySetId;
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
drmSession = pendingDrmSession;
ExoMediaCrypto mediaCrypto = null;
if (drmSession != null) {
mediaCrypto = drmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = drmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createAudioDecoder");
decoder = createDecoder(inputFormat, mediaCrypto);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (AudioDecoderException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (videoDecoder != null) {
return;
}
drmSession = pendingDrmSession;
ExoMediaCrypto mediaCrypto = null;
if (drmSession != null) {
mediaCrypto = drmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = drmSession.getError();
if (drmError != null) {
throw ExoPlaybackException.createForRenderer(drmError, getIndex());
}
// The drm session isn't open yet.
return;
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createFFmpegDecoder");
videoDecoder = new VideoDecoder(format, NUM_INPUT_BUFFERS, NUM_OUTPUT_BUFFERS, INITIAL_INPUT_BUFFER_SIZE,
mediaCrypto);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(videoDecoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (Exception e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
public byte[] downloadLicense() throws InterruptedException, DrmSessionException, IOException {
assertNull(offlineLicenseKeySetId);
offlineLicenseKeySetId = offlineLicenseHelper
.download(httpDataSourceFactory.createDataSource(), parameters.manifestUrl);
assertNotNull(offlineLicenseKeySetId);
assertTrue(offlineLicenseKeySetId.length > 0);
return offlineLicenseKeySetId;
}
public void releaseResources() throws DrmSessionException {
if (offlineLicenseKeySetId != null) {
releaseLicense();
}
if (offlineLicenseHelper != null) {
offlineLicenseHelper.releaseResources();
}
}
/**
* Downloads an offline license.
*
* @param dataSource The {@link HttpDataSource} to be used for download.
* @param dashManifest The {@link DashManifest} of the DASH content.
* @return The downloaded offline license key set id.
* @throws IOException If an error occurs reading data from the stream.
* @throws InterruptedException If the thread has been interrupted.
* @throws DrmSessionException Thrown when there is an error during DRM session.
*/
public byte[] download(HttpDataSource dataSource, DashManifest dashManifest)
throws IOException, InterruptedException, DrmSessionException {
// Get DrmInitData
// Prefer drmInitData obtained from the manifest over drmInitData obtained from the stream,
// as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
if (dashManifest.getPeriodCount() < 1) {
return null;
}
Period period = dashManifest.getPeriod(0);
int adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_VIDEO);
if (adaptationSetIndex == C.INDEX_UNSET) {
adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_AUDIO);
if (adaptationSetIndex == C.INDEX_UNSET) {
return null;
}
}
AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
if (adaptationSet.representations.isEmpty()) {
return null;
}
Representation representation = adaptationSet.representations.get(0);
DrmInitData drmInitData = representation.format.drmInitData;
if (drmInitData == null) {
Format sampleFormat = DashUtil.loadSampleFormat(dataSource, representation);
if (sampleFormat != null) {
drmInitData = sampleFormat.drmInitData;
}
if (drmInitData == null) {
return null;
}
}
blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, drmInitData);
return drmSessionManager.getOfflineLicenseKeySetId();
}
/**
* Returns license and playback durations remaining in seconds of the given offline license.
*
* @param offlineLicenseKeySetId The key set id of the license.
*/
public Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
DrmSession<T> session = openBlockingKeyRequest(DefaultDrmSessionManager.MODE_QUERY,
offlineLicenseKeySetId, null);
Pair<Long, Long> licenseDurationRemainingSec =
WidevineUtil.getLicenseDurationRemainingSec(drmSessionManager);
drmSessionManager.releaseSession(session);
return licenseDurationRemainingSec;
}
private void blockingKeyRequest(@Mode int licenseMode, byte[] offlineLicenseKeySetId,
DrmInitData drmInitData) throws DrmSessionException {
DrmSession<T> session = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = session.getError();
if (error != null) {
throw error;
}
drmSessionManager.releaseSession(session);
}
/**
* Releases an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license to be released.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized void releaseLicense(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
blockingKeyRequest(
DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
}
private byte[] blockingKeyRequest(
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
throws DrmSessionException {
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSessionManager.releaseSession(drmSession);
if (error != null) {
throw error;
}
return Assertions.checkNotNull(keySetId);
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
setDecoderDrmSession(sourceDrmSession);
ExoMediaCrypto mediaCrypto = null;
if (decoderDrmSession != null) {
mediaCrypto = decoderDrmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = decoderDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createAudioDecoder");
decoder = createDecoder(inputFormat, mediaCrypto);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (AudioDecoderException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
/**
* Releases an offline license.
*
* @param offlineLicenseKeySetId The key set id of the license to be released.
* @throws DrmSessionException Thrown when a DRM session error occurs.
*/
public synchronized void releaseLicense(byte[] offlineLicenseKeySetId)
throws DrmSessionException {
Assertions.checkNotNull(offlineLicenseKeySetId);
blockingKeyRequest(
DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, DUMMY_DRM_INIT_DATA);
}
private byte[] blockingKeyRequest(
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData)
throws DrmSessionException {
DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId,
drmInitData);
DrmSessionException error = drmSession.getError();
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
drmSessionManager.releaseSession(drmSession);
if (error != null) {
throw error;
}
return Assertions.checkNotNull(keySetId);
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) {
return;
}
setDecoderDrmSession(sourceDrmSession);
ExoMediaCrypto mediaCrypto = null;
if (decoderDrmSession != null) {
mediaCrypto = decoderDrmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = decoderDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
}
}
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createAudioDecoder");
decoder = createDecoder(inputFormat, mediaCrypto);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.decoderInitCount++;
} catch (AudioDecoderException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
if (sessions.isEmpty()) {
this.playbackLooper = playbackLooper;
if (mediaDrmHandler == null) {
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
}
}
SchemeData schemeData = null;
if (offlineLicenseKeySetId == null) {
schemeData = getSchemeData(drmInitData, uuid, false);
if (schemeData == null) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
return new ErrorStateDrmSession<>(new DrmSessionException(error));
}
}
DefaultDrmSession<T> session;
if (!multiSession) {
session = sessions.isEmpty() ? null : sessions.get(0);
} else {
// Only use an existing session if it has matching init data.
session = null;
byte[] initData = schemeData != null ? schemeData.data : null;
for (DefaultDrmSession<T> existingSession : sessions) {
if (existingSession.hasInitData(initData)) {
session = existingSession;
break;
}
}
}
if (session == null) {
// Create a new session.
session =
new DefaultDrmSession<>(
uuid,
mediaDrm,
this,
schemeData,
mode,
offlineLicenseKeySetId,
optionalKeyRequestParameters,
callback,
playbackLooper,
eventDispatcher,
initialDrmRequestRetryCount);
sessions.add(session);
}
session.acquire();
return session;
}
protected final void maybeInitCodec() throws ExoPlaybackException {
if (codec != null || format == null) {
// We have a codec already, or we don't have a format with which to instantiate one.
return;
}
drmSession = pendingDrmSession;
String mimeType = format.sampleMimeType;
MediaCrypto wrappedMediaCrypto = null;
boolean drmSessionRequiresSecureDecoder = false;
if (drmSession != null) {
FrameworkMediaCrypto mediaCrypto = drmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = drmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
} else {
wrappedMediaCrypto = mediaCrypto.getWrappedMediaCrypto();
drmSessionRequiresSecureDecoder = mediaCrypto.requiresSecureDecoderComponent(mimeType);
}
if (deviceNeedsDrmKeysToConfigureCodecWorkaround()) {
@DrmSession.State int drmSessionState = drmSession.getState();
if (drmSessionState == DrmSession.STATE_ERROR) {
throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
} else if (drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS) {
// Wait for keys.
return;
}
}
}
try {
if (!initCodecWithFallback(wrappedMediaCrypto, drmSessionRequiresSecureDecoder)) {
// We can't initialize a codec yet.
return;
}
} catch (DecoderInitializationException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
String codecName = codecInfo.name;
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, format);
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecInfo);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround = codecNeedsMonoChannelCountWorkaround(codecName, format);
codecHotswapDeadlineMs =
getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
: C.TIME_UNSET;
resetInputBuffer();
resetOutputBuffer();
waitingForFirstSyncFrame = true;
decoderCounters.decoderInitCount++;
}
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
if (sessions.isEmpty()) {
this.playbackLooper = playbackLooper;
if (mediaDrmHandler == null) {
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
}
}
SchemeData schemeData = null;
if (offlineLicenseKeySetId == null) {
schemeData = getSchemeData(drmInitData, uuid, false);
if (schemeData == null) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
return new ErrorStateDrmSession<>(new DrmSessionException(error));
}
}
DefaultDrmSession<T> session;
if (!multiSession) {
session = sessions.isEmpty() ? null : sessions.get(0);
} else {
// Only use an existing session if it has matching init data.
session = null;
byte[] initData = schemeData != null ? schemeData.data : null;
for (DefaultDrmSession<T> existingSession : sessions) {
if (existingSession.hasInitData(initData)) {
session = existingSession;
break;
}
}
}
if (session == null) {
// Create a new session.
session =
new DefaultDrmSession<>(
uuid,
mediaDrm,
this,
schemeData,
mode,
offlineLicenseKeySetId,
optionalKeyRequestParameters,
callback,
playbackLooper,
eventDispatcher,
initialDrmRequestRetryCount);
sessions.add(session);
}
session.acquire();
return session;
}
protected final void maybeInitCodec() throws ExoPlaybackException {
if (codec != null || format == null) {
// We have a codec already, or we don't have a format with which to instantiate one.
return;
}
drmSession = pendingDrmSession;
String mimeType = format.sampleMimeType;
MediaCrypto wrappedMediaCrypto = null;
boolean drmSessionRequiresSecureDecoder = false;
if (drmSession != null) {
FrameworkMediaCrypto mediaCrypto = drmSession.getMediaCrypto();
if (mediaCrypto == null) {
DrmSessionException drmError = drmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if the session recovers, or if a new
// input format causes the session to be replaced before it's used.
} else {
// The drm session isn't open yet.
return;
}
} else {
wrappedMediaCrypto = mediaCrypto.getWrappedMediaCrypto();
drmSessionRequiresSecureDecoder = mediaCrypto.requiresSecureDecoderComponent(mimeType);
}
if (deviceNeedsDrmKeysToConfigureCodecWorkaround()) {
@DrmSession.State int drmSessionState = drmSession.getState();
if (drmSessionState == DrmSession.STATE_ERROR) {
throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
} else if (drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS) {
// Wait for keys.
return;
}
}
}
try {
if (!initCodecWithFallback(wrappedMediaCrypto, drmSessionRequiresSecureDecoder)) {
// We can't initialize a codec yet.
return;
}
} catch (DecoderInitializationException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
String codecName = codecInfo.name;
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, format);
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecInfo);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround = codecNeedsMonoChannelCountWorkaround(codecName, format);
codecHotswapDeadlineMs =
getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
: C.TIME_UNSET;
resetInputBuffer();
resetOutputBuffer();
waitingForFirstSyncFrame = true;
decoderCounters.decoderInitCount++;
}