use of com.google.android.exoplayer2.drm.DrmSession in project ExoPlayer by google.
the class MediaCodecRenderer method drmNeedsCodecReinitialization.
/**
* Returns whether it's necessary to re-initialize the codec to handle a DRM change. If {@code
* false} is returned then either {@code oldSession == newSession} (i.e., there was no change), or
* it's possible to update the existing codec using MediaCrypto.setMediaDrmSession.
*/
private boolean drmNeedsCodecReinitialization(MediaCodecInfo codecInfo, Format newFormat, @Nullable DrmSession oldSession, @Nullable DrmSession newSession) throws ExoPlaybackException {
if (oldSession == newSession) {
// No need to re-initialize if the old and new sessions are the same.
return false;
}
if (newSession == null || oldSession == null) {
// Changing from DRM to no DRM and vice-versa always requires re-initialization.
return true;
}
if (Util.SDK_INT < 23) {
// required to switch to newSession on older API levels.
return true;
}
if (C.PLAYREADY_UUID.equals(oldSession.getSchemeUuid()) || C.PLAYREADY_UUID.equals(newSession.getSchemeUuid())) {
// TODO: Add an API check once [Internal ref: b/128835874] is fixed.
return true;
}
@Nullable FrameworkCryptoConfig newCryptoConfig = getFrameworkCryptoConfig(newSession);
if (newCryptoConfig == null) {
// the case is to occur, so we re-initialize in this case.
return true;
}
boolean requiresSecureDecoder;
if (newCryptoConfig.forceAllowInsecureDecoderComponents) {
requiresSecureDecoder = false;
} else {
requiresSecureDecoder = newSession.requiresSecureDecoder(newFormat.sampleMimeType);
}
if (!codecInfo.secure && requiresSecureDecoder) {
// output path.
return true;
}
return false;
}
use of com.google.android.exoplayer2.drm.DrmSession in project ExoPlayer by google.
the class DefaultDrmSessionManager method acquireSession.
// Must be called on the playback thread.
@Nullable
private DrmSession acquireSession(Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format, boolean shouldReleasePreacquiredSessionsBeforeRetrying) {
maybeCreateMediaDrmHandler(playbackLooper);
if (format.drmInitData == null) {
// Content is not encrypted.
return maybeAcquirePlaceholderSession(MimeTypes.getTrackType(format.sampleMimeType), shouldReleasePreacquiredSessionsBeforeRetrying);
}
@Nullable List<SchemeData> schemeDatas = null;
if (offlineLicenseKeySetId == null) {
schemeDatas = getSchemeDatas(checkNotNull(format.drmInitData), uuid, false);
if (schemeDatas.isEmpty()) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
Log.e(TAG, "DRM error", error);
if (eventDispatcher != null) {
eventDispatcher.drmSessionManagerError(error);
}
return new ErrorStateDrmSession(new DrmSessionException(error, PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR));
}
}
@Nullable DefaultDrmSession session;
if (!multiSession) {
session = noMultiSessionDrmSession;
} else {
// Only use an existing session if it has matching init data.
session = null;
for (DefaultDrmSession existingSession : sessions) {
if (Util.areEqual(existingSession.schemeDatas, schemeDatas)) {
session = existingSession;
break;
}
}
}
if (session == null) {
// Create a new session.
session = createAndAcquireSessionWithRetry(schemeDatas, /* isPlaceholderSession= */
false, eventDispatcher, shouldReleasePreacquiredSessionsBeforeRetrying);
if (!multiSession) {
noMultiSessionDrmSession = session;
}
sessions.add(session);
} else {
session.acquire(eventDispatcher);
}
return session;
}
use of com.google.android.exoplayer2.drm.DrmSession in project ExoPlayer by google.
the class OfflineLicenseHelper method getLicenseDurationRemainingSec.
/**
* 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.setPlayer(handlerThread.getLooper(), PlayerId.UNSET);
drmSessionManager.prepare();
DrmSession drmSession = openBlockingKeyRequest(DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, FORMAT_WITH_EMPTY_DRM_INIT_DATA);
DrmSessionException error = drmSession.getError();
Pair<Long, Long> licenseDurationRemainingSec = WidevineUtil.getLicenseDurationRemainingSec(drmSession);
drmSession.release(eventDispatcher);
drmSessionManager.release();
if (error != null) {
if (error.getCause() instanceof KeysExpiredException) {
return Pair.create(0L, 0L);
}
throw error;
}
return Assertions.checkNotNull(licenseDurationRemainingSec);
}
use of com.google.android.exoplayer2.drm.DrmSession in project ExoPlayer by google.
the class SampleQueue method onFormatResult.
/**
* Sets the downstream format, performs DRM resource management, and populates the {@code
* outputFormatHolder}.
*
* @param newFormat The new downstream format.
* @param outputFormatHolder The output {@link FormatHolder}.
*/
private void onFormatResult(Format newFormat, FormatHolder outputFormatHolder) {
boolean isFirstFormat = downstreamFormat == null;
@Nullable DrmInitData oldDrmInitData = isFirstFormat ? null : downstreamFormat.drmInitData;
downstreamFormat = newFormat;
@Nullable DrmInitData newDrmInitData = newFormat.drmInitData;
outputFormatHolder.format = drmSessionManager != null ? newFormat.copyWithCryptoType(drmSessionManager.getCryptoType(newFormat)) : newFormat;
outputFormatHolder.drmSession = currentDrmSession;
if (drmSessionManager == null) {
// This sample queue is not expected to handle DRM. Nothing to do.
return;
}
if (!isFirstFormat && Util.areEqual(oldDrmInitData, newDrmInitData)) {
// Nothing to do.
return;
}
// Ensure we acquire the new session before releasing the previous one in case the same session
// is being used for both DrmInitData.
@Nullable DrmSession previousSession = currentDrmSession;
currentDrmSession = drmSessionManager.acquireSession(drmEventDispatcher, newFormat);
outputFormatHolder.drmSession = currentDrmSession;
if (previousSession != null) {
previousSession.release(drmEventDispatcher);
}
}
use of com.google.android.exoplayer2.drm.DrmSession in project ExoPlayer by google.
the class SampleQueueTest method allowPlaceholderSessionPopulatesDrmSession.
@Test
public void allowPlaceholderSessionPopulatesDrmSession() {
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
DrmSession mockPlaceholderDrmSession = Mockito.mock(DrmSession.class);
when(mockPlaceholderDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED_WITH_KEYS);
mockDrmSessionManager.mockPlaceholderDrmSession = mockPlaceholderDrmSession;
writeTestDataWithEncryptedSections();
int result = sampleQueue.read(formatHolder, inputBuffer, /* readFlags= */
0, /* loadingFinished= */
false);
assertThat(result).isEqualTo(RESULT_FORMAT_READ);
assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession);
assertReadEncryptedSample(/* sampleIndex= */
0);
assertReadEncryptedSample(/* sampleIndex= */
1);
formatHolder.clear();
assertThat(formatHolder.drmSession).isNull();
result = sampleQueue.read(formatHolder, inputBuffer, /* readFlags= */
0, /* loadingFinished= */
false);
assertThat(result).isEqualTo(RESULT_FORMAT_READ);
assertThat(formatHolder.drmSession).isSameInstanceAs(mockPlaceholderDrmSession);
assertReadEncryptedSample(/* sampleIndex= */
2);
result = sampleQueue.read(formatHolder, inputBuffer, /* readFlags= */
0, /* loadingFinished= */
false);
assertThat(result).isEqualTo(RESULT_FORMAT_READ);
assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession);
assertReadEncryptedSample(/* sampleIndex= */
3);
}
Aggregations