Commit 1e12c079 by olly Committed by Oliver Woodman

Move renderer building into a factory class.

To inject custom renderers into SimpleExoPlayer, developers
currently need to extend SimpleExoPlayer and override the
renderer building methods. This is in contrast to the rest
of the library, where we use proper injection. This change
restores consistency. I think it's fine to make
SimpleExoPlayer final again, but if we find people extending
it for non-renderer purposes, we can revert that part of the
change.

ExoPlayerFactory now has analogous methods for the simple
and non-simple cases, which is a nice outcome.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154295726
parent 0f9d9d56
...@@ -31,7 +31,7 @@ import android.widget.LinearLayout; ...@@ -31,7 +31,7 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
...@@ -253,18 +253,21 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -253,18 +253,21 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
} }
} }
@SimpleExoPlayer.ExtensionRendererMode int extensionRendererMode = @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode =
((DemoApplication) getApplication()).useExtensionRenderers() ((DemoApplication) getApplication()).useExtensionRenderers()
? (preferExtensionDecoders ? SimpleExoPlayer.EXTENSION_RENDERER_MODE_PREFER ? (preferExtensionDecoders ? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_ON) : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF; : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this,
drmSessionManager, extensionRendererMode);
TrackSelection.Factory videoTrackSelectionFactory = TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory); trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory);
lastSeenTrackGroupArray = null; lastSeenTrackGroupArray = null;
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(),
drmSessionManager, extensionRendererMode); player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
player.addListener(this); player.addListener(this);
eventLogger = new EventLogger(trackSelector); eventLogger = new EventLogger(trackSelector);
......
...@@ -26,12 +26,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelector; ...@@ -26,12 +26,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelector;
*/ */
public final class ExoPlayerFactory { public final class ExoPlayerFactory {
/**
* The default maximum duration for which a video renderer can attempt to seamlessly join an
* ongoing playback.
*/
public static final long DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS = 5000;
private ExoPlayerFactory() {} private ExoPlayerFactory() {}
/** /**
...@@ -41,10 +35,13 @@ public final class ExoPlayerFactory { ...@@ -41,10 +35,13 @@ public final class ExoPlayerFactory {
* @param context A {@link Context}. * @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance. * @param loadControl The {@link LoadControl} that will be used by the instance.
* @deprecated Use {@link #newSimpleInstance(RenderersFactory, TrackSelector, LoadControl)}.
*/ */
@Deprecated
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector, public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl) { LoadControl loadControl) {
return newSimpleInstance(context, trackSelector, loadControl, null); RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
return newSimpleInstance(renderersFactory, trackSelector, loadControl);
} }
/** /**
...@@ -56,11 +53,13 @@ public final class ExoPlayerFactory { ...@@ -56,11 +53,13 @@ public final class ExoPlayerFactory {
* @param loadControl The {@link LoadControl} that will be used by the instance. * @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks. * will not be used for DRM protected playbacks.
* @deprecated Use {@link #newSimpleInstance(RenderersFactory, TrackSelector, LoadControl)}.
*/ */
@Deprecated
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector, public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) { LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
return newSimpleInstance(context, trackSelector, loadControl, RenderersFactory renderersFactory = new DefaultRenderersFactory(context, drmSessionManager);
drmSessionManager, SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF); return newSimpleInstance(renderersFactory, trackSelector, loadControl);
} }
/** /**
...@@ -75,12 +74,15 @@ public final class ExoPlayerFactory { ...@@ -75,12 +74,15 @@ public final class ExoPlayerFactory {
* @param extensionRendererMode The extension renderer mode, which determines if and how available * @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 * extension renderers are used. Note that extensions must be included in the application
* build for them to be considered available. * build for them to be considered available.
* @deprecated Use {@link #newSimpleInstance(RenderersFactory, TrackSelector, LoadControl)}.
*/ */
@Deprecated
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector, public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
@SimpleExoPlayer.ExtensionRendererMode int extensionRendererMode) { @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode) {
return newSimpleInstance(context, trackSelector, loadControl, drmSessionManager, RenderersFactory renderersFactory = new DefaultRenderersFactory(context, drmSessionManager,
extensionRendererMode, DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS); extensionRendererMode);
return newSimpleInstance(renderersFactory, trackSelector, loadControl);
} }
/** /**
...@@ -97,13 +99,52 @@ public final class ExoPlayerFactory { ...@@ -97,13 +99,52 @@ public final class ExoPlayerFactory {
* build for them to be considered available. * build for them to be considered available.
* @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to * @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to
* seamlessly join an ongoing playback. * seamlessly join an ongoing playback.
* @deprecated Use {@link #newSimpleInstance(RenderersFactory, TrackSelector, LoadControl)}.
*/ */
@Deprecated
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector, public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
@SimpleExoPlayer.ExtensionRendererMode int extensionRendererMode, @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode,
long allowedVideoJoiningTimeMs) { long allowedVideoJoiningTimeMs) {
return new SimpleExoPlayer(context, trackSelector, loadControl, drmSessionManager, RenderersFactory renderersFactory = new DefaultRenderersFactory(context, drmSessionManager,
extensionRendererMode, allowedVideoJoiningTimeMs); extensionRendererMode, allowedVideoJoiningTimeMs);
return newSimpleInstance(renderersFactory, trackSelector, loadControl);
}
/**
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
*/
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector) {
return newSimpleInstance(new DefaultRenderersFactory(context), trackSelector);
}
/**
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
*/
public static SimpleExoPlayer newSimpleInstance(RenderersFactory renderersFactory,
TrackSelector trackSelector) {
return newSimpleInstance(renderersFactory, trackSelector, new DefaultLoadControl());
}
/**
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
*/
public static SimpleExoPlayer newSimpleInstance(RenderersFactory renderersFactory,
TrackSelector trackSelector, LoadControl loadControl) {
return new SimpleExoPlayer(renderersFactory, trackSelector, loadControl);
} }
/** /**
......
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import android.os.Handler;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.metadata.MetadataRenderer;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
/**
* Builds {@link Renderer} instances for use by a {@link SimpleExoPlayer}.
*/
public interface RenderersFactory {
/**
* Builds the {@link Renderer} instances for a {@link SimpleExoPlayer}.
*
* @param eventHandler A handler to use when invoking event listeners and outputs.
* @param videoRendererEventListener An event listener for video renderers.
* @param videoRendererEventListener An event listener for audio renderers.
* @param textRendererOutput An output for text renderers.
* @param metadataRendererOutput An output for metadata renderers.
* @return The {@link Renderer instances}.
*/
Renderer[] createRenderers(Handler eventHandler,
VideoRendererEventListener videoRendererEventListener,
AudioRendererEventListener audioRendererEventListener,
TextRenderer.Output textRendererOutput, MetadataRenderer.Output metadataRendererOutput);
}
...@@ -25,8 +25,8 @@ import android.net.Uri; ...@@ -25,8 +25,8 @@ import android.net.Uri;
import android.util.Log; import android.util.Log;
import android.view.Surface; import android.view.Surface;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
...@@ -39,7 +39,7 @@ import com.google.android.exoplayer2.drm.MediaDrmCallback; ...@@ -39,7 +39,7 @@ import com.google.android.exoplayer2.drm.MediaDrmCallback;
import com.google.android.exoplayer2.drm.UnsupportedDrmException; import com.google.android.exoplayer2.drm.UnsupportedDrmException;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
import com.google.android.exoplayer2.playbacktests.util.ActionSchedule; import com.google.android.exoplayer2.playbacktests.util.ActionSchedule;
import com.google.android.exoplayer2.playbacktests.util.DebugSimpleExoPlayer; import com.google.android.exoplayer2.playbacktests.util.DebugRenderersFactory;
import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil; import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil;
import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest; import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest;
import com.google.android.exoplayer2.playbacktests.util.HostActivity; import com.google.android.exoplayer2.playbacktests.util.HostActivity;
...@@ -296,8 +296,8 @@ public final class DashTestRunner { ...@@ -296,8 +296,8 @@ public final class DashTestRunner {
protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface, protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface,
MappingTrackSelector trackSelector, MappingTrackSelector trackSelector,
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) { DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
SimpleExoPlayer player = new DebugSimpleExoPlayer(host, trackSelector, SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultLoadControl(), drmSessionManager); new DebugRenderersFactory(host, drmSessionManager), trackSelector);
player.setVideoSurface(surface); player.setVideoSurface(surface);
return player; return player;
} }
......
...@@ -18,39 +18,37 @@ package com.google.android.exoplayer2.playbacktests.util; ...@@ -18,39 +18,37 @@ package com.google.android.exoplayer2.playbacktests.util;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector; import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer; import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoRendererEventListener; import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
* A debug extension of {@link SimpleExoPlayer}. Provides video buffer timestamp assertions. * A debug extension of {@link DefaultRenderersFactory}. Provides a video renderer that performs
* video buffer timestamp assertions.
*/ */
@TargetApi(16) @TargetApi(16)
public class DebugSimpleExoPlayer extends SimpleExoPlayer { public class DebugRenderersFactory extends DefaultRenderersFactory {
public DebugSimpleExoPlayer(Context context, TrackSelector trackSelector, public DebugRenderersFactory(Context context,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) { DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
super(context, trackSelector, loadControl, drmSessionManager, super(context, drmSessionManager, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF, 0);
SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF, 0);
} }
@Override @Override
protected void buildVideoRenderers(Context context, Handler mainHandler, protected void buildVideoRenderers(Context context,
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, long allowedVideoJoiningTimeMs,
@ExtensionRendererMode int extensionRendererMode, VideoRendererEventListener eventListener, Handler eventHandler, VideoRendererEventListener eventListener,
long allowedVideoJoiningTimeMs, ArrayList<Renderer> out) { @ExtensionRendererMode int extensionRendererMode, ArrayList<Renderer> out) {
out.add(new DebugMediaCodecVideoRenderer(context, MediaCodecSelector.DEFAULT, out.add(new DebugMediaCodecVideoRenderer(context, MediaCodecSelector.DEFAULT,
allowedVideoJoiningTimeMs, mainHandler, drmSessionManager, eventListener, allowedVideoJoiningTimeMs, drmSessionManager, eventHandler, eventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)); MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
} }
...@@ -70,9 +68,9 @@ public class DebugSimpleExoPlayer extends SimpleExoPlayer { ...@@ -70,9 +68,9 @@ public class DebugSimpleExoPlayer extends SimpleExoPlayer {
private int minimumInsertIndex; private int minimumInsertIndex;
public DebugMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, public DebugMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
long allowedJoiningTimeMs, Handler eventHandler, long allowedJoiningTimeMs, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, Handler eventHandler, VideoRendererEventListener eventListener,
VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify) { int maxDroppedFrameCountToNotify) {
super(context, mediaCodecSelector, allowedJoiningTimeMs, drmSessionManager, false, super(context, mediaCodecSelector, allowedJoiningTimeMs, drmSessionManager, false,
eventHandler, eventListener, maxDroppedFrameCountToNotify); eventHandler, eventListener, maxDroppedFrameCountToNotify);
} }
......
...@@ -19,12 +19,13 @@ import android.os.Handler; ...@@ -19,12 +19,13 @@ import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.view.Surface; import android.view.Surface;
import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
...@@ -326,9 +327,9 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -326,9 +327,9 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface, protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface,
MappingTrackSelector trackSelector, MappingTrackSelector trackSelector,
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) { DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(host, trackSelector, RenderersFactory renderersFactory = new DefaultRenderersFactory(host, drmSessionManager,
new DefaultLoadControl(), drmSessionManager, SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF, 0);
0); SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
player.setVideoSurface(surface); player.setVideoSurface(surface);
return player; return player;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment