From fb81d629f0ee34a3bd4bb49cc7680d184298c297 Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 4 Feb 2019 19:35:06 +0000 Subject: [PATCH] Merge #5462: Making easier to set the playClearSampleWithoutKeys to renderers Imported from GitHub PR https://github.com/google/ExoPlayer/pull/5462 Pull request for the following issue: #5421 Merge d9d88b079c4ca0533a836b2715a65b924babbb89 into a73819162751116acd3863cf5473b0ff78fac805 PiperOrigin-RevId: 232335113 --- .../exoplayer2/DefaultRenderersFactory.java | 197 +++++++++++++----- .../android/exoplayer2/ExoPlayerFactory.java | 7 +- .../testutil/DebugRenderersFactory.java | 56 +++-- 3 files changed, 195 insertions(+), 65 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java index cc16c43b05..50832dd5af 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2; import android.content.Context; +import android.media.MediaCodec; import android.os.Handler; import android.os.Looper; import android.support.annotation.IntDef; @@ -85,15 +86,18 @@ public class DefaultRenderersFactory implements RenderersFactory { protected static final int MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY = 50; private final Context context; - private final @Nullable DrmSessionManager drmSessionManager; - private final @ExtensionRendererMode int extensionRendererMode; - private final long allowedVideoJoiningTimeMs; + @Nullable private DrmSessionManager drmSessionManager; + @ExtensionRendererMode private int extensionRendererMode; + private long allowedVideoJoiningTimeMs; + private boolean playClearSamplesWithoutKeys; + private MediaCodecSelector mediaCodecSelector; - /** - * @param context A {@link Context}. - */ + /** @param context A {@link Context}. */ public DefaultRenderersFactory(Context context) { - this(context, EXTENSION_RENDERER_MODE_OFF); + this.context = context; + extensionRendererMode = EXTENSION_RENDERER_MODE_OFF; + allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS; + mediaCodecSelector = MediaCodecSelector.DEFAULT; } /** @@ -108,19 +112,20 @@ public class DefaultRenderersFactory implements RenderersFactory { } /** - * @param context A {@link Context}. - * @param extensionRendererMode The extension renderer mode, which determines if and how available - * extension renderers are used. Note that extensions must be included in the application - * build for them to be considered available. + * @deprecated Use {@link #DefaultRenderersFactory(Context)} and {@link + * #setExtensionRendererMode(int)}. */ + @Deprecated + @SuppressWarnings("deprecation") public DefaultRenderersFactory( Context context, @ExtensionRendererMode int extensionRendererMode) { this(context, extensionRendererMode, DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS); } /** - * @deprecated Use {@link #DefaultRenderersFactory(Context, int)} and pass {@link - * DrmSessionManager} directly to {@link SimpleExoPlayer} or {@link ExoPlayerFactory}. + * @deprecated Use {@link #DefaultRenderersFactory(Context)} and {@link + * #setExtensionRendererMode(int)}, and pass {@link DrmSessionManager} directly to {@link + * SimpleExoPlayer} or {@link ExoPlayerFactory}. */ @Deprecated @SuppressWarnings("deprecation") @@ -132,26 +137,22 @@ public class DefaultRenderersFactory implements RenderersFactory { } /** - * @param context A {@link Context}. - * @param extensionRendererMode The extension renderer mode, which determines if and how available - * extension renderers are used. Note that extensions must be included in the application - * build for them to be considered available. - * @param allowedVideoJoiningTimeMs The maximum duration for which video renderers can attempt to - * seamlessly join an ongoing playback. + * @deprecated Use {@link #DefaultRenderersFactory(Context)}, {@link + * #setExtensionRendererMode(int)} and {@link #setAllowedVideoJoiningTimeMs(long)}. */ + @Deprecated + @SuppressWarnings("deprecation") public DefaultRenderersFactory( Context context, @ExtensionRendererMode int extensionRendererMode, long allowedVideoJoiningTimeMs) { - this.context = context; - this.extensionRendererMode = extensionRendererMode; - this.allowedVideoJoiningTimeMs = allowedVideoJoiningTimeMs; - this.drmSessionManager = null; + this(context, null, extensionRendererMode, allowedVideoJoiningTimeMs); } /** - * @deprecated Use {@link #DefaultRenderersFactory(Context, int, long)} and pass {@link - * DrmSessionManager} directly to {@link SimpleExoPlayer} or {@link ExoPlayerFactory}. + * @deprecated Use {@link #DefaultRenderersFactory(Context)}, {@link + * #setExtensionRendererMode(int)} and {@link #setAllowedVideoJoiningTimeMs(long)}, and pass + * {@link DrmSessionManager} directly to {@link SimpleExoPlayer} or {@link ExoPlayerFactory}. */ @Deprecated public DefaultRenderersFactory( @@ -163,6 +164,70 @@ public class DefaultRenderersFactory implements RenderersFactory { this.extensionRendererMode = extensionRendererMode; this.allowedVideoJoiningTimeMs = allowedVideoJoiningTimeMs; this.drmSessionManager = drmSessionManager; + mediaCodecSelector = MediaCodecSelector.DEFAULT; + } + + /** + * Sets the extension renderer mode, which determines if and how available extension renderers are + * used. Note that extensions must be included in the application build for them to be considered + * available. + * + *

