Search in sources :

Example 1 with DrmSessionReference

use of androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference in project media by androidx.

the class SampleQueue method commitSample.

private synchronized void commitSample(long timeUs, @C.BufferFlags int sampleFlags, long offset, int size, @Nullable CryptoData cryptoData) {
    if (length > 0) {
        // Ensure sample data doesn't overlap.
        int previousSampleRelativeIndex = getRelativeIndex(length - 1);
        checkArgument(offsets[previousSampleRelativeIndex] + sizes[previousSampleRelativeIndex] <= offset);
    }
    isLastSampleQueued = (sampleFlags & C.BUFFER_FLAG_LAST_SAMPLE) != 0;
    largestQueuedTimestampUs = max(largestQueuedTimestampUs, timeUs);
    int relativeEndIndex = getRelativeIndex(length);
    timesUs[relativeEndIndex] = timeUs;
    offsets[relativeEndIndex] = offset;
    sizes[relativeEndIndex] = size;
    flags[relativeEndIndex] = sampleFlags;
    cryptoDatas[relativeEndIndex] = cryptoData;
    sourceIds[relativeEndIndex] = upstreamSourceId;
    if (sharedSampleMetadata.isEmpty() || !sharedSampleMetadata.getEndValue().format.equals(upstreamFormat)) {
        DrmSessionReference drmSessionReference = drmSessionManager != null ? drmSessionManager.preacquireSession(drmEventDispatcher, upstreamFormat) : DrmSessionReference.EMPTY;
        sharedSampleMetadata.appendSpan(getWriteIndex(), new SharedSampleMetadata(checkNotNull(upstreamFormat), drmSessionReference));
    }
    length++;
    if (length == capacity) {
        // Increase the capacity.
        int newCapacity = capacity + SAMPLE_CAPACITY_INCREMENT;
        int[] newSourceIds = new int[newCapacity];
        long[] newOffsets = new long[newCapacity];
        long[] newTimesUs = new long[newCapacity];
        int[] newFlags = new int[newCapacity];
        int[] newSizes = new int[newCapacity];
        CryptoData[] newCryptoDatas = new CryptoData[newCapacity];
        int beforeWrap = capacity - relativeFirstIndex;
        System.arraycopy(offsets, relativeFirstIndex, newOffsets, 0, beforeWrap);
        System.arraycopy(timesUs, relativeFirstIndex, newTimesUs, 0, beforeWrap);
        System.arraycopy(flags, relativeFirstIndex, newFlags, 0, beforeWrap);
        System.arraycopy(sizes, relativeFirstIndex, newSizes, 0, beforeWrap);
        System.arraycopy(cryptoDatas, relativeFirstIndex, newCryptoDatas, 0, beforeWrap);
        System.arraycopy(sourceIds, relativeFirstIndex, newSourceIds, 0, beforeWrap);
        int afterWrap = relativeFirstIndex;
        System.arraycopy(offsets, 0, newOffsets, beforeWrap, afterWrap);
        System.arraycopy(timesUs, 0, newTimesUs, beforeWrap, afterWrap);
        System.arraycopy(flags, 0, newFlags, beforeWrap, afterWrap);
        System.arraycopy(sizes, 0, newSizes, beforeWrap, afterWrap);
        System.arraycopy(cryptoDatas, 0, newCryptoDatas, beforeWrap, afterWrap);
        System.arraycopy(sourceIds, 0, newSourceIds, beforeWrap, afterWrap);
        offsets = newOffsets;
        timesUs = newTimesUs;
        flags = newFlags;
        sizes = newSizes;
        cryptoDatas = newCryptoDatas;
        sourceIds = newSourceIds;
        relativeFirstIndex = 0;
        capacity = newCapacity;
    }
}
Also used : DrmSessionReference(androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference)

Example 2 with DrmSessionReference

use of androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference in project media by androidx.

the class DefaultDrmSessionManagerTest method maxConcurrentSessionsExceeded_allPreacquiredAndKeepaliveSessionsEagerlyReleased.

