diff --git a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index ab4e59e08f..55dd0f57ed 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -22,12 +22,12 @@ import android.os.Message; import android.util.Log; import com.google.android.exoplayer2.ExoPlayerImplInternal.PlaybackInfo; import com.google.android.exoplayer2.ExoPlayerImplInternal.SourceInfo; -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.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; import java.util.concurrent.CopyOnWriteArraySet; @@ -319,11 +319,11 @@ import java.util.concurrent.CopyOnWriteArraySet; break; } case ExoPlayerImplInternal.MSG_TRACKS_CHANGED: { - TrackInfo trackInfo = (TrackInfo) msg.obj; + TrackSelectorResult trackSelectorResult = (TrackSelectorResult) msg.obj; tracksSelected = true; - trackGroups = trackInfo.groups; - trackSelections = trackInfo.selections; - trackSelector.onSelectionActivated(trackInfo.info); + trackGroups = trackSelectorResult.groups; + trackSelections = trackSelectorResult.selections; + trackSelector.onSelectionActivated(trackSelectorResult.info); for (EventListener listener : listeners) { listener.onTracksChanged(trackGroups, trackSelections); } diff --git a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index d82ef7e14b..ba4a729f78 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -26,10 +26,10 @@ import com.google.android.exoplayer2.ExoPlayer.ExoPlayerMessage; 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.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.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.PriorityHandlerThread; @@ -72,20 +72,6 @@ import java.io.IOException; } - public static final class TrackInfo { - - public final TrackGroupArray groups; - public final TrackSelectionArray selections; - public final Object info; - - public TrackInfo(TrackGroupArray groups, TrackSelectionArray selections, Object info) { - this.groups = groups; - this.selections = selections; - this.info = info; - } - - } - public static final class SourceInfo { public final Timeline timeline; @@ -799,7 +785,8 @@ import java.io.IOException; } } } - eventHandler.obtainMessage(MSG_TRACKS_CHANGED, periodHolder.getTrackInfo()).sendToTarget(); + eventHandler.obtainMessage(MSG_TRACKS_CHANGED, periodHolder.trackSelectorResult) + .sendToTarget(); enableRenderers(rendererWasEnabledFlags, enabledRendererCount); } else { // Release and re-prepare/buffer periods after the one whose selection changed. @@ -1161,9 +1148,9 @@ import java.io.IOException; } if (readingPeriodHolder.next != null && readingPeriodHolder.next.prepared) { - TrackSelectionArray oldTrackSelections = readingPeriodHolder.trackSelections; + TrackSelectionArray oldTrackSelections = readingPeriodHolder.trackSelectorResult.selections; readingPeriodHolder = readingPeriodHolder.next; - TrackSelectionArray newTrackSelections = readingPeriodHolder.trackSelections; + TrackSelectionArray newTrackSelections = readingPeriodHolder.trackSelectorResult.selections; boolean initialDiscontinuity = readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET; @@ -1330,7 +1317,7 @@ import java.io.IOException; for (int i = 0; i < renderers.length; i++) { Renderer renderer = renderers[i]; rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED; - TrackSelection newSelection = periodHolder.trackSelections.get(i); + TrackSelection newSelection = periodHolder.trackSelectorResult.selections.get(i); if (newSelection != null) { enabledRendererCount++; } @@ -1352,7 +1339,7 @@ import java.io.IOException; } playingPeriodHolder = periodHolder; - eventHandler.obtainMessage(MSG_TRACKS_CHANGED, periodHolder.getTrackInfo()).sendToTarget(); + eventHandler.obtainMessage(MSG_TRACKS_CHANGED, periodHolder.trackSelectorResult).sendToTarget(); enableRenderers(rendererWasEnabledFlags, enabledRendererCount); } @@ -1362,7 +1349,7 @@ import java.io.IOException; enabledRendererCount = 0; for (int i = 0; i < renderers.length; i++) { Renderer renderer = renderers[i]; - TrackSelection newSelection = playingPeriodHolder.trackSelections.get(i); + TrackSelection newSelection = playingPeriodHolder.trackSelectorResult.selections.get(i); if (newSelection != null) { enabledRenderers[enabledRendererCount++] = renderer; if (renderer.getState() == Renderer.STATE_DISABLED) { @@ -1414,6 +1401,7 @@ import java.io.IOException; public boolean hasEnabledTracks; public MediaPeriodHolder next; public boolean needsContinueLoading; + public TrackSelectorResult trackSelectorResult; private final Renderer[] renderers; private final RendererCapabilities[] rendererCapabilities; @@ -1421,9 +1409,6 @@ import java.io.IOException; private final LoadControl loadControl; private final MediaSource mediaSource; - private Object trackSelectionsInfo; - private TrackGroupArray trackGroups; - private TrackSelectionArray trackSelections; private TrackSelectionArray periodTrackSelections; public MediaPeriodHolder(Renderer[] renderers, RendererCapabilities[] rendererCapabilities, @@ -1470,20 +1455,18 @@ import java.io.IOException; public void handlePrepared() throws ExoPlaybackException { prepared = true; - trackGroups = mediaPeriod.getTrackGroups(); selectTracks(); startPositionUs = updatePeriodTrackSelection(startPositionUs, false); } public boolean selectTracks() throws ExoPlaybackException { - Pair selectorResult = trackSelector.selectTracks( - rendererCapabilities, trackGroups); - TrackSelectionArray newTrackSelections = selectorResult.first; + TrackSelectorResult selectorResult = trackSelector.selectTracks(rendererCapabilities, + mediaPeriod.getTrackGroups()); + TrackSelectionArray newTrackSelections = selectorResult.selections; if (newTrackSelections.equals(periodTrackSelections)) { return false; } - trackSelections = newTrackSelections; - trackSelectionsInfo = selectorResult.second; + trackSelectorResult = selectorResult; return true; } @@ -1494,6 +1477,7 @@ import java.io.IOException; public long updatePeriodTrackSelection(long positionUs, boolean forceRecreateStreams, boolean[] streamResetFlags) { + TrackSelectionArray trackSelections = trackSelectorResult.selections; for (int i = 0; i < trackSelections.length; i++) { mayRetainStreamFlags[i] = !forceRecreateStreams && Util.areEqual(periodTrackSelections == null ? null : periodTrackSelections.get(i), @@ -1517,14 +1501,10 @@ import java.io.IOException; } // The track selection has changed. - loadControl.onTracksSelected(renderers, trackGroups, trackSelections); + loadControl.onTracksSelected(renderers, trackSelectorResult.groups, trackSelections); return positionUs; } - public TrackInfo getTrackInfo() { - return new TrackInfo(trackGroups, trackSelections, trackSelectionsInfo); - } - public void release() { try { mediaSource.releasePeriod(mediaPeriod); diff --git a/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java b/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java index fc1ee567aa..59b70965b8 100644 --- a/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java @@ -876,6 +876,7 @@ public final class AudioTrack { framesPerEncodedSample = 0; currentSourceBuffer = null; avSyncHeader = null; + bytesUntilNextAvSync = 0; startMediaTimeState = START_NOT_SET; latencyUs = 0; resetSyncParams(); diff --git a/library/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java b/library/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java index 0dda5656b7..3eb44d1d05 100644 --- a/library/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java +++ b/library/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java @@ -15,7 +15,6 @@ */ package com.google.android.exoplayer2.trackselection; -import android.util.Pair; import android.util.SparseArray; import android.util.SparseBooleanArray; import com.google.android.exoplayer2.C; @@ -227,9 +226,8 @@ public abstract class MappingTrackSelector extends TrackSelector { // TrackSelector implementation. @Override - public final Pair selectTracks( - RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups) - throws ExoPlaybackException { + public final TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, + TrackGroupArray trackGroups) throws ExoPlaybackException { // Structures into which data will be written during the selection. The extra item at the end // of each array is to store data associated with track groups that cannot be associated with // any renderer. @@ -297,7 +295,7 @@ public abstract class MappingTrackSelector extends TrackSelector { MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererTrackTypes, rendererTrackGroupArrays, mixedMimeTypeAdaptationSupport, rendererFormatSupports, unassociatedTrackGroupArray); - return Pair.create(new TrackSelectionArray(trackSelections), + return new TrackSelectorResult(trackGroups, new TrackSelectionArray(trackSelections), mappedTrackInfo); } diff --git a/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java b/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java index 5a9d3923bf..6c9fbfcb00 100644 --- a/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java +++ b/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java @@ -15,7 +15,6 @@ */ package com.google.android.exoplayer2.trackselection; -import android.util.Pair; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.source.TrackGroupArray; @@ -47,25 +46,22 @@ public abstract class TrackSelector { } /** - * Generates {@link TrackSelectionArray} for the renderers. + * Performs a track selection for 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 tracks + * are to be selected. * @param trackGroups The available track groups. - * @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. + * @return A {@link TrackSelectorResult} describing the track selections. * @throws ExoPlaybackException If an error occurs selecting tracks. */ - public abstract Pair selectTracks( - RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups) - throws ExoPlaybackException; + public abstract TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, + TrackGroupArray trackGroups) throws ExoPlaybackException; /** - * Called when {@link TrackSelectionArray} previously generated by - * {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} are activated. + * Called when a {@link TrackSelectorResult} previously generated by + * {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} is activated. * - * @param info The information associated with the selections, or null if the selected tracks are - * being cleared. + * @param info The value of {@link TrackSelectorResult#info} in the activated result. */ public abstract void onSelectionActivated(Object info); diff --git a/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java b/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java new file mode 100644 index 0000000000..84e4aad86a --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.trackselection; + +import com.google.android.exoplayer2.source.TrackGroupArray; + +/** + * The result of a {@link TrackSelector} operation. + */ +public final class TrackSelectorResult { + + /** + * The groups provided to the {@link TrackSelector}. + */ + public final TrackGroupArray groups; + /** + * A {@link TrackSelectionArray} containing the selection for each renderer. + */ + public final TrackSelectionArray selections; + /** + * An opaque object that will be returned to {@link TrackSelector#onSelectionActivated(Object)} + * should the selections be activated. + */ + public final Object info; + + /** + * @param groups The groups provided to the {@link TrackSelector}. + * @param selections A {@link TrackSelectionArray} containing the selection for each renderer. + * @param info An opaque object that will be returned to + * {@link TrackSelector#onSelectionActivated(Object)} should the selections be activated. + */ + public TrackSelectorResult(TrackGroupArray groups, TrackSelectionArray selections, Object info) { + this.groups = groups; + this.selections = selections; + this.info = info; + } + +}