The default value is {@link #EXTENSION_RENDERER_MODE_OFF}. + * + * @param extensionRendererMode The extension renderer mode. + * @return This factory, for convenience. + */ + public DefaultRenderersFactory setExtensionRendererMode( + @ExtensionRendererMode int extensionRendererMode) { + this.extensionRendererMode = extensionRendererMode; + return this; + } + + /** + * Sets whether renderers are permitted to play clear regions of encrypted media prior to having + * obtained the keys necessary to decrypt encrypted regions of the media. For encrypted media that + * starts with a short clear region, this allows playback to begin in parallel with key + * acquisition, which can reduce startup latency. + * + *

The default value is {@code false}. + * + * @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of + * encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of + * the media. + * @return This factory, for convenience. + */ + public DefaultRenderersFactory setPlayClearSamplesWithoutKeys( + boolean playClearSamplesWithoutKeys) { + this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys; + return this; + } + + /** + * Sets a {@link MediaCodecSelector} for use by {@link MediaCodec} based renderers. + * + *

The default value is {@link MediaCodecSelector#DEFAULT}. + * + * @param mediaCodecSelector The {@link MediaCodecSelector}. + * @return This factory, for convenience. + */ + public DefaultRenderersFactory setMediaCodecSelector(MediaCodecSelector mediaCodecSelector) { + this.mediaCodecSelector = mediaCodecSelector; + return this; + } + + /** + * Sets the maximum duration for which video renderers can attempt to seamlessly join an ongoing + * playback. + * + *

The default value is {@link #DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS}. + * + * @param allowedVideoJoiningTimeMs The maximum duration for which video renderers can attempt to + * seamlessly join an ongoing playback, in milliseconds. + * @return This factory, for convenience. + */ + public DefaultRenderersFactory setAllowedVideoJoiningTimeMs(long allowedVideoJoiningTimeMs) { + this.allowedVideoJoiningTimeMs = allowedVideoJoiningTimeMs; + return this; } @Override @@ -177,10 +242,26 @@ public class DefaultRenderersFactory implements RenderersFactory { drmSessionManager = this.drmSessionManager; } ArrayList renderersList = new ArrayList<>(); - buildVideoRenderers(context, drmSessionManager, allowedVideoJoiningTimeMs, - eventHandler, videoRendererEventListener, extensionRendererMode, renderersList); - buildAudioRenderers(context, drmSessionManager, buildAudioProcessors(), - eventHandler, audioRendererEventListener, extensionRendererMode, renderersList); + buildVideoRenderers( + context, + extensionRendererMode, + mediaCodecSelector, + drmSessionManager, + playClearSamplesWithoutKeys, + eventHandler, + videoRendererEventListener, + allowedVideoJoiningTimeMs, + renderersList); + buildAudioRenderers( + context, + extensionRendererMode, + mediaCodecSelector, + drmSessionManager, + playClearSamplesWithoutKeys, + buildAudioProcessors(), + eventHandler, + audioRendererEventListener, + renderersList); buildTextRenderers(context, textRendererOutput, eventHandler.getLooper(), extensionRendererMode, renderersList); buildMetadataRenderers(context, metadataRendererOutput, eventHandler.getLooper(), @@ -194,27 +275,36 @@ public class DefaultRenderersFactory implements RenderersFactory { * Builds video renderers for use by the player. * * @param context The {@link Context} associated with the player. - * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the player - * will not be used for DRM protected playbacks. - * @param allowedVideoJoiningTimeMs The maximum duration in milliseconds for which video - * renderers can attempt to seamlessly join an ongoing playback. + * @param extensionRendererMode The extension renderer mode. + * @param mediaCodecSelector A decoder selector. + * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the player will + * not be used for DRM protected playbacks. + * @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of + * encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of + * the media. * @param eventHandler A handler associated with the main thread's looper. * @param eventListener An event listener. - * @param extensionRendererMode The extension renderer mode. + * @param allowedVideoJoiningTimeMs The maximum duration for which video renderers can attempt to + * seamlessly join an ongoing playback, in milliseconds. * @param out An array to which the built renderers should be appended. */ - protected void buildVideoRenderers(Context context, + protected void buildVideoRenderers( + Context context, + @ExtensionRendererMode int extensionRendererMode, + MediaCodecSelector mediaCodecSelector, @Nullable DrmSessionManager drmSessionManager, - long allowedVideoJoiningTimeMs, Handler eventHandler, - VideoRendererEventListener eventListener, @ExtensionRendererMode int extensionRendererMode, + boolean playClearSamplesWithoutKeys, + Handler eventHandler, + VideoRendererEventListener eventListener, + long allowedVideoJoiningTimeMs, ArrayList out) { out.add( new MediaCodecVideoRenderer( context, - MediaCodecSelector.DEFAULT, + mediaCodecSelector, allowedVideoJoiningTimeMs, drmSessionManager, - /* playClearSamplesWithoutKeys= */ false, + playClearSamplesWithoutKeys, eventHandler, eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)); @@ -261,26 +351,35 @@ public class DefaultRenderersFactory implements RenderersFactory { * Builds audio renderers for use by the player. * * @param context The {@link Context} associated with the player. - * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the player - * will not be used for DRM protected playbacks. - * @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio - * buffers before output. May be empty. + * @param extensionRendererMode The extension renderer mode. + * @param mediaCodecSelector A decoder selector. + * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the player will + * not be used for DRM protected playbacks. + * @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of + * encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of + * the media. + * @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio buffers + * before output. May be empty. * @param eventHandler A handler to use when invoking event listeners and outputs. * @param eventListener An event listener. - * @param extensionRendererMode The extension renderer mode. * @param out An array to which the built renderers should be appended. */ - protected void buildAudioRenderers(Context context, + protected void buildAudioRenderers( + Context context, + @ExtensionRendererMode int extensionRendererMode, + MediaCodecSelector mediaCodecSelector, @Nullable DrmSessionManager drmSessionManager, - AudioProcessor[] audioProcessors, Handler eventHandler, - AudioRendererEventListener eventListener, @ExtensionRendererMode int extensionRendererMode, + boolean playClearSamplesWithoutKeys, + AudioProcessor[] audioProcessors, + Handler eventHandler, + AudioRendererEventListener eventListener, ArrayList out) { out.add( new MediaCodecAudioRenderer( context, - MediaCodecSelector.DEFAULT, + mediaCodecSelector, drmSessionManager, - /* playClearSamplesWithoutKeys= */ false, + playClearSamplesWithoutKeys, eventHandler, eventListener, AudioCapabilities.getCapabilities(context), diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java index 81f4285a08..6c2a6f527c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java @@ -97,7 +97,8 @@ public final class ExoPlayerFactory { LoadControl loadControl, @Nullable DrmSessionManager drmSessionManager, @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode) { - RenderersFactory renderersFactory = new DefaultRenderersFactory(context, extensionRendererMode); + RenderersFactory renderersFactory = + new DefaultRenderersFactory(context).setExtensionRendererMode(extensionRendererMode); return newSimpleInstance( context, renderersFactory, trackSelector, loadControl, drmSessionManager); } @@ -127,7 +128,9 @@ public final class ExoPlayerFactory { @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode, long allowedVideoJoiningTimeMs) { RenderersFactory renderersFactory = - new DefaultRenderersFactory(context, extensionRendererMode, allowedVideoJoiningTimeMs); + new DefaultRenderersFactory(context) + .setExtensionRendererMode(extensionRendererMode) + .setAllowedVideoJoiningTimeMs(allowedVideoJoiningTimeMs); return newSimpleInstance( context, renderersFactory, trackSelector, loadControl, drmSessionManager); } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java index 627b5b72f3..4ea2d7d754 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java @@ -20,6 +20,7 @@ import android.content.Context; import android.media.MediaCodec; import android.media.MediaCrypto; import android.os.Handler; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.Format; @@ -37,23 +38,38 @@ import java.util.ArrayList; /** * A debug extension of {@link DefaultRenderersFactory}. Provides a video renderer that performs - * video buffer timestamp assertions. + * video buffer timestamp assertions, and modifies the default value for {@link + * #setAllowedVideoJoiningTimeMs(long)} to be {@code 0}. */ @TargetApi(16) public class DebugRenderersFactory extends DefaultRenderersFactory { public DebugRenderersFactory(Context context) { - super(context, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF, 0); + super(context); + setAllowedVideoJoiningTimeMs(0); } @Override - protected void buildVideoRenderers(Context context, - DrmSessionManager drmSessionManager, long allowedVideoJoiningTimeMs, - Handler eventHandler, VideoRendererEventListener eventListener, - @ExtensionRendererMode int extensionRendererMode, ArrayList out) { - out.add(new DebugMediaCodecVideoRenderer(context, MediaCodecSelector.DEFAULT, - allowedVideoJoiningTimeMs, drmSessionManager, eventHandler, eventListener, - MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)); + protected void buildVideoRenderers( + Context context, + @ExtensionRendererMode int extensionRendererMode, + MediaCodecSelector mediaCodecSelector, + @Nullable DrmSessionManager drmSessionManager, + boolean playClearSamplesWithoutKeys, + Handler eventHandler, + VideoRendererEventListener eventListener, + long allowedVideoJoiningTimeMs, + ArrayList out) { + out.add( + new DebugMediaCodecVideoRenderer( + context, + mediaCodecSelector, + allowedVideoJoiningTimeMs, + drmSessionManager, + playClearSamplesWithoutKeys, + eventHandler, + eventListener, + MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)); } /** @@ -72,12 +88,24 @@ public class DebugRenderersFactory extends DefaultRenderersFactory { private int minimumInsertIndex; private boolean skipToPositionBeforeRenderingFirstFrame; - public DebugMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, - long allowedJoiningTimeMs, DrmSessionManager drmSessionManager, - Handler eventHandler, VideoRendererEventListener eventListener, + public DebugMediaCodecVideoRenderer( + Context context, + MediaCodecSelector mediaCodecSelector, + long allowedJoiningTimeMs, + DrmSessionManager drmSessionManager, + boolean playClearSamplesWithoutKeys, + Handler eventHandler, + VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify) { - super(context, mediaCodecSelector, allowedJoiningTimeMs, drmSessionManager, false, - eventHandler, eventListener, maxDroppedFrameCountToNotify); + super( + context, + mediaCodecSelector, + allowedJoiningTimeMs, + drmSessionManager, + playClearSamplesWithoutKeys, + eventHandler, + eventListener, + maxDroppedFrameCountToNotify); } @Override