mirror of
https://github.com/samsonjs/media.git
synced 2026-04-24 14:37:45 +00:00
Make context non-optional for DefaultBandwidthMeter
- Added ability to override the DefaultBandwidthMeter network type. - These methods currently only work properly if called before the meter is used, but the plan is for them to be handled in the same way as internally detected network changes. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=217887019
This commit is contained in:
parent
4c6507e7a0
commit
ca4b5d0a0d
8 changed files with 115 additions and 99 deletions
|
|
@ -18,6 +18,8 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.google.android.exoplayer2.ext.flac.test">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<application android:debuggable="true"
|
||||
android:allowBackup="false"
|
||||
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class FlacPlaybackTest {
|
|||
Looper.prepare();
|
||||
LibflacAudioRenderer audioRenderer = new LibflacAudioRenderer();
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
|
||||
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
|
||||
player = ExoPlayerFactory.newInstance(context, new Renderer[] {audioRenderer}, trackSelector);
|
||||
player.addListener(this);
|
||||
MediaSource mediaSource =
|
||||
new ExtractorMediaSource.Factory(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.google.android.exoplayer2.ext.opus.test">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<application android:debuggable="true"
|
||||
android:allowBackup="false"
|
||||
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class OpusPlaybackTest {
|
|||
Looper.prepare();
|
||||
LibopusAudioRenderer audioRenderer = new LibopusAudioRenderer();
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
|
||||
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
|
||||
player = ExoPlayerFactory.newInstance(context, new Renderer[] {audioRenderer}, trackSelector);
|
||||
player.addListener(this);
|
||||
MediaSource mediaSource =
|
||||
new ExtractorMediaSource.Factory(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.google.android.exoplayer2.ext.vp9.test">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<application android:debuggable="true"
|
||||
android:allowBackup="false"
|
||||
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public class VpxPlaybackTest {
|
|||
Looper.prepare();
|
||||
LibvpxVideoRenderer videoRenderer = new LibvpxVideoRenderer(true, 0);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
|
||||
player = ExoPlayerFactory.newInstance(new Renderer[] {videoRenderer}, trackSelector);
|
||||
player = ExoPlayerFactory.newInstance(context, new Renderer[] {videoRenderer}, trackSelector);
|
||||
player.addListener(this);
|
||||
MediaSource mediaSource =
|
||||
new ExtractorMediaSource.Factory(
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import android.content.Context;
|
|||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
|
|
@ -38,44 +37,6 @@ public final class ExoPlayerFactory {
|
|||
|
||||
private ExoPlayerFactory() {}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
|
||||
* @param loadControl The {@link LoadControl} that will be used by the instance.
|
||||
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
|
||||
* LoadControl)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SimpleExoPlayer newSimpleInstance(
|
||||
Context context, TrackSelector trackSelector, LoadControl loadControl) {
|
||||
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
|
||||
return newSimpleInstance(context, renderersFactory, trackSelector, loadControl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance. Available extension renderers are not used.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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.
|
||||
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
|
||||
* LoadControl)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SimpleExoPlayer newSimpleInstance(
|
||||
Context context,
|
||||
TrackSelector trackSelector,
|
||||
LoadControl loadControl,
|
||||
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
|
||||
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
|
||||
return newSimpleInstance(
|
||||
context, renderersFactory, trackSelector, loadControl, drmSessionManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance.
|
||||
*
|
||||
|
|
@ -88,7 +49,7 @@ public final class ExoPlayerFactory {
|
|||
* extension renderers are used. Note that extensions must be included in the application
|
||||
* build for them to be considered available.
|
||||
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
|
||||
* LoadControl)}.
|
||||
* LoadControl, DrmSessionManager)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SimpleExoPlayer newSimpleInstance(
|
||||
|
|
@ -116,7 +77,7 @@ public final class ExoPlayerFactory {
|
|||
* @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to
|
||||
* seamlessly join an ongoing playback.
|
||||
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
|
||||
* LoadControl)}.
|
||||
* LoadControl, DrmSessionManager)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SimpleExoPlayer newSimpleInstance(
|
||||
|
|
@ -151,23 +112,6 @@ public final class ExoPlayerFactory {
|
|||
return newSimpleInstance(context, new DefaultRenderersFactory(context), trackSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector)}. The use
|
||||
* of {@link SimpleExoPlayer#setAudioAttributes(AudioAttributes, boolean)} to manage audio
|
||||
* focus will be unavailable for the {@link SimpleExoPlayer} returned by this method.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("nullness:argument.type.incompatible")
|
||||
public static SimpleExoPlayer newSimpleInstance(
|
||||
RenderersFactory renderersFactory, TrackSelector trackSelector) {
|
||||
return newSimpleInstance(
|
||||
/* context= */ null, renderersFactory, trackSelector, new DefaultLoadControl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance.
|
||||
*
|
||||
|
|
@ -180,6 +124,38 @@ public final class ExoPlayerFactory {
|
|||
return newSimpleInstance(context, renderersFactory, trackSelector, new DefaultLoadControl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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(
|
||||
Context context, TrackSelector trackSelector, LoadControl loadControl) {
|
||||
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
|
||||
return newSimpleInstance(context, renderersFactory, trackSelector, loadControl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance. Available extension renderers are not used.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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.
|
||||
*/
|
||||
public static SimpleExoPlayer newSimpleInstance(
|
||||
Context context,
|
||||
TrackSelector trackSelector,
|
||||
LoadControl loadControl,
|
||||
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
|
||||
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
|
||||
return newSimpleInstance(
|
||||
context, renderersFactory, trackSelector, loadControl, drmSessionManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SimpleExoPlayer} instance.
|
||||
*
|
||||
|
|
@ -355,7 +331,7 @@ public final class ExoPlayerFactory {
|
|||
trackSelector,
|
||||
loadControl,
|
||||
drmSessionManager,
|
||||
getDefaultBandwidthMeter(),
|
||||
getDefaultBandwidthMeter(context),
|
||||
analyticsCollectorFactory,
|
||||
looper);
|
||||
}
|
||||
|
|
@ -397,28 +373,32 @@ public final class ExoPlayerFactory {
|
|||
/**
|
||||
* Creates an {@link ExoPlayer} instance.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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.
|
||||
*/
|
||||
public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector) {
|
||||
return newInstance(renderers, trackSelector, new DefaultLoadControl());
|
||||
public static ExoPlayer newInstance(
|
||||
Context context, Renderer[] renderers, TrackSelector trackSelector) {
|
||||
return newInstance(context, renderers, trackSelector, new DefaultLoadControl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link ExoPlayer} instance.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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.
|
||||
*/
|
||||
public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector,
|
||||
LoadControl loadControl) {
|
||||
return newInstance(renderers, trackSelector, loadControl, Util.getLooper());
|
||||
public static ExoPlayer newInstance(
|
||||
Context context, Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl) {
|
||||
return newInstance(context, renderers, trackSelector, loadControl, Util.getLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link ExoPlayer} instance.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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.
|
||||
|
|
@ -426,13 +406,19 @@ public final class ExoPlayerFactory {
|
|||
* used to call listeners on.
|
||||
*/
|
||||
public static ExoPlayer newInstance(
|
||||
Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl, Looper looper) {
|
||||
return newInstance(renderers, trackSelector, loadControl, getDefaultBandwidthMeter(), looper);
|
||||
Context context,
|
||||
Renderer[] renderers,
|
||||
TrackSelector trackSelector,
|
||||
LoadControl loadControl,
|
||||
Looper looper) {
|
||||
return newInstance(
|
||||
context, renderers, trackSelector, loadControl, getDefaultBandwidthMeter(context), looper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link ExoPlayer} instance.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @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.
|
||||
|
|
@ -440,7 +426,9 @@ public final class ExoPlayerFactory {
|
|||
* @param looper The {@link Looper} which must be used for all calls to the player and which is
|
||||
* used to call listeners on.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static ExoPlayer newInstance(
|
||||
Context context,
|
||||
Renderer[] renderers,
|
||||
TrackSelector trackSelector,
|
||||
LoadControl loadControl,
|
||||
|
|
@ -450,9 +438,9 @@ public final class ExoPlayerFactory {
|
|||
renderers, trackSelector, loadControl, bandwidthMeter, Clock.DEFAULT, looper);
|
||||
}
|
||||
|
||||
private static synchronized BandwidthMeter getDefaultBandwidthMeter() {
|
||||
private static synchronized BandwidthMeter getDefaultBandwidthMeter(Context context) {
|
||||
if (singletonBandwidthMeter == null) {
|
||||
singletonBandwidthMeter = new DefaultBandwidthMeter.Builder().build();
|
||||
singletonBandwidthMeter = new DefaultBandwidthMeter.Builder(context).build();
|
||||
}
|
||||
return singletonBandwidthMeter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,18 +82,13 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
|
|||
private int slidingWindowMaxWeight;
|
||||
private Clock clock;
|
||||
|
||||
/** @deprecated Use {@link #Builder(Context)} instead. */
|
||||
@Deprecated
|
||||
public Builder() {
|
||||
this(/* context= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder with default parameters and without listener.
|
||||
*
|
||||
* @param context A context.
|
||||
*/
|
||||
public Builder(@Nullable Context context) {
|
||||
public Builder(Context context) {
|
||||
// Handling of null is for backward compatibility only.
|
||||
this.context = context == null ? null : context.getApplicationContext();
|
||||
initialBitrateEstimates = getInitialBitrateEstimatesForCountry(Util.getCountryCode(context));
|
||||
slidingWindowMaxWeight = DEFAULT_SLIDING_WINDOW_MAX_WEIGHT;
|
||||
|
|
@ -187,14 +182,9 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
|
|||
* @return A bandwidth meter with the configured properties.
|
||||
*/
|
||||
public DefaultBandwidthMeter build() {
|
||||
Long initialBitrateEstimate =
|
||||
initialBitrateEstimates.get(
|
||||
context == null ? C.NETWORK_TYPE_UNKNOWN : Util.getNetworkType(context));
|
||||
if (initialBitrateEstimate == null) {
|
||||
initialBitrateEstimate = initialBitrateEstimates.get(C.NETWORK_TYPE_UNKNOWN);
|
||||
}
|
||||
DefaultBandwidthMeter bandwidthMeter =
|
||||
new DefaultBandwidthMeter(initialBitrateEstimate, slidingWindowMaxWeight, clock);
|
||||
new DefaultBandwidthMeter(
|
||||
context, initialBitrateEstimates, slidingWindowMaxWeight, clock);
|
||||
if (eventHandler != null && eventListener != null) {
|
||||
bandwidthMeter.addEventListener(eventHandler, eventListener);
|
||||
}
|
||||
|
|
@ -225,6 +215,7 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
|
|||
private static final int ELAPSED_MILLIS_FOR_ESTIMATE = 2000;
|
||||
private static final int BYTES_TRANSFERRED_FOR_ESTIMATE = 512 * 1024;
|
||||
|
||||
private final SparseArray<Long> initialBitrateEstimates;
|
||||
private final EventDispatcher<EventListener> eventDispatcher;
|
||||
private final SlidingPercentile slidingPercentile;
|
||||
private final Clock clock;
|
||||
|
|
@ -237,34 +228,54 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
|
|||
private long totalBytesTransferred;
|
||||
private long bitrateEstimate;
|
||||
|
||||
/** Creates a bandwidth meter with default parameters. */
|
||||
/** @deprecated Use {@link Builder} instead. */
|
||||
@Deprecated
|
||||
public DefaultBandwidthMeter() {
|
||||
this(DEFAULT_INITIAL_BITRATE_ESTIMATE, DEFAULT_SLIDING_WINDOW_MAX_WEIGHT, Clock.DEFAULT);
|
||||
this(
|
||||
/* context= */ null,
|
||||
/* initialBitrateEstimates= */ new SparseArray<>(),
|
||||
DEFAULT_SLIDING_WINDOW_MAX_WEIGHT,
|
||||
Clock.DEFAULT);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link Builder} instead. */
|
||||
@Deprecated
|
||||
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener) {
|
||||
this(DEFAULT_INITIAL_BITRATE_ESTIMATE, DEFAULT_SLIDING_WINDOW_MAX_WEIGHT, Clock.DEFAULT);
|
||||
this(
|
||||
/* context= */ null,
|
||||
/* initialBitrateEstimates= */ new SparseArray<>(),
|
||||
DEFAULT_SLIDING_WINDOW_MAX_WEIGHT,
|
||||
Clock.DEFAULT);
|
||||
if (eventHandler != null && eventListener != null) {
|
||||
addEventListener(eventHandler, eventListener);
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link Builder} instead. */
|
||||
@Deprecated
|
||||
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener, int maxWeight) {
|
||||
this(DEFAULT_INITIAL_BITRATE_ESTIMATE, maxWeight, Clock.DEFAULT);
|
||||
if (eventHandler != null && eventListener != null) {
|
||||
addEventListener(eventHandler, eventListener);
|
||||
}
|
||||
}
|
||||
|
||||
private DefaultBandwidthMeter(long initialBitrateEstimate, int maxWeight, Clock clock) {
|
||||
private DefaultBandwidthMeter(
|
||||
@Nullable Context context,
|
||||
SparseArray<Long> initialBitrateEstimates,
|
||||
int maxWeight,
|
||||
Clock clock) {
|
||||
this.initialBitrateEstimates = initialBitrateEstimates;
|
||||
this.eventDispatcher = new EventDispatcher<>();
|
||||
this.slidingPercentile = new SlidingPercentile(maxWeight);
|
||||
this.clock = clock;
|
||||
bitrateEstimate = initialBitrateEstimate;
|
||||
bitrateEstimate =
|
||||
getInitialBitrateEstimateForNetworkType(
|
||||
context == null ? C.NETWORK_TYPE_UNKNOWN : Util.getNetworkType(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the network type. Handled in the same way as if the meter had detected a change from
|
||||
* the current network type to the specified network type.
|
||||
*
|
||||
* <p>Applications should not normally call this method. It is intended for testing purposes.
|
||||
*
|
||||
* @param networkType The overriding network type.
|
||||
*/
|
||||
public synchronized void setNetworkTypeOverride(@C.NetworkType int networkType) {
|
||||
// TODO: Handle properly as a network change (in same way as non-external network changes).
|
||||
bitrateEstimate = getInitialBitrateEstimateForNetworkType(networkType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -343,6 +354,17 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
|
|||
eventDispatcher.dispatch(listener -> listener.onBandwidthSample(elapsedMs, bytes, bitrate));
|
||||
}
|
||||
|
||||
private long getInitialBitrateEstimateForNetworkType(@C.NetworkType int networkType) {
|
||||
Long initialBitrateEstimate = initialBitrateEstimates.get(networkType);
|
||||
if (initialBitrateEstimate == null) {
|
||||
initialBitrateEstimate = initialBitrateEstimates.get(C.NETWORK_TYPE_UNKNOWN);
|
||||
}
|
||||
if (initialBitrateEstimate == null) {
|
||||
initialBitrateEstimate = DEFAULT_INITIAL_BITRATE_ESTIMATE;
|
||||
}
|
||||
return initialBitrateEstimate;
|
||||
}
|
||||
|
||||
private static Map<String, int[]> createInitialBitrateCountryGroupAssignment() {
|
||||
HashMap<String, int[]> countryGroupAssignment = new HashMap<>();
|
||||
countryGroupAssignment.put("AD", new int[] {1, 0, 0, 0});
|
||||
|
|
|
|||
Loading…
Reference in a new issue