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