@Test(timeout = 10_000)
public void maxConcurrentSessionsExceeded_allPreacquiredAndKeepaliveSessionsEagerlyReleased() throws Exception {
    ImmutableList<DrmInitData.SchemeData> secondSchemeDatas = ImmutableList.of(DRM_SCHEME_DATAS.get(0).copyWithData(TestUtil.createByteArray(4, 5, 6)));
    FakeExoMediaDrm.LicenseServer licenseServer = FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS, secondSchemeDatas);
    Format secondFormatWithDrmInitData = new Format.Builder().setDrmInitData(new DrmInitData(secondSchemeDatas)).build();
    DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm.Builder().setMaxConcurrentSessions(1).build()).setSessionKeepaliveMs(10_000).setMultiSession(true).build(/* mediaDrmCallback= */
    licenseServer);
    drmSessionManager.prepare();
    drmSessionManager.setPlayer(/* playbackLooper= */
    Looper.myLooper(), PlayerId.UNSET);
    DrmSessionReference firstDrmSessionReference = checkNotNull(drmSessionManager.preacquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA));
    DrmSession firstDrmSession = checkNotNull(drmSessionManager.acquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA));
    waitForOpenedWithKeys(firstDrmSession);
    firstDrmSession.release(/* eventDispatcher= */
    null);
    // The direct reference to firstDrmSession has been released, it's being kept alive by both
    // firstDrmSessionReference and drmSessionManager's internal reference.
    assertThat(firstDrmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
    DrmSession secondDrmSession = checkNotNull(drmSessionManager.acquireSession(/* eventDispatcher= */
    null, secondFormatWithDrmInitData));
    // The drmSessionManager had to release both it's internal keep-alive reference and the
    // reference represented by firstDrmSessionReference in order to acquire secondDrmSession.
    assertThat(firstDrmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
    waitForOpenedWithKeys(secondDrmSession);
    assertThat(secondDrmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
    // Not needed (because the manager has already released this reference) but we call it anyway
    // for completeness.
    firstDrmSessionReference.release();
    // Clean-up
    secondDrmSession.release(/* eventDispatcher= */
    null);
    drmSessionManager.release();
}
Also used : Assertions.checkNotNull(androidx.media3.common.util.Assertions.checkNotNull) DrmInitData(androidx.media3.common.DrmInitData) AppManagedProvider(androidx.media3.exoplayer.drm.ExoMediaDrm.AppManagedProvider) Assert.assertThrows(org.junit.Assert.assertThrows) DrmSessionReference(androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference) RunWith(org.junit.runner.RunWith) FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) ImmutableList(com.google.common.collect.ImmutableList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Looper(android.os.Looper) TestUtil(androidx.media3.test.utils.TestUtil) MediaSource(androidx.media3.exoplayer.source.MediaSource) ImmutableSet(com.google.common.collect.ImmutableSet) ShadowLooper(org.robolectric.shadows.ShadowLooper) MimeTypes(androidx.media3.common.MimeTypes) Test(org.junit.Test) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) Util(androidx.media3.common.util.Util) Format(androidx.media3.common.Format) C(androidx.media3.common.C) Nullable(androidx.annotation.Nullable) PlayerId(androidx.media3.exoplayer.analytics.PlayerId) SECONDS(java.util.concurrent.TimeUnit.SECONDS) Format(androidx.media3.common.Format) DrmInitData(androidx.media3.common.DrmInitData) DrmSessionReference(androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference) FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) Test(org.junit.Test)

Example 3 with DrmSessionReference

use of androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference in project media by androidx.

the class DefaultDrmSessionManagerTest method preacquireSession_releaseBeforeUnderlyingAcquisitionCompletesReleasesSessionOnceAcquired.

@Test(timeout = 10_000)
public void preacquireSession_releaseBeforeUnderlyingAcquisitionCompletesReleasesSessionOnceAcquired() throws Exception {
    FakeExoMediaDrm.LicenseServer licenseServer = FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS);
    DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()).setSessionKeepaliveMs(C.TIME_UNSET).build(/* mediaDrmCallback= */
    licenseServer);
    drmSessionManager.prepare();
    drmSessionManager.setPlayer(/* playbackLooper= */
    Looper.myLooper(), PlayerId.UNSET);
    DrmSessionReference sessionReference = drmSessionManager.preacquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA);
    // Release the pre-acquired reference before the underlying session has had a chance to be
    // constructed.
    sessionReference.release();
    // Acquiring the same session triggers a second key load (because the pre-acquired session was
    // fully released).
    DrmSession drmSession = checkNotNull(drmSessionManager.acquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA));
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED);
    waitForOpenedWithKeys(drmSession);
    drmSession.release(/* eventDispatcher= */
    null);
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
}
Also used : DrmSessionReference(androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference) FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) Test(org.junit.Test)

Example 4 with DrmSessionReference

use of androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference in project media by androidx.

the class DefaultDrmSessionManagerTest method preacquireSession_loadsKeysBeforeFullAcquisition.

