Add EventDispatcher to DrmSession(Manager) acquire & release calls
This is passed in but not currently used. I'll use it in follow-up changes. Pre-work for issue:#6765 PiperOrigin-RevId: 299314341
This commit is contained in:
parent
1f4156ce6d
commit
eeab811301
@ -33,6 +33,7 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.EventDispatcher;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
@ -258,7 +259,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acquire() {
|
||||
public void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher) {
|
||||
Assertions.checkState(referenceCount >= 0);
|
||||
if (++referenceCount == 1) {
|
||||
Assertions.checkState(state == STATE_OPENING);
|
||||
@ -272,7 +273,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
public void release(@Nullable MediaSourceEventDispatcher eventDispatcher) {
|
||||
if (--referenceCount == 0) {
|
||||
// Assigning null to various non-null variables for clean-up.
|
||||
state = STATE_RELEASED;
|
||||
@ -288,7 +289,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
if (sessionId != null) {
|
||||
mediaDrm.closeSession(sessionId);
|
||||
sessionId = null;
|
||||
eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmSessionReleased);
|
||||
this.eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmSessionReleased);
|
||||
}
|
||||
releaseCallback.onSessionReleased(this);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.EventDispatcher;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -386,8 +387,8 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
|
||||
/**
|
||||
* Sets the mode, which determines the role of sessions acquired from the instance. This must be
|
||||
* called before {@link #acquireSession(Looper, DrmInitData)} or {@link
|
||||
* #acquirePlaceholderSession} is called.
|
||||
* called before {@link #acquireSession(Looper, MediaSourceEventDispatcher, DrmInitData)} or
|
||||
* {@link #acquirePlaceholderSession} is called.
|
||||
*
|
||||
* <p>By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when
|
||||
* required.
|
||||
@ -490,12 +491,15 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
sessions.add(placeholderDrmSession);
|
||||
this.placeholderDrmSession = placeholderDrmSession;
|
||||
}
|
||||
placeholderDrmSession.acquire();
|
||||
placeholderDrmSession.acquire(/* eventDispatcher= */ null);
|
||||
return placeholderDrmSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
|
||||
public DrmSession<T> acquireSession(
|
||||
Looper playbackLooper,
|
||||
@Nullable MediaSourceEventDispatcher eventDispatcher,
|
||||
DrmInitData drmInitData) {
|
||||
assertExpectedPlaybackLooper(playbackLooper);
|
||||
maybeCreateMediaDrmHandler(playbackLooper);
|
||||
|
||||
@ -504,7 +508,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
schemeDatas = getSchemeDatas(drmInitData, uuid, false);
|
||||
if (schemeDatas.isEmpty()) {
|
||||
final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
|
||||
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
|
||||
this.eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error));
|
||||
return new ErrorStateDrmSession<>(new DrmSessionException(error));
|
||||
}
|
||||
}
|
||||
@ -531,7 +535,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
|
||||
}
|
||||
sessions.add(session);
|
||||
}
|
||||
session.acquire();
|
||||
session.acquire(eventDispatcher);
|
||||
return session;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm;
|
||||
import android.media.MediaDrm;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -30,8 +31,11 @@ import java.util.Map;
|
||||
public interface DrmSession<T extends ExoMediaCrypto> {
|
||||
|
||||
/**
|
||||
* Invokes {@code newSession's} {@link #acquire()} and {@code previousSession's} {@link
|
||||
* #release()} in that order. Null arguments are ignored. Does nothing if {@code previousSession}
|
||||
* Acquires {@code newSession} then releases {@code previousSession}.
|
||||
*
|
||||
* <p>Invokes {@code newSession's} {@link #acquire(MediaSourceEventDispatcher)} and {@code
|
||||
* previousSession's} {@link #release(MediaSourceEventDispatcher)} in that order (passing {@code
|
||||
* eventDispatcher = null}). Null arguments are ignored. Does nothing if {@code previousSession}
|
||||
* and {@code newSession} are the same session.
|
||||
*/
|
||||
static <T extends ExoMediaCrypto> void replaceSession(
|
||||
@ -41,10 +45,10 @@ public interface DrmSession<T extends ExoMediaCrypto> {
|
||||
return;
|
||||
}
|
||||
if (newSession != null) {
|
||||
newSession.acquire();
|
||||
newSession.acquire(/* eventDispatcher= */ null);
|
||||
}
|
||||
if (previousSession != null) {
|
||||
previousSession.release();
|
||||
previousSession.release(/* eventDispatcher= */ null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,13 +136,20 @@ public interface DrmSession<T extends ExoMediaCrypto> {
|
||||
|
||||
/**
|
||||
* Increments the reference count. When the caller no longer needs to use the instance, it must
|
||||
* call {@link #release()} to decrement the reference count.
|
||||
* call {@link #release(MediaSourceEventDispatcher)} to decrement the reference count.
|
||||
*
|
||||
* @param eventDispatcher The {@link MediaSourceEventDispatcher} used to route DRM-related events
|
||||
* dispatched from this session, or null if no event handling is needed.
|
||||
*/
|
||||
void acquire();
|
||||
void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher);
|
||||
|
||||
/**
|
||||
* Decrements the reference count. If the reference count drops to 0 underlying resources are
|
||||
* released, and the instance cannot be re-used.
|
||||
*
|
||||
* @param eventDispatcher The {@link MediaSourceEventDispatcher} to disconnect when the session is
|
||||
* released (the same instance (possibly null) that was passed by the caller to {@link
|
||||
* #acquire(MediaSourceEventDispatcher)}).
|
||||
*/
|
||||
void release();
|
||||
void release(@Nullable MediaSourceEventDispatcher eventDispatcher);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
|
||||
/**
|
||||
* Manages a DRM session.
|
||||
@ -42,7 +43,9 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
|
||||
|
||||
@Override
|
||||
public DrmSession<ExoMediaCrypto> acquireSession(
|
||||
Looper playbackLooper, DrmInitData drmInitData) {
|
||||
Looper playbackLooper,
|
||||
@Nullable MediaSourceEventDispatcher eventDispatcher,
|
||||
DrmInitData drmInitData) {
|
||||
return new ErrorStateDrmSession<>(
|
||||
new DrmSession.DrmSessionException(
|
||||
new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME)));
|
||||
@ -83,7 +86,7 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
|
||||
/**
|
||||
* Returns a {@link DrmSession} that does not execute key requests, with an incremented reference
|
||||
* count. When the caller no longer needs to use the instance, it must call {@link
|
||||
* DrmSession#release()} to decrement the reference count.
|
||||
* DrmSession#release(MediaSourceEventDispatcher)} to decrement the reference count.
|
||||
*
|
||||
* <p>Placeholder {@link DrmSession DrmSessions} may be used to configure secure decoders for
|
||||
* playback of clear content periods. This can reduce the cost of transitioning between clear and
|
||||
@ -103,14 +106,19 @@ public interface DrmSessionManager<T extends ExoMediaCrypto> {
|
||||
/**
|
||||
* Returns a {@link DrmSession} for the specified {@link DrmInitData}, with an incremented
|
||||
* reference count. When the caller no longer needs to use the instance, it must call {@link
|
||||
* DrmSession#release()} to decrement the reference count.
|
||||
* DrmSession#release(MediaSourceEventDispatcher)} to decrement the reference count.
|
||||
*
|
||||
* @param playbackLooper The looper associated with the media playback thread.
|
||||
* @param eventDispatcher The {@link MediaSourceEventDispatcher} used to distribute events, and
|
||||
* passed on to {@link DrmSession#acquire(MediaSourceEventDispatcher)}.
|
||||
* @param drmInitData DRM initialization data. All contained {@link SchemeData}s must contain
|
||||
* non-null {@link SchemeData#data}.
|
||||
* @return The DRM session.
|
||||
*/
|
||||
DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData);
|
||||
DrmSession<T> acquireSession(
|
||||
Looper playbackLooper,
|
||||
@Nullable MediaSourceEventDispatcher eventDispatcher,
|
||||
DrmInitData drmInitData);
|
||||
|
||||
/**
|
||||
* Returns the {@link ExoMediaCrypto} type returned by sessions acquired using the given {@link
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.drm;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import java.util.Map;
|
||||
|
||||
/** A {@link DrmSession} that's in a terminal error state. */
|
||||
@ -63,12 +64,12 @@ public final class ErrorStateDrmSession<T extends ExoMediaCrypto> implements Drm
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acquire() {
|
||||
public void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
public void release(@Nullable MediaSourceEventDispatcher eventDispatcher) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
|
||||
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource.Factory;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -41,6 +41,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
private final ConditionVariable conditionVariable;
|
||||
private final DefaultDrmSessionManager<T> drmSessionManager;
|
||||
private final HandlerThread handlerThread;
|
||||
private final MediaSourceEventDispatcher eventDispatcher;
|
||||
|
||||
/**
|
||||
* Instantiates a new instance which uses Widevine CDM. Call {@link #release()} when the instance
|
||||
@ -49,14 +50,18 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
|
||||
* their own license URL.
|
||||
* @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances.
|
||||
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
|
||||
* events.
|
||||
* @return A new instance which uses Widevine CDM.
|
||||
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
|
||||
* instantiated.
|
||||
*/
|
||||
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
|
||||
String defaultLicenseUrl, Factory httpDataSourceFactory)
|
||||
String defaultLicenseUrl,
|
||||
HttpDataSource.Factory httpDataSourceFactory,
|
||||
MediaSourceEventDispatcher eventDispatcher)
|
||||
throws UnsupportedDrmException {
|
||||
return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, null);
|
||||
return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, eventDispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,15 +73,24 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
* @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that
|
||||
* include their own license URL.
|
||||
* @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances.
|
||||
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
|
||||
* events.
|
||||
* @return A new instance which uses Widevine CDM.
|
||||
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
|
||||
* instantiated.
|
||||
*/
|
||||
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
|
||||
String defaultLicenseUrl, boolean forceDefaultLicenseUrl, Factory httpDataSourceFactory)
|
||||
String defaultLicenseUrl,
|
||||
boolean forceDefaultLicenseUrl,
|
||||
HttpDataSource.Factory httpDataSourceFactory,
|
||||
MediaSourceEventDispatcher eventDispatcher)
|
||||
throws UnsupportedDrmException {
|
||||
return newWidevineInstance(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory,
|
||||
null);
|
||||
return newWidevineInstance(
|
||||
defaultLicenseUrl,
|
||||
forceDefaultLicenseUrl,
|
||||
httpDataSourceFactory,
|
||||
/* optionalKeyRequestParameters= */ null,
|
||||
eventDispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,6 +103,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
* include their own license URL.
|
||||
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
|
||||
* to {@link MediaDrm#getKeyRequest}. May be null.
|
||||
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
|
||||
* events.
|
||||
* @return A new instance which uses Widevine CDM.
|
||||
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
|
||||
* instantiated.
|
||||
@ -97,14 +113,16 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
|
||||
String defaultLicenseUrl,
|
||||
boolean forceDefaultLicenseUrl,
|
||||
Factory httpDataSourceFactory,
|
||||
@Nullable Map<String, String> optionalKeyRequestParameters)
|
||||
HttpDataSource.Factory httpDataSourceFactory,
|
||||
@Nullable Map<String, String> optionalKeyRequestParameters,
|
||||
MediaSourceEventDispatcher eventDispatcher)
|
||||
throws UnsupportedDrmException {
|
||||
return new OfflineLicenseHelper<>(
|
||||
C.WIDEVINE_UUID,
|
||||
FrameworkMediaDrm.DEFAULT_PROVIDER,
|
||||
new HttpMediaDrmCallback(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory),
|
||||
optionalKeyRequestParameters);
|
||||
optionalKeyRequestParameters,
|
||||
eventDispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,6 +133,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
* @param callback Performs key and provisioning requests.
|
||||
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
|
||||
* to {@link MediaDrm#getKeyRequest}. May be null.
|
||||
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
|
||||
* events.
|
||||
* @see DefaultDrmSessionManager.Builder
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -122,7 +142,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
UUID uuid,
|
||||
ExoMediaDrm.Provider<T> mediaDrmProvider,
|
||||
MediaDrmCallback callback,
|
||||
@Nullable Map<String, String> optionalKeyRequestParameters) {
|
||||
@Nullable Map<String, String> optionalKeyRequestParameters,
|
||||
MediaSourceEventDispatcher eventDispatcher) {
|
||||
handlerThread = new HandlerThread("OfflineLicenseHelper");
|
||||
handlerThread.start();
|
||||
conditionVariable = new ConditionVariable();
|
||||
@ -158,6 +179,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
.setKeyRequestParameters(optionalKeyRequestParameters)
|
||||
.build(callback);
|
||||
drmSessionManager.addListener(new Handler(handlerThread.getLooper()), eventListener);
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,7 +238,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
DrmSessionException error = drmSession.getError();
|
||||
Pair<Long, Long> licenseDurationRemainingSec =
|
||||
WidevineUtil.getLicenseDurationRemainingSec(drmSession);
|
||||
drmSession.release();
|
||||
drmSession.release(eventDispatcher);
|
||||
drmSessionManager.release();
|
||||
if (error != null) {
|
||||
if (error.getCause() instanceof KeysExpiredException) {
|
||||
@ -242,7 +264,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
drmInitData);
|
||||
DrmSessionException error = drmSession.getError();
|
||||
byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
|
||||
drmSession.release();
|
||||
drmSession.release(eventDispatcher);
|
||||
drmSessionManager.release();
|
||||
if (error != null) {
|
||||
throw error;
|
||||
@ -254,8 +276,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
|
||||
@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) {
|
||||
drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId);
|
||||
conditionVariable.close();
|
||||
DrmSession<T> drmSession = drmSessionManager.acquireSession(handlerThread.getLooper(),
|
||||
drmInitData);
|
||||
DrmSession<T> drmSession =
|
||||
drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, drmInitData);
|
||||
// Block current thread until key loading is finished
|
||||
conditionVariable.block();
|
||||
return drmSession;
|
||||
|
@ -675,7 +675,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
return sampleQueues[i];
|
||||
}
|
||||
}
|
||||
SampleQueue trackOutput = new SampleQueue(allocator, drmSessionManager);
|
||||
SampleQueue trackOutput = new SampleQueue(allocator, drmSessionManager, eventDispatcher);
|
||||
trackOutput.setUpstreamFormatChangeListener(this);
|
||||
@NullableType
|
||||
TrackId[] sampleQueueTrackIds = Arrays.copyOf(this.sampleQueueTrackIds, trackCount + 1);
|
||||
|
@ -30,6 +30,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataReader;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -55,6 +56,7 @@ public class SampleQueue implements TrackOutput {
|
||||
private final SampleDataQueue sampleDataQueue;
|
||||
private final SampleExtrasHolder extrasHolder;
|
||||
private final DrmSessionManager<?> drmSessionManager;
|
||||
private final MediaSourceEventDispatcher eventDispatcher;
|
||||
@Nullable private UpstreamFormatChangedListener upstreamFormatChangeListener;
|
||||
|
||||
@Nullable private Format downstreamFormat;
|
||||
@ -94,10 +96,16 @@ public class SampleQueue implements TrackOutput {
|
||||
* @param allocator An {@link Allocator} from which allocations for sample data can be obtained.
|
||||
* @param drmSessionManager The {@link DrmSessionManager} to obtain {@link DrmSession DrmSessions}
|
||||
* from. The created instance does not take ownership of this {@link DrmSessionManager}.
|
||||
* @param eventDispatcher A {@link MediaSourceEventDispatcher} to notify of events related to this
|
||||
* SampleQueue.
|
||||
*/
|
||||
public SampleQueue(Allocator allocator, DrmSessionManager<?> drmSessionManager) {
|
||||
public SampleQueue(
|
||||
Allocator allocator,
|
||||
DrmSessionManager<?> drmSessionManager,
|
||||
MediaSourceEventDispatcher eventDispatcher) {
|
||||
sampleDataQueue = new SampleDataQueue(allocator);
|
||||
this.drmSessionManager = drmSessionManager;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
extrasHolder = new SampleExtrasHolder();
|
||||
capacity = SAMPLE_CAPACITY_INCREMENT;
|
||||
sourceIds = new int[capacity];
|
||||
@ -647,7 +655,7 @@ public class SampleQueue implements TrackOutput {
|
||||
|
||||
private void releaseDrmSessionReferences() {
|
||||
if (currentDrmSession != null) {
|
||||
currentDrmSession.release();
|
||||
currentDrmSession.release(eventDispatcher);
|
||||
currentDrmSession = null;
|
||||
// Clear downstream format to avoid violating the assumption that downstreamFormat.drmInitData
|
||||
// != null implies currentSession != null
|
||||
@ -791,13 +799,13 @@ public class SampleQueue implements TrackOutput {
|
||||
Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper());
|
||||
currentDrmSession =
|
||||
newDrmInitData != null
|
||||
? drmSessionManager.acquireSession(playbackLooper, newDrmInitData)
|
||||
? drmSessionManager.acquireSession(playbackLooper, eventDispatcher, newDrmInitData)
|
||||
: drmSessionManager.acquirePlaceholderSession(
|
||||
playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType));
|
||||
outputFormatHolder.drmSession = currentDrmSession;
|
||||
|
||||
if (previousSession != null) {
|
||||
previousSession.release();
|
||||
previousSession.release(eventDispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,13 +131,14 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
int[] trackTypes = new int[1 + embeddedTrackCount];
|
||||
SampleQueue[] sampleQueues = new SampleQueue[1 + embeddedTrackCount];
|
||||
|
||||
primarySampleQueue = new SampleQueue(allocator, drmSessionManager);
|
||||
primarySampleQueue = new SampleQueue(allocator, drmSessionManager, eventDispatcher);
|
||||
trackTypes[0] = primaryTrackType;
|
||||
sampleQueues[0] = primarySampleQueue;
|
||||
|
||||
for (int i = 0; i < embeddedTrackCount; i++) {
|
||||
SampleQueue sampleQueue =
|
||||
new SampleQueue(allocator, DrmSessionManager.getDummyDrmSessionManager());
|
||||
new SampleQueue(
|
||||
allocator, DrmSessionManager.getDummyDrmSessionManager(), eventDispatcher);
|
||||
embeddedSampleQueues[i] = sampleQueue;
|
||||
sampleQueues[i + 1] = sampleQueue;
|
||||
trackTypes[i + 1] = this.embeddedTrackTypes[i];
|
||||
|
@ -25,6 +25,7 @@ import android.util.Pair;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import java.util.HashMap;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -55,7 +56,8 @@ public class OfflineLicenseHelperTest {
|
||||
C.WIDEVINE_UUID,
|
||||
new ExoMediaDrm.AppManagedProvider<>(mediaDrm),
|
||||
mediaDrmCallback,
|
||||
null);
|
||||
/* optionalKeyRequestParameters= */ null,
|
||||
new MediaSourceEventDispatcher());
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -40,6 +40,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
@ -125,6 +126,7 @@ public final class SampleQueueTest {
|
||||
private Allocator allocator;
|
||||
private DrmSessionManager<ExoMediaCrypto> mockDrmSessionManager;
|
||||
private DrmSession<ExoMediaCrypto> mockDrmSession;
|
||||
private MediaSourceEventDispatcher eventDispatcher;
|
||||
private SampleQueue sampleQueue;
|
||||
private FormatHolder formatHolder;
|
||||
private DecoderInputBuffer inputBuffer;
|
||||
@ -136,9 +138,11 @@ public final class SampleQueueTest {
|
||||
mockDrmSessionManager =
|
||||
(DrmSessionManager<ExoMediaCrypto>) Mockito.mock(DrmSessionManager.class);
|
||||
mockDrmSession = (DrmSession<ExoMediaCrypto>) Mockito.mock(DrmSession.class);
|
||||
when(mockDrmSessionManager.acquireSession(ArgumentMatchers.any(), ArgumentMatchers.any()))
|
||||
when(mockDrmSessionManager.acquireSession(
|
||||
ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any()))
|
||||
.thenReturn(mockDrmSession);
|
||||
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager);
|
||||
eventDispatcher = new MediaSourceEventDispatcher();
|
||||
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
|
||||
formatHolder = new FormatHolder();
|
||||
inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
}
|
||||
@ -355,7 +359,7 @@ public final class SampleQueueTest {
|
||||
public void isReadyReturnsTrueForClearSampleAndPlayClearSamplesWithoutKeysIsTrue() {
|
||||
when(mockDrmSession.playClearSamplesWithoutKeys()).thenReturn(true);
|
||||
// We recreate the queue to ensure the mock DRM session manager flags are taken into account.
|
||||
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager);
|
||||
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
|
||||
writeTestDataWithEncryptedSections();
|
||||
assertThat(sampleQueue.isReady(/* loadingFinished= */ false)).isTrue();
|
||||
}
|
||||
@ -535,7 +539,7 @@ public final class SampleQueueTest {
|
||||
public void allowPlayClearSamplesWithoutKeysReadsClearSamples() {
|
||||
when(mockDrmSession.playClearSamplesWithoutKeys()).thenReturn(true);
|
||||
// We recreate the queue to ensure the mock DRM session manager flags are taken into account.
|
||||
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager);
|
||||
sampleQueue = new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher);
|
||||
when(mockDrmSession.getState()).thenReturn(DrmSession.STATE_OPENED);
|
||||
writeTestDataWithEncryptedSections();
|
||||
|
||||
@ -925,7 +929,7 @@ public final class SampleQueueTest {
|
||||
public void adjustUpstreamFormat() {
|
||||
String label = "label";
|
||||
sampleQueue =
|
||||
new SampleQueue(allocator, mockDrmSessionManager) {
|
||||
new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher) {
|
||||
@Override
|
||||
public Format getAdjustedUpstreamFormat(Format format) {
|
||||
return super.getAdjustedUpstreamFormat(copyWithLabel(format, label));
|
||||
@ -941,7 +945,7 @@ public final class SampleQueueTest {
|
||||
public void invalidateUpstreamFormatAdjustment() {
|
||||
AtomicReference<String> label = new AtomicReference<>("label1");
|
||||
sampleQueue =
|
||||
new SampleQueue(allocator, mockDrmSessionManager) {
|
||||
new SampleQueue(allocator, mockDrmSessionManager, eventDispatcher) {
|
||||
@Override
|
||||
public Format getAdjustedUpstreamFormat(Format format) {
|
||||
return super.getAdjustedUpstreamFormat(copyWithLabel(format, label.get()));
|
||||
|
@ -35,6 +35,7 @@ import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataReader;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -284,7 +285,11 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
||||
private final MetadataInputBuffer buffer;
|
||||
|
||||
/* package */ PlayerTrackEmsgHandler(Allocator allocator) {
|
||||
this.sampleQueue = new SampleQueue(allocator, DrmSessionManager.getDummyDrmSessionManager());
|
||||
this.sampleQueue =
|
||||
new SampleQueue(
|
||||
allocator,
|
||||
DrmSessionManager.getDummyDrmSessionManager(),
|
||||
new MediaSourceEventDispatcher());
|
||||
formatHolder = new FormatHolder();
|
||||
buffer = new MetadataInputBuffer();
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -907,7 +908,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
boolean isAudioVideo = type == C.TRACK_TYPE_AUDIO || type == C.TRACK_TYPE_VIDEO;
|
||||
FormatAdjustingSampleQueue trackOutput =
|
||||
new FormatAdjustingSampleQueue(allocator, drmSessionManager, overridingDrmInitData);
|
||||
new FormatAdjustingSampleQueue(
|
||||
allocator, drmSessionManager, eventDispatcher, overridingDrmInitData);
|
||||
if (isAudioVideo) {
|
||||
trackOutput.setDrmInitData(drmInitData);
|
||||
}
|
||||
@ -1348,8 +1350,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
public FormatAdjustingSampleQueue(
|
||||
Allocator allocator,
|
||||
DrmSessionManager<?> drmSessionManager,
|
||||
MediaSourceEventDispatcher eventDispatcher,
|
||||
Map<String, DrmInitData> overridingDrmInitData) {
|
||||
super(allocator, drmSessionManager);
|
||||
super(allocator, drmSessionManager, eventDispatcher);
|
||||
this.overridingDrmInitData = overridingDrmInitData;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import com.google.android.exoplayer2.testutil.ActionSchedule;
|
||||
import com.google.android.exoplayer2.testutil.HostActivity;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -75,8 +76,9 @@ public final class DashWidevineOfflineTest {
|
||||
String widevineLicenseUrl = DashTestData.getWidevineLicenseUrl(true, useL1Widevine);
|
||||
httpDataSourceFactory = new DefaultHttpDataSourceFactory(USER_AGENT);
|
||||
if (Util.SDK_INT >= 18) {
|
||||
offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(widevineLicenseUrl,
|
||||
httpDataSourceFactory);
|
||||
offlineLicenseHelper =
|
||||
OfflineLicenseHelper.newWidevineInstance(
|
||||
widevineLicenseUrl, httpDataSourceFactory, new MediaSourceEventDispatcher());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user