Commit 2c543632 by olly Committed by Oliver Woodman

Report track groups and selections through ExoPlayer

TrackSelector no longer has a listener. Instead, tracks
change events are reported through ExoPlayer.EventListener.
Applications interested in retrieving the selection info
should retrieve it directly from the TrackSelector by
calling an exposed getter.

Pretty sure the ref'd issue is fixed as a side effect of
this change.

Issue: #1942

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=137183073
parent 0b8e9754
Showing with 296 additions and 241 deletions
......@@ -38,10 +38,10 @@ import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelections;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.io.IOException;
......@@ -55,7 +55,7 @@ import java.util.Locale;
/* package */ final class EventLogger implements ExoPlayer.EventListener,
AudioRendererEventListener, VideoRendererEventListener, AdaptiveMediaSourceEventListener,
ExtractorMediaSource.EventListener, StreamingDrmSessionManager.EventListener,
TrackSelector.EventListener<MappedTrackInfo>, MetadataRenderer.Output<List<Id3Frame>> {
MetadataRenderer.Output<List<Id3Frame>> {
private static final String TAG = "EventLogger";
private static final int MAX_TIMELINE_ITEM_LINES = 3;
......@@ -67,11 +67,13 @@ import java.util.Locale;
TIME_FORMAT.setGroupingUsed(false);
}
private final MappingTrackSelector trackSelector;
private final Timeline.Window window;
private final Timeline.Period period;
private final long startTimeMs;
public EventLogger() {
public EventLogger(MappingTrackSelector trackSelector) {
this.trackSelector = trackSelector;
window = new Timeline.Window();
period = new Timeline.Period();
startTimeMs = SystemClock.elapsedRealtime();
......@@ -126,27 +128,29 @@ import java.util.Locale;
Log.e(TAG, "playerFailed [" + getSessionTimeString() + "]", e);
}
// MappingTrackSelector.EventListener
@Override
public void onTrackSelectionsChanged(TrackSelections<? extends MappedTrackInfo> trackSelections) {
public void onTracksChanged(TrackGroupArray ignored, TrackSelectionArray trackSelections) {
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo == null) {
Log.d(TAG, "Tracks []");
return;
}
Log.d(TAG, "Tracks [");
// Log tracks associated to renderers.
MappedTrackInfo info = trackSelections.info;
for (int rendererIndex = 0; rendererIndex < trackSelections.length; rendererIndex++) {
TrackGroupArray trackGroups = info.getTrackGroups(rendererIndex);
for (int rendererIndex = 0; rendererIndex < mappedTrackInfo.length; rendererIndex++) {
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
TrackSelection trackSelection = trackSelections.get(rendererIndex);
if (trackGroups.length > 0) {
if (rendererTrackGroups.length > 0) {
Log.d(TAG, " Renderer:" + rendererIndex + " [");
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
TrackGroup trackGroup = trackGroups.get(groupIndex);
String adaptiveSupport = getAdaptiveSupportString(
trackGroup.length, info.getAdaptiveSupport(rendererIndex, groupIndex, false));
for (int groupIndex = 0; groupIndex < rendererTrackGroups.length; groupIndex++) {
TrackGroup trackGroup = rendererTrackGroups.get(groupIndex);
String adaptiveSupport = getAdaptiveSupportString(trackGroup.length,
mappedTrackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false));
Log.d(TAG, " Group:" + groupIndex + ", adaptive_supported=" + adaptiveSupport + " [");
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
String status = getTrackStatusString(trackSelection, trackGroup, trackIndex);
String formatSupport = getFormatSupportString(
info.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex));
mappedTrackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex));
Log.d(TAG, " " + status + " Track:" + trackIndex + ", "
+ getFormatString(trackGroup.getFormat(trackIndex))
+ ", supported=" + formatSupport);
......@@ -157,12 +161,12 @@ import java.util.Locale;
}
}
// Log tracks not associated with a renderer.
TrackGroupArray trackGroups = info.getUnassociatedTrackGroups();
if (trackGroups.length > 0) {
TrackGroupArray unassociatedTrackGroups = mappedTrackInfo.getUnassociatedTrackGroups();
if (unassociatedTrackGroups.length > 0) {
Log.d(TAG, " Renderer:None [");
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
for (int groupIndex = 0; groupIndex < unassociatedTrackGroups.length; groupIndex++) {
Log.d(TAG, " Group:" + groupIndex + " [");
TrackGroup trackGroup = trackGroups.get(groupIndex);
TrackGroup trackGroup = unassociatedTrackGroups.get(groupIndex);
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
String status = getTrackStatusString(false);
String formatSupport = getFormatSupportString(
......
......@@ -58,8 +58,7 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelections;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.DebugTextViewHelper;
import com.google.android.exoplayer2.ui.PlaybackControlView;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
......@@ -78,7 +77,7 @@ import java.util.UUID;
* An activity that plays media using {@link SimpleExoPlayer}.
*/
public class PlayerActivity extends Activity implements OnClickListener, ExoPlayer.EventListener,
TrackSelector.EventListener<MappedTrackInfo>, PlaybackControlView.VisibilityListener {
PlaybackControlView.VisibilityListener {
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
public static final String DRM_LICENSE_URL = "drm_license_url";
......@@ -203,8 +202,11 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
if (view == retryButton) {
initializePlayer();
} else if (view.getParent() == debugRootView) {
trackSelectionHelper.showSelectionDialog(this, ((Button) view).getText(),
trackSelector.getCurrentSelections().info, (int) view.getTag());
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
trackSelectionHelper.showSelectionDialog(this, ((Button) view).getText(),
trackSelector.getCurrentMappedTrackInfo(), (int) view.getTag());
}
}
}
......@@ -249,20 +251,20 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
}
}
eventLogger = new EventLogger();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveVideoTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(mainHandler, videoTrackSelectionFactory);
trackSelector.addListener(this);
trackSelector.addListener(eventLogger);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(),
drmSessionManager, preferExtensionDecoders);
player.addListener(this);
eventLogger = new EventLogger(trackSelector);
player.addListener(eventLogger);
player.setAudioDebugListener(eventLogger);
player.setVideoDebugListener(eventLogger);
player.setId3Output(eventLogger);
simpleExoPlayerView.setPlayer(player);
if (isTimelineStatic) {
if (playerPosition == C.TIME_UNSET) {
......@@ -447,17 +449,17 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
showControls();
}
// MappingTrackSelector.EventListener implementation
@Override
public void onTrackSelectionsChanged(TrackSelections<? extends MappedTrackInfo> trackSelections) {
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
updateButtonVisibilities();
MappedTrackInfo trackInfo = trackSelections.info;
if (trackInfo.hasOnlyUnplayableTracks(C.TRACK_TYPE_VIDEO)) {
showToast(R.string.error_unsupported_video);
}
if (trackInfo.hasOnlyUnplayableTracks(C.TRACK_TYPE_AUDIO)) {
showToast(R.string.error_unsupported_audio);
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
if (mappedTrackInfo.hasOnlyUnplayableTracks(C.TRACK_TYPE_VIDEO)) {
showToast(R.string.error_unsupported_video);
}
if (mappedTrackInfo.hasOnlyUnplayableTracks(C.TRACK_TYPE_AUDIO)) {
showToast(R.string.error_unsupported_audio);
}
}
}
......@@ -473,14 +475,13 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
return;
}
TrackSelections<MappedTrackInfo> trackSelections = trackSelector.getCurrentSelections();
if (trackSelections == null) {
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo == null) {
return;
}
int rendererCount = trackSelections.length;
for (int i = 0; i < rendererCount; i++) {
TrackGroupArray trackGroups = trackSelections.info.getTrackGroups(i);
for (int i = 0; i < mappedTrackInfo.length; i++) {
TrackGroupArray trackGroups = mappedTrackInfo.getTrackGroups(i);
if (trackGroups.length != 0) {
Button button = new Button(this);
int label;
......
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.ext.flac;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException;
......@@ -27,7 +26,9 @@ import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
/**
......@@ -72,7 +73,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
public void run() {
Looper.prepare();
LibflacAudioRenderer audioRenderer = new LibflacAudioRenderer();
DefaultTrackSelector trackSelector = new DefaultTrackSelector(new Handler());
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
player.addListener(this);
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
......@@ -92,6 +93,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// Do nothing.
}
@Override
public void onPositionDiscontinuity() {
// Do nothing.
}
......
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.ext.opus;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException;
......@@ -27,7 +26,9 @@ import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
/**
......@@ -72,7 +73,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
public void run() {
Looper.prepare();
LibopusAudioRenderer audioRenderer = new LibopusAudioRenderer();
DefaultTrackSelector trackSelector = new DefaultTrackSelector(new Handler());
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
player.addListener(this);
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
......@@ -92,6 +93,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// Do nothing.
}
@Override
public void onPositionDiscontinuity() {
// Do nothing.
}
......
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.ext.vp9;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException;
......@@ -27,7 +26,9 @@ import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
/**
......@@ -88,7 +89,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
public void run() {
Looper.prepare();
LibvpxVideoRenderer videoRenderer = new LibvpxVideoRenderer(true, 0);
DefaultTrackSelector trackSelector = new DefaultTrackSelector(new Handler());
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newInstance(new Renderer[] {videoRenderer}, trackSelector);
player.addListener(this);
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
......@@ -111,6 +112,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// Do nothing.
}
@Override
public void onPositionDiscontinuity() {
// Do nothing.
}
......
......@@ -16,7 +16,7 @@
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelections;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.util.Util;
......@@ -111,7 +111,7 @@ public final class DefaultLoadControl implements LoadControl {
@Override
public void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelections<?> trackSelections) {
TrackSelectionArray trackSelections) {
targetBufferSize = 0;
for (int i = 0; i < renderers.length; i++) {
if (trackSelections.get(i) != null) {
......
......@@ -22,11 +22,13 @@ import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.text.TextRenderer;
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.DataSource;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
......@@ -111,6 +113,15 @@ public interface ExoPlayer {
interface EventListener {
/**
* Called when the available or selected tracks change.
*
* @param trackGroups The available tracks. Never null, but may be of length zero.
* @param trackSelections The track selections for each {@link Renderer}. Never null and always
* of length {@link #getRendererCount()}, but may contain null elements.
*/
void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections);
/**
* Called when the player starts or stops loading the source.
*
* @param isLoading Whether the source is currently being loaded.
......@@ -259,11 +270,11 @@ public interface ExoPlayer {
* @param resetPosition Whether the playback position should be reset to the default position in
* the first {@link Timeline.Window}. If false, playback will start from the position defined
* by {@link #getCurrentWindowIndex()} and {@link #getCurrentPosition()}.
* @param resetTimeline Whether the timeline and manifest should be reset. Should be true unless
* the player is being prepared to play the same media as it was playing previously (e.g. if
* playback failed and is being retried).
* @param resetState Whether the timeline, manifest, tracks and track selections should be reset.
* Should be true unless the player is being prepared to play the same media as it was playing
* previously (e.g. if playback failed and is being retried).
*/
void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetTimeline);
void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState);
/**
* Sets whether playback should proceed when {@link #getPlaybackState()} == {@link #STATE_READY}.
......@@ -357,6 +368,30 @@ public interface ExoPlayer {
void blockingSendMessages(ExoPlayerMessage... messages);
/**
* Returns the number of renderers.
*/
int getRendererCount();
/**
* Returns the track type that the renderer at a given index handles.
*
* @see Renderer#getTrackType()
* @param index The index of the renderer.
* @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
*/
int getRendererType(int index);
/**
* Returns the available track groups.
*/
TrackGroupArray getCurrentTrackGroups();
/**
* Returns the current track selections for each renderer.
*/
TrackSelectionArray getCurrentTrackSelections();
/**
* Returns the current manifest. The type depends on the {@link MediaSource} passed to
* {@link #prepare}.
*/
......
......@@ -42,7 +42,7 @@ public final class ExoPlayerFactory {
* @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,
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl) {
return newSimpleInstance(context, trackSelector, loadControl, null);
}
......@@ -57,7 +57,7 @@ public final class ExoPlayerFactory {
* @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,
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
return newSimpleInstance(context, trackSelector, loadControl, drmSessionManager, false);
}
......@@ -75,7 +75,7 @@ public final class ExoPlayerFactory {
* available extensions over those defined in the core library. Note that extensions must be
* included in the application build for setting this flag to have any effect.
*/
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector<?> trackSelector,
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean preferExtensionDecoders) {
return newSimpleInstance(context, trackSelector, loadControl, drmSessionManager,
......@@ -97,7 +97,7 @@ public final class ExoPlayerFactory {
* @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to
* seamlessly join an ongoing playback.
*/
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector<?> trackSelector,
public static SimpleExoPlayer newSimpleInstance(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean preferExtensionDecoders, long allowedVideoJoiningTimeMs) {
return new SimpleExoPlayer(context, trackSelector, loadControl, drmSessionManager,
......@@ -111,7 +111,7 @@ public final class ExoPlayerFactory {
* @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) {
public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector) {
return newInstance(renderers, trackSelector, new DefaultLoadControl());
}
......@@ -123,7 +123,7 @@ public final class ExoPlayerFactory {
* @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,
public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector,
LoadControl loadControl) {
return new ExoPlayerImpl(renderers, trackSelector, loadControl);
}
......
......@@ -22,7 +22,11 @@ import android.os.Message;
import android.util.Log;
import android.util.Pair;
import com.google.android.exoplayer2.ExoPlayerImplInternal.PlaybackInfo;
import com.google.android.exoplayer2.ExoPlayerImplInternal.TrackInfo;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
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.util.Assertions;
import java.util.concurrent.CopyOnWriteArraySet;
......@@ -34,12 +38,16 @@ import java.util.concurrent.CopyOnWriteArraySet;
private static final String TAG = "ExoPlayerImpl";
private final Renderer[] renderers;
private final TrackSelector trackSelector;
private final TrackSelectionArray emptyTrackSelections;
private final Handler eventHandler;
private final ExoPlayerImplInternal<?> internalPlayer;
private final ExoPlayerImplInternal internalPlayer;
private final CopyOnWriteArraySet<EventListener> listeners;
private final Timeline.Window window;
private final Timeline.Period period;
private boolean tracksSelected;
private boolean pendingInitialSeek;
private boolean playWhenReady;
private int playbackState;
......@@ -47,6 +55,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
private boolean isLoading;
private Timeline timeline;
private Object manifest;
private TrackGroupArray trackGroups;
private TrackSelectionArray trackSelections;
// Playback information when there is no pending seek/set source operation.
private PlaybackInfo playbackInfo;
......@@ -63,16 +73,19 @@ import java.util.concurrent.CopyOnWriteArraySet;
* @param loadControl The {@link LoadControl} that will be used by the instance.
*/
@SuppressLint("HandlerLeak")
public ExoPlayerImpl(Renderer[] renderers, TrackSelector<?> trackSelector,
LoadControl loadControl) {
public ExoPlayerImpl(Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl) {
Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION);
Assertions.checkNotNull(renderers);
Assertions.checkState(renderers.length > 0);
this.renderers = Assertions.checkNotNull(renderers);
this.trackSelector = Assertions.checkNotNull(trackSelector);
this.playWhenReady = false;
this.playbackState = STATE_IDLE;
this.listeners = new CopyOnWriteArraySet<>();
emptyTrackSelections = new TrackSelectionArray(new TrackSelection[renderers.length]);
window = new Timeline.Window();
period = new Timeline.Period();
trackGroups = TrackGroupArray.EMPTY;
trackSelections = emptyTrackSelections;
eventHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
......@@ -80,8 +93,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
};
playbackInfo = new ExoPlayerImplInternal.PlaybackInfo(0, 0);
internalPlayer = new ExoPlayerImplInternal<>(renderers, trackSelector, loadControl,
playWhenReady, eventHandler, playbackInfo);
internalPlayer = new ExoPlayerImplInternal(renderers, trackSelector, loadControl, playWhenReady,
eventHandler, playbackInfo);
}
@Override
......@@ -105,12 +118,23 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
@Override
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetTimeline) {
if (resetTimeline && (timeline != null || manifest != null)) {
timeline = null;
manifest = null;
for (EventListener listener : listeners) {
listener.onTimelineChanged(null, null);
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
if (resetState) {
if (timeline != null || manifest != null) {
timeline = null;
manifest = null;
for (EventListener listener : listeners) {
listener.onTimelineChanged(null, null);
}
}
if (tracksSelected) {
tracksSelected = false;
trackGroups = TrackGroupArray.EMPTY;
trackSelections = emptyTrackSelections;
trackSelector.onSelectionActivated(null);
for (EventListener listener : listeners) {
listener.onTracksChanged(trackGroups, trackSelections);
}
}
}
internalPlayer.prepare(mediaSource, resetPosition);
......@@ -267,6 +291,26 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
@Override
public int getRendererCount() {
return renderers.length;
}
@Override
public int getRendererType(int index) {
return renderers[index].getTrackType();
}
@Override
public TrackGroupArray getCurrentTrackGroups() {
return trackGroups;
}
@Override
public TrackSelectionArray getCurrentTrackSelections() {
return trackSelections;
}
@Override
public Timeline getCurrentTimeline() {
return timeline;
}
......@@ -293,6 +337,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
break;
}
case ExoPlayerImplInternal.MSG_TRACKS_CHANGED: {
TrackInfo trackInfo = (TrackInfo) msg.obj;
tracksSelected = true;
trackGroups = trackInfo.groups;
trackSelections = trackInfo.selections;
trackSelector.onSelectionActivated(trackInfo.info);
for (EventListener listener : listeners) {
listener.onTracksChanged(trackGroups, trackSelections);
}
break;
}
case ExoPlayerImplInternal.MSG_SEEK_ACK: {
if (--pendingSeekAcks == 0) {
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
......
......@@ -17,7 +17,7 @@ package com.google.android.exoplayer2;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelections;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.Allocator;
/**
......@@ -38,7 +38,7 @@ public interface LoadControl {
* @param trackSelections The track selections that were made.
*/
void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelections<?> trackSelections);
TrackSelectionArray trackSelections);
/**
* Called by the player when stopped.
......
......@@ -39,9 +39,10 @@ import com.google.android.exoplayer2.metadata.MetadataRenderer;
import com.google.android.exoplayer2.metadata.id3.Id3Decoder;
import com.google.android.exoplayer2.metadata.id3.Id3Frame;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelections;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
......@@ -86,11 +87,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
*/
void onRenderedFirstFrame();
/**
* Called when a video track is no longer selected.
*/
void onVideoTracksDisabled();
}
private static final String TAG = "SimpleExoPlayer";
......@@ -103,7 +99,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
private final int videoRendererCount;
private final int audioRendererCount;
private boolean videoTracksEnabled;
private Format videoFormat;
private Format audioFormat;
......@@ -122,12 +117,11 @@ public final class SimpleExoPlayer implements ExoPlayer {
private float volume;
private PlaybackParamsHolder playbackParamsHolder;
/* package */ SimpleExoPlayer(Context context, TrackSelector<?> trackSelector,
/* package */ SimpleExoPlayer(Context context, TrackSelector trackSelector,
LoadControl loadControl, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean preferExtensionDecoders, long allowedVideoJoiningTimeMs) {
mainHandler = new Handler();
componentListener = new ComponentListener();
trackSelector.addListener(componentListener);
// Build the renderers.
ArrayList<Renderer> renderersList = new ArrayList<>();
......@@ -165,26 +159,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
}
/**
* Returns the number of renderers.
*
* @return The number of renderers.
*/
public int getRendererCount() {
return renderers.length;
}
/**
* Returns the track type that the renderer at a given index handles.
*
* @see Renderer#getTrackType()
* @param index The index of the renderer.
* @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
*/
public int getRendererType(int index) {
return renderers[index].getTrackType();
}
/**
* Clears any {@link Surface}, {@link SurfaceHolder}, {@link SurfaceView} or {@link TextureView}
* currently set on the player.
*/
......@@ -518,6 +492,26 @@ public final class SimpleExoPlayer implements ExoPlayer {
}
@Override
public int getRendererCount() {
return player.getRendererCount();
}
@Override
public int getRendererType(int index) {
return player.getRendererType(index);
}
@Override
public TrackGroupArray getCurrentTrackGroups() {
return player.getCurrentTrackGroups();
}
@Override
public TrackSelectionArray getCurrentTrackSelections() {
return player.getCurrentTrackSelections();
}
@Override
public Timeline getCurrentTimeline() {
return player.getCurrentTimeline();
}
......@@ -651,8 +645,7 @@ public final class SimpleExoPlayer implements ExoPlayer {
private final class ComponentListener implements VideoRendererEventListener,
AudioRendererEventListener, TextRenderer.Output, MetadataRenderer.Output<List<Id3Frame>>,
SurfaceHolder.Callback, TextureView.SurfaceTextureListener,
TrackSelector.EventListener<Object> {
SurfaceHolder.Callback, TextureView.SurfaceTextureListener {
// VideoRendererEventListener implementation
......@@ -831,23 +824,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
// Do nothing.
}
// TrackSelector.EventListener implementation
@Override
public void onTrackSelectionsChanged(TrackSelections<?> trackSelections) {
boolean videoTracksEnabled = false;
for (int i = 0; i < renderers.length; i++) {
if (renderers[i].getTrackType() == C.TRACK_TYPE_VIDEO && trackSelections.get(i) != null) {
videoTracksEnabled = true;
break;
}
}
if (videoListener != null && SimpleExoPlayer.this.videoTracksEnabled && !videoTracksEnabled) {
videoListener.onVideoTracksDisabled();
}
SimpleExoPlayer.this.videoTracksEnabled = videoTracksEnabled;
}
}
@TargetApi(23)
......
......@@ -24,6 +24,11 @@ import java.util.Arrays;
public final class TrackGroupArray {
/**
* The empty array.
*/
public static final TrackGroupArray EMPTY = new TrackGroupArray();
/**
* The number of groups in the array. Greater than or equal to zero.
*/
public final int length;
......
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.trackselection;
import android.content.Context;
import android.graphics.Point;
import android.os.Handler;
import android.text.TextUtils;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
......@@ -326,25 +325,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/**
* Constructs an instance that does not support adaptive video.
*
* @param eventHandler A handler to use when delivering events to listeners. May be null if
* listeners will not be added.
*/
public DefaultTrackSelector(Handler eventHandler) {
this(eventHandler, null);
public DefaultTrackSelector() {
this(null);
}
/**
* Constructs an instance that uses a factory to create adaptive video track selections.
*
* @param eventHandler A handler to use when delivering events to listeners. May be null if
* listeners will not be added.
* @param adaptiveVideoTrackSelectionFactory A factory for adaptive video {@link TrackSelection}s,
* or null if the selector should not support adaptive video.
*/
public DefaultTrackSelector(Handler eventHandler,
TrackSelection.Factory adaptiveVideoTrackSelectionFactory) {
super(eventHandler);
public DefaultTrackSelector(TrackSelection.Factory adaptiveVideoTrackSelectionFactory) {
this.adaptiveVideoTrackSelectionFactory = adaptiveVideoTrackSelectionFactory;
params = new AtomicReference<>(new Parameters());
}
......
......@@ -15,14 +15,13 @@
*/
package com.google.android.exoplayer2.trackselection;
import android.os.Handler;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.util.Util;
import java.util.Arrays;
import java.util.HashMap;
......@@ -32,7 +31,7 @@ import java.util.Map;
* Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s
* and renderers, and then from that mapping create a {@link TrackSelection} for each renderer.
*/
public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo> {
public abstract class MappingTrackSelector extends TrackSelector {
/**
* A track selection override.
......@@ -83,17 +82,22 @@ public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo
private final SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides;
private final SparseBooleanArray rendererDisabledFlags;
/**
* @param eventHandler A handler to use when delivering events to listeners added via
* {@link #addListener(EventListener)}.
*/
public MappingTrackSelector(Handler eventHandler) {
super(eventHandler);
private MappedTrackInfo currentMappedTrackInfo;
public MappingTrackSelector() {
selectionOverrides = new SparseArray<>();
rendererDisabledFlags = new SparseBooleanArray();
}
/**
* Returns the mapping information associated with the current track selections, or null if no
* selection is currently active.
*/
public final MappedTrackInfo getCurrentMappedTrackInfo() {
return currentMappedTrackInfo;
}
/**
* Sets whether the renderer at the specified index is disabled.
*
* @param rendererIndex The renderer index.
......@@ -224,7 +228,7 @@ public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo
// TrackSelector implementation.
@Override
public final TrackSelections<MappedTrackInfo> selectTracks(
public final Pair<TrackSelectionArray, Object> selectTracks(
RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups)
throws ExoPlaybackException {
// Structures into which data will be written during the selection. The extra item at the end
......@@ -294,7 +298,13 @@ public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo
MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererTrackTypes,
rendererTrackGroupArrays, mixedMimeTypeAdaptationSupport, rendererFormatSupports,
unassociatedTrackGroupArray);
return new TrackSelections<>(mappedTrackInfo, trackSelections);
return Pair.<TrackSelectionArray, Object>create(new TrackSelectionArray(trackSelections),
mappedTrackInfo);
}
@Override
public final void onSelectionActivated(Object info) {
currentMappedTrackInfo = (MappedTrackInfo) info;
}
/**
......@@ -409,12 +419,16 @@ public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo
*/
public static final int RENDERER_SUPPORT_PLAYABLE_TRACKS = 2;
/**
* The number of renderers to which tracks are mapped.
*/
public final int length;
private final int[] rendererTrackTypes;
private final TrackGroupArray[] trackGroups;
private final int[] mixedMimeTypeAdaptiveSupport;
private final int[][][] formatSupport;
private final TrackGroupArray unassociatedTrackGroups;
private final int rendererCount;
/**
* @param rendererTrackTypes The track type supported by each renderer.
......@@ -433,7 +447,7 @@ public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo
this.formatSupport = formatSupport;
this.mixedMimeTypeAdaptiveSupport = mixedMimeTypeAdaptiveSupport;
this.unassociatedTrackGroups = unassociatedTrackGroups;
this.rendererCount = trackGroups.length;
this.length = trackGroups.length;
}
/**
......@@ -573,7 +587,7 @@ public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo
*/
public boolean hasOnlyUnplayableTracks(int trackType) {
int rendererSupport = RENDERER_SUPPORT_NO_TRACKS;
for (int i = 0; i < rendererCount; i++) {
for (int i = 0; i < length; i++) {
if (rendererTrackTypes[i] == trackType) {
rendererSupport = Math.max(rendererSupport, getRendererSupport(i));
}
......
......@@ -20,13 +20,9 @@ import java.util.Arrays;
/**
* The result of a {@link TrackSelector} operation.
*/
public final class TrackSelections<T> {
public final class TrackSelectionArray {
/**
* Opaque information associated with the result.
*/
public final T info;
/**
* The number of selections in the result. Greater than or equal to zero.
*/
public final int length;
......@@ -37,11 +33,9 @@ public final class TrackSelections<T> {
private int hashCode;
/**
* @param info Opaque information associated with the result.
* @param trackSelections The selections. Must not be null, but may contain null elements.
*/
public TrackSelections(T info, TrackSelection... trackSelections) {
this.info = info;
public TrackSelectionArray(TrackSelection... trackSelections) {
this.trackSelections = trackSelections;
this.length = trackSelections.length;
}
......@@ -81,7 +75,7 @@ public final class TrackSelections<T> {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
TrackSelections<?> other = (TrackSelections<?>) obj;
TrackSelectionArray other = (TrackSelectionArray) obj;
return Arrays.equals(trackSelections, other.trackSelections);
}
......
......@@ -15,15 +15,13 @@
*/
package com.google.android.exoplayer2.trackselection;
import android.os.Handler;
import android.util.Pair;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.util.Assertions;
import java.util.concurrent.CopyOnWriteArraySet;
/** Selects tracks to be consumed by available renderers. */
public abstract class TrackSelector<T> {
public abstract class TrackSelector {
/**
* Notified when previous selections by a {@link TrackSelector} are no longer valid.
......@@ -37,56 +35,7 @@ public abstract class TrackSelector<T> {
}
/** Listener of {@link TrackSelector} events. */
public interface EventListener<T> {
/**
* Called when the track selections have changed.
*
* @param trackSelections The new track selections.
*/
void onTrackSelectionsChanged(TrackSelections<? extends T> trackSelections);
}
private final Handler eventHandler;
private final CopyOnWriteArraySet<MappingTrackSelector.EventListener<? super T>> listeners;
private InvalidationListener listener;
private TrackSelections<T> activeSelections;
/**
* @param eventHandler A handler to use when delivering events to listeners added via {@link
* #addListener(EventListener)}.
*/
public TrackSelector(Handler eventHandler) {
this.eventHandler = Assertions.checkNotNull(eventHandler);
this.listeners = new CopyOnWriteArraySet<>();
}
/**
* Registers a listener to receive events from the selector. The listener's methods will be called
* using the {@link Handler} that was passed to the constructor.
*
* @param listener The listener to register.
*/
public final void addListener(EventListener<? super T> listener) {
listeners.add(listener);
}
/**
* Unregister a listener. The listener will no longer receive events from the selector.
*
* @param listener The listener to unregister.
*/
public final void removeListener(EventListener<? super T> listener) {
listeners.remove(listener);
}
/** Returns the current track selections. */
public final TrackSelections<T> getCurrentSelections() {
return activeSelections;
}
/**
* Initializes the selector.
......@@ -98,28 +47,27 @@ public abstract class TrackSelector<T> {
}
/**
* Generates {@link TrackSelections} for the renderers.
* Generates {@link TrackSelectionArray} for the renderers.
*
* @param rendererCapabilities The {@link RendererCapabilities} of the renderers for which {@link
* TrackSelection}s are to be generated.
* @param rendererCapabilities The {@link RendererCapabilities} of the renderers for which
* {@link TrackSelection}s are to be generated.
* @param trackGroups The available track groups.
* @return The track selections.
* @return The track selections, and an implementation specific object that will be returned to
* the selector via {@link #onSelectionActivated(Object)} should the selections be activated.
* @throws ExoPlaybackException If an error occurs selecting tracks.
*/
public abstract TrackSelections<T> selectTracks(
public abstract Pair<TrackSelectionArray, Object> selectTracks(
RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups)
throws ExoPlaybackException;
/**
* Called when {@link TrackSelections} previously generated by {@link
* #selectTracks(RendererCapabilities[], TrackGroupArray)} are activated.
* Called when {@link TrackSelectionArray} previously generated by
* {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} are activated.
*
* @param activeSelections The activated {@link TrackSelections}.
* @param info The information associated with the selections, or null if the selected tracks are
* being cleared.
*/
public final void onSelectionActivated(TrackSelections<T> activeSelections) {
this.activeSelections = activeSelections;
notifyTrackSelectionsChanged(activeSelections);
}
public abstract void onSelectionActivated(Object info);
/**
* Invalidates all previously generated track selections.
......@@ -130,18 +78,4 @@ public abstract class TrackSelector<T> {
}
}
private void notifyTrackSelectionsChanged(final TrackSelections<T> activeSelections) {
if (eventHandler != null) {
eventHandler.post(
new Runnable() {
@Override
public void run() {
for (EventListener<? super T> listener : listeners) {
listener.onTrackSelectionsChanged(activeSelections);
}
}
});
}
}
}
......@@ -22,6 +22,8 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
/**
* A helper class for periodically updating a {@link TextView} with debug information obtained from
......@@ -98,6 +100,11 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
// Do nothing.
}
@Override
public void onTracksChanged(TrackGroupArray tracks, TrackSelectionArray selections) {
// Do nothing.
}
// Runnable implementation.
@Override
......
......@@ -31,6 +31,8 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.R;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.util.Util;
import java.util.Formatter;
import java.util.Locale;
......@@ -577,6 +579,11 @@ public class PlaybackControlView extends FrameLayout {
}
@Override
public void onTracksChanged(TrackGroupArray tracks, TrackSelectionArray selections) {
// Do nothing.
}
@Override
public void onPlayerError(ExoPlaybackException error) {
// Do nothing.
}
......
......@@ -27,13 +27,16 @@ import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.R;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import java.util.List;
/**
......@@ -325,7 +328,13 @@ public final class SimpleExoPlayerView extends FrameLayout {
}
@Override
public void onVideoTracksDisabled() {
public void onTracksChanged(TrackGroupArray tracks, TrackSelectionArray selections) {
for (int i = 0; i < selections.length; i++) {
if (player.getRendererType(i) == C.TRACK_TYPE_VIDEO && selections.get(i) != null) {
return;
}
}
// No enabled video renderers. Close the shutter.
shutterView.setVisibility(VISIBLE);
}
......
......@@ -19,8 +19,6 @@ import android.annotation.TargetApi;
import android.media.MediaDrm;
import android.media.UnsupportedSchemeException;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import com.google.android.exoplayer2.C;
......@@ -805,7 +803,6 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private DashTestTrackSelector(String audioFormatId, String[] videoFormatIds,
boolean canIncludeAdditionalVideoFormats) {
super(new Handler(Looper.getMainLooper()));
this.audioFormatId = audioFormatId;
this.videoFormatIds = videoFormatIds;
this.canIncludeAdditionalVideoFormats = canIncludeAdditionalVideoFormats;
......
......@@ -33,9 +33,11 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.playbacktests.util.HostActivity.HostedTest;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveVideoTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
......@@ -187,6 +189,11 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// Do nothing.
}
@Override
public final void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.d(tag, "state [" + playWhenReady + ", " + playbackState + "]");
playerWasPrepared |= playbackState != ExoPlayer.STATE_IDLE;
......@@ -305,7 +312,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
@SuppressWarnings("unused")
protected MappingTrackSelector buildTrackSelector(HostActivity host,
BandwidthMeter bandwidthMeter) {
return new DefaultTrackSelector(null, new AdaptiveVideoTrackSelection.Factory(bandwidthMeter));
return new DefaultTrackSelector(new AdaptiveVideoTrackSelection.Factory(bandwidthMeter));
}
@SuppressWarnings("unused")
......
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