@Test(timeout = 10_000)
public void preacquireSession_loadsKeysBeforeFullAcquisition() throws Exception {
    AtomicInteger keyLoadCount = new AtomicInteger(0);
    DrmSessionEventListener.EventDispatcher eventDispatcher = new DrmSessionEventListener.EventDispatcher();
    eventDispatcher.addEventListener(Util.createHandlerForCurrentLooper(), new DrmSessionEventListener() {

        @Override
        public void onDrmKeysLoaded(int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId) {
            keyLoadCount.incrementAndGet();
        }
    });
    FakeExoMediaDrm.LicenseServer licenseServer = FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS);
    DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()).setSessionKeepaliveMs(C.TIME_UNSET).build(/* mediaDrmCallback= */
    licenseServer);
    drmSessionManager.prepare();
    drmSessionManager.setPlayer(/* playbackLooper= */
    Looper.myLooper(), PlayerId.UNSET);
    DrmSessionReference sessionReference = drmSessionManager.preacquireSession(eventDispatcher, FORMAT_WITH_DRM_INIT_DATA);
    // STATE_OPENED_WITH_KEYS.
    while (keyLoadCount.get() == 0) {
        // Allow the key response to be handled.
        ShadowLooper.idleMainLooper();
    }
    DrmSession drmSession = checkNotNull(drmSessionManager.acquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA));
    // Without idling the main/playback looper, we assert the session is already in OPENED_WITH_KEYS
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
    assertThat(keyLoadCount.get()).isEqualTo(1);
    // After releasing our concrete session reference, the session is held open by the pre-acquired
    // reference.
    drmSession.release(/* eventDispatcher= */
    null);
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
    // Releasing the pre-acquired reference allows the session to be fully released.
    sessionReference.release();
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
}
Also used : FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) DrmSessionReference(androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference) MediaSource(androidx.media3.exoplayer.source.MediaSource) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.Test)

Example 5 with DrmSessionReference

use of androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference in project media by androidx.

the class DefaultDrmSessionManagerTest method preacquireSession_releaseManagerBeforeAcquisition_acquisitionDoesntHappen.

@Test(timeout = 10_000)
public void preacquireSession_releaseManagerBeforeAcquisition_acquisitionDoesntHappen() throws Exception {
    FakeExoMediaDrm.LicenseServer licenseServer = FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS);
    DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()).setSessionKeepaliveMs(C.TIME_UNSET).build(/* mediaDrmCallback= */
    licenseServer);
    drmSessionManager.prepare();
    drmSessionManager.setPlayer(/* playbackLooper= */
    Looper.myLooper(), PlayerId.UNSET);
    DrmSessionReference sessionReference = drmSessionManager.preacquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA);
    // Release the manager before the underlying session has had a chance to be constructed. This
    // will release all pre-acquired sessions.
    drmSessionManager.release();
    // Allow the acquisition event to be handled on the main/playback thread.
    ShadowLooper.idleMainLooper();
    // Re-prepare the manager so we can fully acquire the same session, and check the previous
    // pre-acquisition didn't do anything.
    drmSessionManager.prepare();
    DrmSession drmSession = checkNotNull(drmSessionManager.acquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA));
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED);
    waitForOpenedWithKeys(drmSession);
    drmSession.release(/* eventDispatcher= */
    null);
    // If the (still unreleased) pre-acquired session above was linked to the same underlying
    // session then the state would still be OPENED_WITH_KEYS.
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED);
    // Release the pre-acquired session from above (this is a no-op, but we do it anyway for
    // correctness).
    sessionReference.release();
    drmSessionManager.release();
}
Also used : DrmSessionReference(androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference) FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) Test(org.junit.Test)

Aggregations

DrmSessionReference (androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference)5 FakeExoMediaDrm (androidx.media3.test.utils.FakeExoMediaDrm)4 Test (org.junit.Test)4 MediaSource (androidx.media3.exoplayer.source.MediaSource)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Looper (android.os.Looper)1 Nullable (androidx.annotation.Nullable)1 C (androidx.media3.common.C)1 DrmInitData (androidx.media3.common.DrmInitData)1 Format (androidx.media3.common.Format)1 MimeTypes (androidx.media3.common.MimeTypes)1 Assertions.checkNotNull (androidx.media3.common.util.Assertions.checkNotNull)1 Util (androidx.media3.common.util.Util)1 PlayerId (androidx.media3.exoplayer.analytics.PlayerId)1 AppManagedProvider (androidx.media3.exoplayer.drm.ExoMediaDrm.AppManagedProvider)1 TestUtil (androidx.media3.test.utils.TestUtil)1 AndroidJUnit4 (androidx.test.ext.junit.runners.AndroidJUnit4)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Truth.assertThat (com.google.common.truth.Truth.assertThat)1