Commit 6aab2bdc by tonihei Committed by Oliver Woodman

Set bandwidth meter at player level.

This bandwidth meter is then forwarded to the track selection and as a transfer
listener to media and data sources.

When no bandwidth meter is specified in the ExoPlayerFactory methods, a static
singleton instance will be used.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=204881497
parent 74dadae5
......@@ -28,14 +28,18 @@
* Add support for lazy preparation of playlist media sources in
`ConcatenatingMediaSource`
([#3972](https://github.com/google/ExoPlayer/issues/3972)).
* `BandwidthMeter` management (work in progress):
* `BandwidthMeter` management:
* Pass `BandwidthMeter` directly to `ExoPlayerFactory` instead of
`TrackSelection.Factory` and `DataSource.Factory`. May also be omitted to
use the default bandwidth meter automatically. This change only works
correctly if the following changes are adopted for custom `BandwidthMeter`s,
`TrackSelection`s, `MediaSource`s and `DataSource`s.
* Pass `BandwidthMeter` to `TrackSelection.Factory` which can be used to
obtain bandwidth estimates in the future. Always null at the moment.
obtain bandwidth estimates.
* Add method to `BandwidthMeter` to return the `TransferListener` used to
gather bandwidth information. Also add methods to add and remove event
listeners.
* Pass `TransferListener` to `MediaSource`s to listen to media data transfers.
Always null at the moment.
* Add method to `DataSource` to add `TransferListener`s. Custom `DataSource`s
directly reading data should implement `BaseDataSource` to handle the
registration correctly. Custom `DataSource`'s forwarding to other sources
......
......@@ -22,6 +22,8 @@ import com.google.android.exoplayer2.analytics.AnalyticsCollector;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.Util;
......@@ -30,6 +32,8 @@ import com.google.android.exoplayer2.util.Util;
*/
public final class ExoPlayerFactory {
private static @Nullable BandwidthMeter singletonBandwidthMeter;
private ExoPlayerFactory() {}
/**
......@@ -157,7 +161,7 @@ public final class ExoPlayerFactory {
*/
public static SimpleExoPlayer newSimpleInstance(RenderersFactory renderersFactory,
TrackSelector trackSelector, LoadControl loadControl) {
return new SimpleExoPlayer(
return newSimpleInstance(
renderersFactory,
trackSelector,
loadControl,
......@@ -179,7 +183,7 @@ public final class ExoPlayerFactory {
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
return new SimpleExoPlayer(
return newSimpleInstance(
renderersFactory, trackSelector, loadControl, drmSessionManager, Util.getLooper());
}
......@@ -191,6 +195,32 @@ public final class ExoPlayerFactory {
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
*/
public static SimpleExoPlayer newSimpleInstance(
RenderersFactory renderersFactory,
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
BandwidthMeter bandwidthMeter) {
return newSimpleInstance(
renderersFactory,
trackSelector,
loadControl,
drmSessionManager,
bandwidthMeter,
new AnalyticsCollector.Factory(),
Util.getLooper());
}
/**
* Creates a {@link SimpleExoPlayer} instance.
*
* @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.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that
* will collect and forward all player events.
*/
......@@ -200,7 +230,7 @@ public final class ExoPlayerFactory {
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
AnalyticsCollector.Factory analyticsCollectorFactory) {
return new SimpleExoPlayer(
return newSimpleInstance(
renderersFactory,
trackSelector,
loadControl,
......@@ -226,8 +256,43 @@ public final class ExoPlayerFactory {
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
Looper looper) {
return new SimpleExoPlayer(
renderersFactory, trackSelector, loadControl, drmSessionManager, looper);
return newSimpleInstance(
renderersFactory,
trackSelector,
loadControl,
drmSessionManager,
new AnalyticsCollector.Factory(),
looper);
}
/**
* Creates a {@link SimpleExoPlayer} instance.
*
* @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.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that
* will collect and forward all player events.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
*/
public static SimpleExoPlayer newSimpleInstance(
RenderersFactory renderersFactory,
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
AnalyticsCollector.Factory analyticsCollectorFactory,
Looper looper) {
return newSimpleInstance(
renderersFactory,
trackSelector,
loadControl,
drmSessionManager,
getDefaultBandwidthMeter(),
analyticsCollectorFactory,
looper);
}
/**
......@@ -248,6 +313,7 @@ public final class ExoPlayerFactory {
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
BandwidthMeter bandwidthMeter,
AnalyticsCollector.Factory analyticsCollectorFactory,
Looper looper) {
return new SimpleExoPlayer(
......@@ -255,6 +321,7 @@ public final class ExoPlayerFactory {
trackSelector,
loadControl,
drmSessionManager,
bandwidthMeter,
analyticsCollectorFactory,
looper);
}
......@@ -292,6 +359,33 @@ public final class ExoPlayerFactory {
*/
public static ExoPlayer newInstance(
Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl, Looper looper) {
return new ExoPlayerImpl(renderers, trackSelector, loadControl, Clock.DEFAULT, looper);
return newInstance(renderers, trackSelector, loadControl, getDefaultBandwidthMeter(), looper);
}
/**
* Creates an {@link ExoPlayer} instance.
*
* @param renderers The {@link Renderer}s 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 bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
*/
public static ExoPlayer newInstance(
Renderer[] renderers,
TrackSelector trackSelector,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
Looper looper) {
return new ExoPlayerImpl(
renderers, trackSelector, loadControl, bandwidthMeter, Clock.DEFAULT, looper);
}
private static synchronized BandwidthMeter getDefaultBandwidthMeter() {
if (singletonBandwidthMeter == null) {
singletonBandwidthMeter = new DefaultBandwidthMeter.Builder().build();
}
return singletonBandwidthMeter;
}
}
......@@ -30,6 +30,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.Util;
......@@ -81,6 +82,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
* @param renderers The {@link Renderer}s 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 bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
* @param clock The {@link Clock} that will be used by the instance.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
......@@ -90,6 +92,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
Renderer[] renderers,
TrackSelector trackSelector,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
Clock clock,
Looper looper) {
Log.i(TAG, "Init " + Integer.toHexString(System.identityHashCode(this)) + " ["
......@@ -130,6 +133,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
trackSelector,
emptyTrackSelectorResult,
loadControl,
bandwidthMeter,
playWhenReady,
repeatMode,
shuffleModeEnabled,
......
......@@ -35,6 +35,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.HandlerWrapper;
......@@ -87,6 +88,7 @@ import java.util.Collections;
private final TrackSelector trackSelector;
private final TrackSelectorResult emptyTrackSelectorResult;
private final LoadControl loadControl;
private final BandwidthMeter bandwidthMeter;
private final HandlerWrapper handler;
private final HandlerThread internalPlaybackThread;
private final Handler eventHandler;
......@@ -123,6 +125,7 @@ import java.util.Collections;
TrackSelector trackSelector,
TrackSelectorResult emptyTrackSelectorResult,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
boolean playWhenReady,
@Player.RepeatMode int repeatMode,
boolean shuffleModeEnabled,
......@@ -133,6 +136,7 @@ import java.util.Collections;
this.trackSelector = trackSelector;
this.emptyTrackSelectorResult = emptyTrackSelectorResult;
this.loadControl = loadControl;
this.bandwidthMeter = bandwidthMeter;
this.playWhenReady = playWhenReady;
this.repeatMode = repeatMode;
this.shuffleModeEnabled = shuffleModeEnabled;
......@@ -162,7 +166,7 @@ import java.util.Collections;
enabledRenderers = new Renderer[0];
window = new Timeline.Window();
period = new Timeline.Period();
trackSelector.init(/* listener= */ this, /* bandwidthMeter= */ null);
trackSelector.init(/* listener= */ this, bandwidthMeter);
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
// not normally change to this priority" is incorrect.
......@@ -397,7 +401,7 @@ import java.util.Collections;
player,
/* isTopLevelSource= */ true,
/* listener= */ this,
/* mediaTransferListener= */ null);
bandwidthMeter.getTransferListener());
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
......
......@@ -45,6 +45,7 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
......@@ -100,22 +101,10 @@ public class SimpleExoPlayer
private List<Cue> currentCues;
/**
* @deprecated Use {@link #SimpleExoPlayer(RenderersFactory, TrackSelector, LoadControl,
* DrmSessionManager, Looper)}.
*/
@Deprecated
protected SimpleExoPlayer(
RenderersFactory renderersFactory,
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
this(renderersFactory, trackSelector, loadControl, drmSessionManager, Util.getLooper());
}
/**
* @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.
* @param bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
......@@ -125,6 +114,7 @@ public class SimpleExoPlayer
RenderersFactory renderersFactory,
TrackSelector trackSelector,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
Looper looper) {
this(
......@@ -132,6 +122,7 @@ public class SimpleExoPlayer
trackSelector,
loadControl,
drmSessionManager,
bandwidthMeter,
new AnalyticsCollector.Factory(),
looper);
}
......@@ -142,6 +133,7 @@ public class SimpleExoPlayer
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
* @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that
* will collect and forward all player events.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
......@@ -152,6 +144,7 @@ public class SimpleExoPlayer
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
BandwidthMeter bandwidthMeter,
AnalyticsCollector.Factory analyticsCollectorFactory,
Looper looper) {
this(
......@@ -159,6 +152,7 @@ public class SimpleExoPlayer
trackSelector,
loadControl,
drmSessionManager,
bandwidthMeter,
analyticsCollectorFactory,
Clock.DEFAULT,
looper);
......@@ -170,6 +164,7 @@ public class SimpleExoPlayer
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
* @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that
* will collect and forward all player events.
* @param clock The {@link Clock} that will be used by the instance. Should always be {@link
......@@ -182,6 +177,7 @@ public class SimpleExoPlayer
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
BandwidthMeter bandwidthMeter,
AnalyticsCollector.Factory analyticsCollectorFactory,
Clock clock,
Looper looper) {
......@@ -210,7 +206,8 @@ public class SimpleExoPlayer
currentCues = Collections.emptyList();
// Build the player and associated objects.
player = createExoPlayerImpl(renderers, trackSelector, loadControl, clock, looper);
player =
createExoPlayerImpl(renderers, trackSelector, loadControl, bandwidthMeter, clock, looper);
analyticsCollector = analyticsCollectorFactory.createAnalyticsCollector(player, clock);
addListener(analyticsCollector);
videoDebugListeners.add(analyticsCollector);
......@@ -993,6 +990,7 @@ public class SimpleExoPlayer
* @param renderers The {@link Renderer}s 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 bandwidthMeter The {@link BandwidthMeter} that will be used by the instance.
* @param clock The {@link Clock} that will be used by this instance.
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
......@@ -1002,9 +1000,10 @@ public class SimpleExoPlayer
Renderer[] renderers,
TrackSelector trackSelector,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
Clock clock,
Looper looper) {
return new ExoPlayerImpl(renderers, trackSelector, loadControl, clock, looper);
return new ExoPlayerImpl(renderers, trackSelector, loadControl, bandwidthMeter, clock, looper);
}
private void removeSurfaceCallbacks() {
......
......@@ -41,6 +41,7 @@ import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.HandlerWrapper;
import com.google.android.exoplayer2.util.MimeTypes;
......@@ -660,6 +661,7 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
trackSelector,
loadControl,
/* drmSessionManager= */ null,
new DefaultBandwidthMeter.Builder().build(),
new AnalyticsCollector.Factory(),
clock,
Looper.myLooper());
......
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