mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Fix shutter open/close behavior
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=134389619
This commit is contained in:
parent
d74166cd35
commit
eaf8218855
15 changed files with 220 additions and 219 deletions
|
|
@ -38,9 +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.TrackInfo;
|
||||
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.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
||||
import java.io.IOException;
|
||||
|
|
@ -54,7 +55,7 @@ import java.util.Locale;
|
|||
/* package */ final class EventLogger implements ExoPlayer.EventListener,
|
||||
AudioRendererEventListener, VideoRendererEventListener, AdaptiveMediaSourceEventListener,
|
||||
ExtractorMediaSource.EventListener, StreamingDrmSessionManager.EventListener,
|
||||
MappingTrackSelector.EventListener, MetadataRenderer.Output<List<Id3Frame>> {
|
||||
TrackSelector.EventListener<MappedTrackInfo>, MetadataRenderer.Output<List<Id3Frame>> {
|
||||
|
||||
private static final String TAG = "EventLogger";
|
||||
private static final int MAX_TIMELINE_ITEM_LINES = 3;
|
||||
|
|
@ -125,23 +126,24 @@ import java.util.Locale;
|
|||
// MappingTrackSelector.EventListener
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(TrackInfo trackInfo) {
|
||||
public void onTrackSelectionsChanged(TrackSelections<? extends MappedTrackInfo> trackSelections) {
|
||||
Log.d(TAG, "Tracks [");
|
||||
// Log tracks associated to renderers.
|
||||
for (int rendererIndex = 0; rendererIndex < trackInfo.rendererCount; rendererIndex++) {
|
||||
TrackGroupArray trackGroups = trackInfo.getTrackGroups(rendererIndex);
|
||||
TrackSelection trackSelection = trackInfo.getTrackSelection(rendererIndex);
|
||||
MappedTrackInfo info = trackSelections.info;
|
||||
for (int rendererIndex = 0; rendererIndex < trackSelections.length; rendererIndex++) {
|
||||
TrackGroupArray trackGroups = info.getTrackGroups(rendererIndex);
|
||||
TrackSelection trackSelection = trackSelections.get(rendererIndex);
|
||||
if (trackGroups.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, trackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false));
|
||||
trackGroup.length, info.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(
|
||||
trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex));
|
||||
info.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex));
|
||||
Log.d(TAG, " " + status + " Track:" + trackIndex + ", "
|
||||
+ getFormatString(trackGroup.getFormat(trackIndex))
|
||||
+ ", supported=" + formatSupport);
|
||||
|
|
@ -152,7 +154,7 @@ import java.util.Locale;
|
|||
}
|
||||
}
|
||||
// Log tracks not associated with a renderer.
|
||||
TrackGroupArray trackGroups = trackInfo.getUnassociatedTrackGroups();
|
||||
TrackGroupArray trackGroups = info.getUnassociatedTrackGroups();
|
||||
if (trackGroups.length > 0) {
|
||||
Log.d(TAG, " Renderer:None [");
|
||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import com.google.android.exoplayer2.ExoPlayerFactory;
|
|||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
|
||||
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
||||
import com.google.android.exoplayer2.drm.StreamingDrmSessionManager;
|
||||
|
|
@ -55,8 +56,10 @@ import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
|
|||
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.MappingTrackSelector.TrackInfo;
|
||||
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.ui.DebugTextViewHelper;
|
||||
import com.google.android.exoplayer2.ui.PlaybackControlView;
|
||||
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
|
||||
|
|
@ -77,7 +80,7 @@ import java.util.UUID;
|
|||
* An activity that plays media using {@link SimpleExoPlayer}.
|
||||
*/
|
||||
public class PlayerActivity extends Activity implements OnClickListener, ExoPlayer.EventListener,
|
||||
MappingTrackSelector.EventListener, PlaybackControlView.VisibilityListener {
|
||||
TrackSelector.EventListener<MappedTrackInfo>, PlaybackControlView.VisibilityListener {
|
||||
|
||||
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
|
||||
public static final String DRM_LICENSE_URL = "drm_license_url";
|
||||
|
|
@ -203,7 +206,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
|
|||
initializePlayer();
|
||||
} else if (view.getParent() == debugRootView) {
|
||||
trackSelectionHelper.showSelectionDialog(this, ((Button) view).getText(),
|
||||
trackSelector.getTrackInfo(), (int) view.getTag());
|
||||
trackSelector.getCurrentSelections().info, (int) view.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +225,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
|
|||
boolean preferExtensionDecoders = intent.getBooleanExtra(PREFER_EXTENSION_DECODERS, false);
|
||||
UUID drmSchemeUuid = intent.hasExtra(DRM_SCHEME_UUID_EXTRA)
|
||||
? UUID.fromString(intent.getStringExtra(DRM_SCHEME_UUID_EXTRA)) : null;
|
||||
DrmSessionManager drmSessionManager = null;
|
||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
|
||||
if (drmSchemeUuid != null) {
|
||||
String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL);
|
||||
String[] keyRequestPropertiesArray = intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES);
|
||||
|
|
@ -333,9 +336,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
|
|||
}
|
||||
}
|
||||
|
||||
private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl,
|
||||
Map<String, String> keyRequestProperties)
|
||||
throws UnsupportedDrmException {
|
||||
private DrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManager(UUID uuid,
|
||||
String licenseUrl, Map<String, String> keyRequestProperties) throws UnsupportedDrmException {
|
||||
if (Util.SDK_INT < 18) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -452,8 +454,9 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
|
|||
// MappingTrackSelector.EventListener implementation
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(TrackInfo trackInfo) {
|
||||
public void onTrackSelectionsChanged(TrackSelections<? extends MappedTrackInfo> trackSelections) {
|
||||
updateButtonVisibilities();
|
||||
MappedTrackInfo trackInfo = trackSelections.info;
|
||||
if (trackInfo.hasOnlyUnplayableTracks(C.TRACK_TYPE_VIDEO)) {
|
||||
showToast(R.string.error_unsupported_video);
|
||||
}
|
||||
|
|
@ -474,14 +477,14 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
|
|||
return;
|
||||
}
|
||||
|
||||
TrackInfo trackInfo = trackSelector.getTrackInfo();
|
||||
if (trackInfo == null) {
|
||||
TrackSelections<MappedTrackInfo> trackSelections = trackSelector.getCurrentSelections();
|
||||
if (trackSelections == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int rendererCount = trackInfo.rendererCount;
|
||||
int rendererCount = trackSelections.length;
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
TrackGroupArray trackGroups = trackInfo.getTrackGroups(i);
|
||||
TrackGroupArray trackGroups = trackSelections.info.getTrackGroups(i);
|
||||
if (trackGroups.length != 0) {
|
||||
Button button = new Button(this);
|
||||
int label;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.SelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.TrackInfo;
|
||||
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
|
|
@ -51,7 +51,7 @@ import java.util.Locale;
|
|||
private final MappingTrackSelector selector;
|
||||
private final TrackSelection.Factory adaptiveVideoTrackSelectionFactory;
|
||||
|
||||
private TrackInfo trackInfo;
|
||||
private MappedTrackInfo trackInfo;
|
||||
private int rendererIndex;
|
||||
private TrackGroupArray trackGroups;
|
||||
private boolean[] trackGroupsAdaptive;
|
||||
|
|
@ -82,7 +82,7 @@ import java.util.Locale;
|
|||
* @param trackInfo The current track information.
|
||||
* @param rendererIndex The index of the renderer.
|
||||
*/
|
||||
public void showSelectionDialog(Activity activity, CharSequence title, TrackInfo trackInfo,
|
||||
public void showSelectionDialog(Activity activity, CharSequence title, MappedTrackInfo trackInfo,
|
||||
int rendererIndex) {
|
||||
this.trackInfo = trackInfo;
|
||||
this.rendererIndex = rendererIndex;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ 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;
|
||||
|
|
@ -71,7 +72,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
|
|||
public void run() {
|
||||
Looper.prepare();
|
||||
LibflacAudioRenderer audioRenderer = new LibflacAudioRenderer();
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(null);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(new Handler());
|
||||
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
|
||||
player.addListener(this);
|
||||
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ 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;
|
||||
|
|
@ -71,7 +72,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
|
|||
public void run() {
|
||||
Looper.prepare();
|
||||
LibopusAudioRenderer audioRenderer = new LibopusAudioRenderer();
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(null);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(new Handler());
|
||||
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
|
||||
player.addListener(this);
|
||||
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ 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;
|
||||
|
|
@ -87,7 +88,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
|
|||
public void run() {
|
||||
Looper.prepare();
|
||||
LibvpxVideoRenderer videoRenderer = new LibvpxVideoRenderer(true, 0);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(null);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(new Handler());
|
||||
player = ExoPlayerFactory.newInstance(new Renderer[] {videoRenderer}, trackSelector);
|
||||
player.addListener(this);
|
||||
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
package com.google.android.exoplayer2;
|
||||
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelections;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -106,7 +106,7 @@ public final class DefaultLoadControl implements LoadControl {
|
|||
|
||||
@Override
|
||||
public void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
|
||||
TrackSelectionArray trackSelections) {
|
||||
TrackSelections<?> trackSelections) {
|
||||
targetBufferSize = 0;
|
||||
for (int i = 0; i < renderers.length; i++) {
|
||||
if (trackSelections.get(i) != null) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import com.google.android.exoplayer2.source.MediaPeriod;
|
|||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelections;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MediaClock;
|
||||
|
|
@ -40,8 +40,8 @@ import java.io.IOException;
|
|||
/**
|
||||
* Implements the internal behavior of {@link ExoPlayerImpl}.
|
||||
*/
|
||||
/* package */ final class ExoPlayerImplInternal implements Handler.Callback, MediaPeriod.Callback,
|
||||
TrackSelector.InvalidationListener, MediaSource.Listener {
|
||||
/* package */ final class ExoPlayerImplInternal<T> implements Handler.Callback,
|
||||
MediaPeriod.Callback, TrackSelector.InvalidationListener, MediaSource.Listener {
|
||||
|
||||
/**
|
||||
* Playback position information which is read on the application's thread by
|
||||
|
|
@ -100,7 +100,7 @@ import java.io.IOException;
|
|||
|
||||
private final Renderer[] renderers;
|
||||
private final RendererCapabilities[] rendererCapabilities;
|
||||
private final TrackSelector trackSelector;
|
||||
private final TrackSelector<T> trackSelector;
|
||||
private final LoadControl loadControl;
|
||||
private final StandaloneMediaClock standaloneMediaClock;
|
||||
private final Handler handler;
|
||||
|
|
@ -128,13 +128,13 @@ import java.io.IOException;
|
|||
private boolean isTimelineReady;
|
||||
private boolean isTimelineEnded;
|
||||
private int bufferAheadPeriodCount;
|
||||
private MediaPeriodHolder playingPeriodHolder;
|
||||
private MediaPeriodHolder readingPeriodHolder;
|
||||
private MediaPeriodHolder loadingPeriodHolder;
|
||||
private MediaPeriodHolder<T> playingPeriodHolder;
|
||||
private MediaPeriodHolder<T> readingPeriodHolder;
|
||||
private MediaPeriodHolder<T> loadingPeriodHolder;
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
public ExoPlayerImplInternal(Renderer[] renderers, TrackSelector trackSelector,
|
||||
public ExoPlayerImplInternal(Renderer[] renderers, TrackSelector<T> trackSelector,
|
||||
LoadControl loadControl, boolean playWhenReady, Handler eventHandler,
|
||||
PlaybackInfo playbackInfo) {
|
||||
this.renderers = renderers;
|
||||
|
|
@ -538,8 +538,8 @@ import java.io.IOException;
|
|||
}
|
||||
|
||||
// Clear the timeline, but keep the requested period if it is already prepared.
|
||||
MediaPeriodHolder periodHolder = playingPeriodHolder;
|
||||
MediaPeriodHolder newPlayingPeriodHolder = null;
|
||||
MediaPeriodHolder<T> periodHolder = playingPeriodHolder;
|
||||
MediaPeriodHolder<T> newPlayingPeriodHolder = null;
|
||||
while (periodHolder != null) {
|
||||
if (periodHolder.index == periodIndex && periodHolder.prepared) {
|
||||
newPlayingPeriodHolder = periodHolder;
|
||||
|
|
@ -671,7 +671,7 @@ import java.io.IOException;
|
|||
return;
|
||||
}
|
||||
// Reselect tracks on each period in turn, until the selection changes.
|
||||
MediaPeriodHolder periodHolder = playingPeriodHolder;
|
||||
MediaPeriodHolder<T> periodHolder = playingPeriodHolder;
|
||||
boolean selectionsChangedForReadPeriod = true;
|
||||
while (true) {
|
||||
if (periodHolder == null || !periodHolder.prepared) {
|
||||
|
|
@ -738,7 +738,7 @@ import java.io.IOException;
|
|||
}
|
||||
}
|
||||
}
|
||||
trackSelector.onSelectionActivated(playingPeriodHolder.trackSelectionData);
|
||||
trackSelector.onSelectionActivated(playingPeriodHolder.trackSelections);
|
||||
enableRenderers(rendererWasEnabledFlags, enabledRendererCount);
|
||||
} else {
|
||||
// Release and re-prepare/buffer periods after the one whose selection changed.
|
||||
|
|
@ -810,11 +810,11 @@ import java.io.IOException;
|
|||
playingPeriodHolder.setIndex(timeline, timeline.getWindow(period.windowIndex, window),
|
||||
index);
|
||||
|
||||
MediaPeriodHolder previousPeriod = playingPeriodHolder;
|
||||
MediaPeriodHolder<T> previousPeriod = playingPeriodHolder;
|
||||
boolean seenReadingPeriod = false;
|
||||
bufferAheadPeriodCount = 0;
|
||||
while (previousPeriod.next != null) {
|
||||
MediaPeriodHolder periodHolder = previousPeriod.next;
|
||||
MediaPeriodHolder<T> periodHolder = previousPeriod.next;
|
||||
index++;
|
||||
timeline.getPeriod(index, period, true);
|
||||
if (!periodHolder.uid.equals(period.uid)) {
|
||||
|
|
@ -954,8 +954,9 @@ import java.io.IOException;
|
|||
Object newPeriodUid = timeline.getPeriod(newLoadingPeriodIndex, period, true).uid;
|
||||
MediaPeriod newMediaPeriod = mediaSource.createPeriod(newLoadingPeriodIndex, this,
|
||||
loadControl.getAllocator(), periodStartPositionUs);
|
||||
MediaPeriodHolder newPeriodHolder = new MediaPeriodHolder(renderers, rendererCapabilities,
|
||||
trackSelector, mediaSource, newMediaPeriod, newPeriodUid, periodStartPositionUs);
|
||||
MediaPeriodHolder<T> newPeriodHolder = new MediaPeriodHolder<>(renderers,
|
||||
rendererCapabilities, trackSelector, mediaSource, newMediaPeriod, newPeriodUid,
|
||||
periodStartPositionUs);
|
||||
timeline.getWindow(windowIndex, window);
|
||||
newPeriodHolder.setIndex(timeline, window, newLoadingPeriodIndex);
|
||||
if (loadingPeriodHolder != null) {
|
||||
|
|
@ -1012,9 +1013,9 @@ import java.io.IOException;
|
|||
}
|
||||
}
|
||||
if (readingPeriodHolder.next != null && readingPeriodHolder.next.prepared) {
|
||||
TrackSelectionArray oldTrackSelections = readingPeriodHolder.trackSelections;
|
||||
TrackSelections<T> oldTrackSelections = readingPeriodHolder.trackSelections;
|
||||
readingPeriodHolder = readingPeriodHolder.next;
|
||||
TrackSelectionArray newTrackSelections = readingPeriodHolder.trackSelections;
|
||||
TrackSelections<T> newTrackSelections = readingPeriodHolder.trackSelections;
|
||||
for (int i = 0; i < renderers.length; i++) {
|
||||
Renderer renderer = renderers[i];
|
||||
TrackSelection oldSelection = oldTrackSelections.get(i);
|
||||
|
|
@ -1088,14 +1089,15 @@ import java.io.IOException;
|
|||
}
|
||||
}
|
||||
|
||||
private void releasePeriodHoldersFrom(MediaPeriodHolder periodHolder) {
|
||||
private void releasePeriodHoldersFrom(MediaPeriodHolder<T> periodHolder) {
|
||||
while (periodHolder != null) {
|
||||
periodHolder.release();
|
||||
periodHolder = periodHolder.next;
|
||||
}
|
||||
}
|
||||
|
||||
private void setPlayingPeriodHolder(MediaPeriodHolder periodHolder) throws ExoPlaybackException {
|
||||
private void setPlayingPeriodHolder(MediaPeriodHolder<T> periodHolder)
|
||||
throws ExoPlaybackException {
|
||||
int enabledRendererCount = 0;
|
||||
boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
|
||||
for (int i = 0; i < renderers.length; i++) {
|
||||
|
|
@ -1118,7 +1120,7 @@ import java.io.IOException;
|
|||
}
|
||||
}
|
||||
|
||||
trackSelector.onSelectionActivated(periodHolder.trackSelectionData);
|
||||
trackSelector.onSelectionActivated(periodHolder.trackSelections);
|
||||
playingPeriodHolder = periodHolder;
|
||||
enableRenderers(rendererWasEnabledFlags, enabledRendererCount);
|
||||
}
|
||||
|
|
@ -1175,7 +1177,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* Holds a {@link MediaPeriod} with information required to play it as part of a timeline.
|
||||
*/
|
||||
private static final class MediaPeriodHolder {
|
||||
private static final class MediaPeriodHolder<T> {
|
||||
|
||||
public final MediaPeriod mediaPeriod;
|
||||
public final Object uid;
|
||||
|
|
@ -1189,21 +1191,20 @@ import java.io.IOException;
|
|||
public boolean prepared;
|
||||
public boolean hasEnabledTracks;
|
||||
public long rendererPositionOffsetUs;
|
||||
public MediaPeriodHolder next;
|
||||
public MediaPeriodHolder<T> next;
|
||||
public boolean needsContinueLoading;
|
||||
|
||||
private final Renderer[] renderers;
|
||||
private final RendererCapabilities[] rendererCapabilities;
|
||||
private final TrackSelector trackSelector;
|
||||
private final TrackSelector<T> trackSelector;
|
||||
private final MediaSource mediaSource;
|
||||
|
||||
private Object trackSelectionData;
|
||||
private TrackSelectionArray trackSelections;
|
||||
private TrackSelectionArray periodTrackSelections;
|
||||
private TrackSelections<T> trackSelections;
|
||||
private TrackSelections<T> periodTrackSelections;
|
||||
|
||||
public MediaPeriodHolder(Renderer[] renderers, RendererCapabilities[] rendererCapabilities,
|
||||
TrackSelector trackSelector, MediaSource mediaSource, MediaPeriod mediaPeriod, Object uid,
|
||||
long positionUs) {
|
||||
TrackSelector<T> trackSelector, MediaSource mediaSource, MediaPeriod mediaPeriod,
|
||||
Object uid, long positionUs) {
|
||||
this.renderers = renderers;
|
||||
this.rendererCapabilities = rendererCapabilities;
|
||||
this.trackSelector = trackSelector;
|
||||
|
|
@ -1215,7 +1216,7 @@ import java.io.IOException;
|
|||
startPositionUs = positionUs;
|
||||
}
|
||||
|
||||
public void setNext(MediaPeriodHolder next) {
|
||||
public void setNext(MediaPeriodHolder<T> next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
|
|
@ -1237,14 +1238,12 @@ import java.io.IOException;
|
|||
}
|
||||
|
||||
public boolean selectTracks() throws ExoPlaybackException {
|
||||
Pair<TrackSelectionArray, Object> result =
|
||||
trackSelector.selectTracks(rendererCapabilities, mediaPeriod.getTrackGroups());
|
||||
TrackSelectionArray newTrackSelections = result.first;
|
||||
TrackSelections<T> newTrackSelections = trackSelector.selectTracks(rendererCapabilities,
|
||||
mediaPeriod.getTrackGroups());
|
||||
if (newTrackSelections.equals(periodTrackSelections)) {
|
||||
return false;
|
||||
}
|
||||
trackSelections = newTrackSelections;
|
||||
trackSelectionData = result.second;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +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.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelections;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
||||
/**
|
||||
|
|
@ -31,10 +30,10 @@ public interface LoadControl {
|
|||
*
|
||||
* @param renderers The renderers.
|
||||
* @param trackGroups The {@link TrackGroup}s from which the selection was made.
|
||||
* @param trackSelections The {@link TrackSelection}s that were made.
|
||||
* @param trackSelections The track selections that were made.
|
||||
*/
|
||||
void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
|
||||
TrackSelectionArray trackSelections);
|
||||
TrackSelections<?> trackSelections);
|
||||
|
||||
/**
|
||||
* Called by the player when all tracks are disabled.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import com.google.android.exoplayer2.audio.AudioTrack;
|
|||
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
|
||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
||||
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
|
||||
import com.google.android.exoplayer2.metadata.MetadataRenderer;
|
||||
import com.google.android.exoplayer2.metadata.id3.Id3Decoder;
|
||||
|
|
@ -40,6 +41,7 @@ import com.google.android.exoplayer2.metadata.id3.Id3Frame;
|
|||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
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.TrackSelector;
|
||||
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
|
||||
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
||||
|
|
@ -80,18 +82,14 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
|
||||
/**
|
||||
* Called when a frame is rendered for the first time since setting the surface, and when a
|
||||
* frame is rendered for the first time since the renderer was reset.
|
||||
*
|
||||
* @param surface The {@link Surface} to which a first frame has been rendered.
|
||||
* frame is rendered for the first time since a video track was selected.
|
||||
*/
|
||||
void onRenderedFirstFrame(Surface surface);
|
||||
void onRenderedFirstFrame();
|
||||
|
||||
/**
|
||||
* Called when the renderer is disabled.
|
||||
*
|
||||
* @param counters {@link DecoderCounters} that were updated by the renderer.
|
||||
* Called when a video track is no longer selected.
|
||||
*/
|
||||
void onVideoDisabled(DecoderCounters counters);
|
||||
void onVideoTracksDisabled();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -105,9 +103,11 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
private final int videoRendererCount;
|
||||
private final int audioRendererCount;
|
||||
|
||||
private boolean videoTracksEnabled;
|
||||
private Format videoFormat;
|
||||
private Format audioFormat;
|
||||
|
||||
private Surface surface;
|
||||
private SurfaceHolder surfaceHolder;
|
||||
private TextureView textureView;
|
||||
private TextRenderer.Output textOutput;
|
||||
|
|
@ -121,11 +121,12 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
private float volume;
|
||||
private PlaybackParamsHolder playbackParamsHolder;
|
||||
|
||||
/* package */ SimpleExoPlayer(Context context, TrackSelector trackSelector,
|
||||
LoadControl loadControl, DrmSessionManager drmSessionManager,
|
||||
/* 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<>();
|
||||
|
|
@ -509,8 +510,9 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
|
||||
// Internal methods.
|
||||
|
||||
private void buildRenderers(Context context, DrmSessionManager drmSessionManager,
|
||||
ArrayList<Renderer> renderersList, long allowedVideoJoiningTimeMs) {
|
||||
private void buildRenderers(Context context,
|
||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, ArrayList<Renderer> renderersList,
|
||||
long allowedVideoJoiningTimeMs) {
|
||||
MediaCodecVideoRenderer videoRenderer = new MediaCodecVideoRenderer(context,
|
||||
MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT,
|
||||
allowedVideoJoiningTimeMs, drmSessionManager, false, mainHandler, componentListener,
|
||||
|
|
@ -601,6 +603,7 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
}
|
||||
|
||||
private void setVideoSurfaceInternal(Surface surface) {
|
||||
this.surface = surface;
|
||||
ExoPlayerMessage[] messages = new ExoPlayerMessage[videoRendererCount];
|
||||
int count = 0;
|
||||
for (Renderer renderer : renderers) {
|
||||
|
|
@ -618,7 +621,8 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
|
||||
private final class ComponentListener implements VideoRendererEventListener,
|
||||
AudioRendererEventListener, TextRenderer.Output, MetadataRenderer.Output<List<Id3Frame>>,
|
||||
SurfaceHolder.Callback, TextureView.SurfaceTextureListener {
|
||||
SurfaceHolder.Callback, TextureView.SurfaceTextureListener,
|
||||
TrackSelector.EventListener<Object> {
|
||||
|
||||
// VideoRendererEventListener implementation
|
||||
|
||||
|
|
@ -669,8 +673,8 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
|
||||
@Override
|
||||
public void onRenderedFirstFrame(Surface surface) {
|
||||
if (videoListener != null) {
|
||||
videoListener.onRenderedFirstFrame(surface);
|
||||
if (videoListener != null && SimpleExoPlayer.this.surface == surface) {
|
||||
videoListener.onRenderedFirstFrame();
|
||||
}
|
||||
if (videoDebugListener != null) {
|
||||
videoDebugListener.onRenderedFirstFrame(surface);
|
||||
|
|
@ -679,9 +683,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
|||
|
||||
@Override
|
||||
public void onVideoDisabled(DecoderCounters counters) {
|
||||
if (videoListener != null) {
|
||||
videoListener.onVideoDisabled(counters);
|
||||
}
|
||||
if (videoDebugListener != null) {
|
||||
videoDebugListener.onVideoDisabled(counters);
|
||||
}
|
||||
|
|
@ -800,6 +801,23 @@ 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)
|
||||
|
|
|
|||
|
|
@ -453,10 +453,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
case C.TRACK_TYPE_VIDEO:
|
||||
rendererTrackSelections[i] = selectVideoTrack(rendererCapabilities[i],
|
||||
rendererTrackGroupArrays[i], rendererFormatSupports[i], params.maxVideoWidth,
|
||||
params.maxVideoHeight,
|
||||
params.allowNonSeamlessAdaptiveness, params.allowMixedMimeAdaptiveness,
|
||||
params.viewportWidth, params.viewportHeight, params.orientationMayChange,
|
||||
adaptiveVideoTrackSelectionFactory, params.exceedVideoConstraintsIfNecessary);
|
||||
params.maxVideoHeight, params.allowNonSeamlessAdaptiveness,
|
||||
params.allowMixedMimeAdaptiveness, params.viewportWidth, params.viewportHeight,
|
||||
params.orientationMayChange, adaptiveVideoTrackSelectionFactory,
|
||||
params.exceedVideoConstraintsIfNecessary);
|
||||
break;
|
||||
case C.TRACK_TYPE_AUDIO:
|
||||
rendererTrackSelections[i] = selectAudioTrack(rendererTrackGroupArrays[i],
|
||||
|
|
|
|||
|
|
@ -16,39 +16,23 @@
|
|||
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.util.Assertions;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Listener of {@link MappingTrackSelector} events.
|
||||
*/
|
||||
public interface EventListener {
|
||||
|
||||
/**
|
||||
* Called when the track information has changed.
|
||||
*
|
||||
* @param trackInfo Contains the new track and track selection information.
|
||||
*/
|
||||
void onTracksChanged(TrackInfo trackInfo);
|
||||
|
||||
}
|
||||
public abstract class MappingTrackSelector extends TrackSelector<MappedTrackInfo> {
|
||||
|
||||
/**
|
||||
* A track selection override.
|
||||
|
|
@ -96,51 +80,19 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
|
||||
}
|
||||
|
||||
private final Handler eventHandler;
|
||||
private final CopyOnWriteArraySet<EventListener> listeners;
|
||||
private final SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides;
|
||||
private final SparseBooleanArray rendererDisabledFlags;
|
||||
|
||||
private TrackInfo activeTrackInfo;
|
||||
|
||||
/**
|
||||
* @param eventHandler A handler to use when delivering events to listeners added via
|
||||
* {@link #addListener(EventListener)}.
|
||||
*/
|
||||
public MappingTrackSelector(Handler eventHandler) {
|
||||
this.eventHandler = eventHandler;
|
||||
this.listeners = new CopyOnWriteArraySet<>();
|
||||
super(eventHandler);
|
||||
selectionOverrides = new SparseArray<>();
|
||||
rendererDisabledFlags = new SparseBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register 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 listener) {
|
||||
Assertions.checkState(eventHandler != null);
|
||||
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 listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the current tracks and track selection for each renderer.
|
||||
*/
|
||||
public final TrackInfo getTrackInfo() {
|
||||
return activeTrackInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the renderer at the specified index is disabled.
|
||||
*
|
||||
|
|
@ -272,13 +224,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
// TrackSelector implementation.
|
||||
|
||||
@Override
|
||||
public final void onSelectionActivated(Object selectionInfo) {
|
||||
activeTrackInfo = (TrackInfo) selectionInfo;
|
||||
notifyTrackInfoChanged(activeTrackInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Pair<TrackSelectionArray, Object> selectTracks(
|
||||
public final TrackSelections<MappedTrackInfo> selectTracks(
|
||||
RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups)
|
||||
throws ExoPlaybackException {
|
||||
// Structures into which data will be written during the selection. The extra item at the end
|
||||
|
|
@ -345,11 +291,10 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
}
|
||||
|
||||
// Package up the track information and selections.
|
||||
TrackSelectionArray trackSelectionArray = new TrackSelectionArray(trackSelections);
|
||||
TrackInfo trackInfo = new TrackInfo(rendererTrackTypes, rendererTrackGroupArrays,
|
||||
trackSelections, mixedMimeTypeAdaptationSupport, rendererFormatSupports,
|
||||
MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererTrackTypes,
|
||||
rendererTrackGroupArrays, mixedMimeTypeAdaptationSupport, rendererFormatSupports,
|
||||
unassociatedTrackGroupArray);
|
||||
return Pair.<TrackSelectionArray, Object>create(trackSelectionArray, trackInfo);
|
||||
return new TrackSelections<>(mappedTrackInfo, trackSelections);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -446,23 +391,10 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
return mixedMimeTypeAdaptationSupport;
|
||||
}
|
||||
|
||||
private void notifyTrackInfoChanged(final TrackInfo trackInfo) {
|
||||
if (eventHandler != null) {
|
||||
eventHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (EventListener listener : listeners) {
|
||||
listener.onTracksChanged(trackInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides track information for each renderer.
|
||||
*/
|
||||
public static final class TrackInfo {
|
||||
public static final class MappedTrackInfo {
|
||||
|
||||
/**
|
||||
* The renderer does not have any associated tracks.
|
||||
|
|
@ -477,34 +409,27 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
*/
|
||||
public static final int RENDERER_SUPPORT_PLAYABLE_TRACKS = 2;
|
||||
|
||||
/**
|
||||
* The number of renderers.
|
||||
*/
|
||||
public final int rendererCount;
|
||||
|
||||
private final int[] rendererTrackTypes;
|
||||
private final TrackGroupArray[] trackGroups;
|
||||
private final TrackSelection[] trackSelections;
|
||||
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.
|
||||
* @param trackGroups The {@link TrackGroupArray}s for each renderer.
|
||||
* @param trackSelections The current {@link TrackSelection}s for each renderer.
|
||||
* @param mixedMimeTypeAdaptiveSupport The result of
|
||||
* {@link RendererCapabilities#supportsMixedMimeTypeAdaptation()} for each renderer.
|
||||
* @param formatSupport The result of {@link RendererCapabilities#supportsFormat} for each
|
||||
* track, indexed by renderer index, group index and track index (in that order).
|
||||
* @param unassociatedTrackGroups Contains {@link TrackGroup}s not associated with any renderer.
|
||||
*/
|
||||
/* package */ TrackInfo(int[] rendererTrackTypes, TrackGroupArray[] trackGroups,
|
||||
TrackSelection[] trackSelections, int[] mixedMimeTypeAdaptiveSupport,
|
||||
/* package */ MappedTrackInfo(int[] rendererTrackTypes,
|
||||
TrackGroupArray[] trackGroups, int[] mixedMimeTypeAdaptiveSupport,
|
||||
int[][][] formatSupport, TrackGroupArray unassociatedTrackGroups) {
|
||||
this.rendererTrackTypes = rendererTrackTypes;
|
||||
this.trackGroups = trackGroups;
|
||||
this.trackSelections = trackSelections;
|
||||
this.formatSupport = formatSupport;
|
||||
this.mixedMimeTypeAdaptiveSupport = mixedMimeTypeAdaptiveSupport;
|
||||
this.unassociatedTrackGroups = unassociatedTrackGroups;
|
||||
|
|
@ -521,16 +446,6 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
return trackGroups[rendererIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current {@link TrackSelection} for the renderer at a specified index.
|
||||
*
|
||||
* @param rendererIndex The renderer index.
|
||||
* @return The corresponding {@link TrackSelection}, or null if the renderer is disabled.
|
||||
*/
|
||||
public TrackSelection getTrackSelection(int rendererIndex) {
|
||||
return trackSelections[rendererIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extent to which a renderer can support playback of the tracks associated to it.
|
||||
*
|
||||
|
|
@ -657,7 +572,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
* unplayable. False in all other cases.
|
||||
*/
|
||||
public boolean hasOnlyUnplayableTracks(int trackType) {
|
||||
int rendererSupport = TrackInfo.RENDERER_SUPPORT_NO_TRACKS;
|
||||
int rendererSupport = RENDERER_SUPPORT_NO_TRACKS;
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
if (rendererTrackTypes[i] == trackType) {
|
||||
rendererSupport = Math.max(rendererSupport, getRendererSupport(i));
|
||||
|
|
|
|||
|
|
@ -18,12 +18,16 @@ package com.google.android.exoplayer2.trackselection;
|
|||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* An array of {@link TrackSelection}s generated by a {@link TrackSelector}.
|
||||
* The result of a {@link TrackSelector} operation.
|
||||
*/
|
||||
public final class TrackSelectionArray {
|
||||
public final class TrackSelections<T> {
|
||||
|
||||
/**
|
||||
* The number of selections in the array. Greater than or equal to zero.
|
||||
* 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;
|
||||
|
||||
|
|
@ -33,9 +37,11 @@ public final class TrackSelectionArray {
|
|||
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 TrackSelectionArray(TrackSelection... trackSelections) {
|
||||
public TrackSelections(T info, TrackSelection... trackSelections) {
|
||||
this.info = info;
|
||||
this.trackSelections = trackSelections;
|
||||
this.length = trackSelections.length;
|
||||
}
|
||||
|
|
@ -75,7 +81,7 @@ public final class TrackSelectionArray {
|
|||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TrackSelectionArray other = (TrackSelectionArray) obj;
|
||||
TrackSelections<?> other = (TrackSelections<?>) obj;
|
||||
return Arrays.equals(trackSelections, other.trackSelections);
|
||||
}
|
||||
|
||||
|
|
@ -15,15 +15,15 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.trackselection;
|
||||
|
||||
import android.util.Pair;
|
||||
import android.os.Handler;
|
||||
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 {
|
||||
/** Selects tracks to be consumed by available renderers. */
|
||||
public abstract class TrackSelector<T> {
|
||||
|
||||
/**
|
||||
* Notified when previous selections by a {@link TrackSelector} are no longer valid.
|
||||
|
|
@ -37,7 +37,55 @@ public abstract class TrackSelector {
|
|||
|
||||
}
|
||||
|
||||
/** 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.
|
||||
|
|
@ -49,31 +97,28 @@ public abstract class TrackSelector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a {@link TrackSelection} for each renderer.
|
||||
* <P>
|
||||
* The selections are returned in a {@link TrackSelectionArray}, together with an opaque object
|
||||
* that the selector wishes to receive in an invocation of {@link #onSelectionActivated(Object)}
|
||||
* should the selection be activated.
|
||||
* Generates {@link TrackSelections} 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 A {@link TrackSelectionArray} containing a {@link TrackSelection} for each renderer,
|
||||
* together with an opaque object that will be passed to {@link #onSelectionActivated(Object)}
|
||||
* if the selection is activated.
|
||||
* @return The track selections.
|
||||
* @throws ExoPlaybackException If an error occurs selecting tracks.
|
||||
*/
|
||||
public abstract Pair<TrackSelectionArray, Object> selectTracks(
|
||||
public abstract TrackSelections<T> selectTracks(
|
||||
RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups)
|
||||
throws ExoPlaybackException;
|
||||
|
||||
/**
|
||||
* Called when a selection previously generated by
|
||||
* {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} is activated.
|
||||
* Called when {@link TrackSelections} previously generated by {@link
|
||||
* #selectTracks(RendererCapabilities[], TrackGroupArray)} are activated.
|
||||
*
|
||||
* @param selectionInfo The opaque object associated with the selection.
|
||||
* @param activeSelections The activated {@link TrackSelections}.
|
||||
*/
|
||||
public abstract void onSelectionActivated(Object selectionInfo);
|
||||
public final void onSelectionActivated(TrackSelections<T> activeSelections) {
|
||||
this.activeSelections = activeSelections;
|
||||
notifyTrackSelectionsChanged(activeSelections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates all previously generated track selections.
|
||||
|
|
@ -84,4 +129,18 @@ public abstract class TrackSelector {
|
|||
}
|
||||
}
|
||||
|
||||
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,22 +22,18 @@ import android.util.AttributeSet;
|
|||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
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.decoder.DecoderCounters;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextRenderer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -112,7 +108,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||
this.player.setVideoSurface(null);
|
||||
}
|
||||
this.player = player;
|
||||
|
||||
if (player != null) {
|
||||
if (surfaceView instanceof TextureView) {
|
||||
player.setVideoTextureView((TextureView) surfaceView);
|
||||
|
|
@ -122,6 +117,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||
player.setVideoListener(componentListener);
|
||||
player.addListener(componentListener);
|
||||
player.setTextOutput(componentListener);
|
||||
} else {
|
||||
shutterView.setVisibility(VISIBLE);
|
||||
}
|
||||
setUseController(useController);
|
||||
}
|
||||
|
|
@ -233,12 +230,12 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onRenderedFirstFrame(Surface surface) {
|
||||
public void onRenderedFirstFrame() {
|
||||
shutterView.setVisibility(GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoDisabled(DecoderCounters counters) {
|
||||
public void onVideoTracksDisabled() {
|
||||
shutterView.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue