mirror of
https://github.com/androidx/media.git
synced 2025-05-10 00:59:51 +08:00
Notify TrackSelection when it's enabled and disabled.
Add onEnable() and onDisable() call-backs to TrackSelection. This allows TrackSelection to perform interesting operations (like subscribe to NetworkStatus) and clean up after itself. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=175558485
This commit is contained in:
parent
877c89a0e1
commit
5bf4c249a2
@ -28,6 +28,8 @@ import com.google.android.exoplayer2.testutil.FakeRenderer;
|
|||||||
import com.google.android.exoplayer2.testutil.FakeShuffleOrder;
|
import com.google.android.exoplayer2.testutil.FakeShuffleOrder;
|
||||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||||
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
||||||
|
import com.google.android.exoplayer2.testutil.FakeTrackSelection;
|
||||||
|
import com.google.android.exoplayer2.testutil.FakeTrackSelector;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@ -311,4 +313,143 @@ public final class ExoPlayerTest extends TestCase {
|
|||||||
assertEquals(Player.STATE_BUFFERING, (int) playbackStatesWhenSeekProcessed.get(2));
|
assertEquals(Player.STATE_BUFFERING, (int) playbackStatesWhenSeekProcessed.get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAllActivatedTrackSelectionAreReleasedForSinglePeriod() throws Exception {
|
||||||
|
Timeline timeline =
|
||||||
|
new FakeTimeline(new TimelineWindowDefinition(false, false, /* durationUs= */ 500_000));
|
||||||
|
MediaSource mediaSource =
|
||||||
|
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||||
|
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
|
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||||
|
FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||||
|
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setMediaSource(mediaSource)
|
||||||
|
.setRenderers(videoRenderer, audioRenderer)
|
||||||
|
.setTrackSelector(trackSelector)
|
||||||
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
||||||
|
List<FakeTrackSelection> createdTrackSelections = trackSelector.getSelectedTrackSelections();
|
||||||
|
int numSelectionsEnabled = 0;
|
||||||
|
// Assert that all tracks selection are disabled at the end of the playback.
|
||||||
|
for (FakeTrackSelection trackSelection : createdTrackSelections) {
|
||||||
|
assertFalse(trackSelection.isEnabled);
|
||||||
|
numSelectionsEnabled += trackSelection.enableCount;
|
||||||
|
}
|
||||||
|
// There are 2 renderers, and track selections are made once (1 period).
|
||||||
|
// Track selections are not reused, so there are 2 track selections made.
|
||||||
|
assertEquals(2, createdTrackSelections.size());
|
||||||
|
// There should be 2 track selections enabled in total.
|
||||||
|
assertEquals(2, numSelectionsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllActivatedTrackSelectionAreReleasedForMultiPeriods() throws Exception {
|
||||||
|
Timeline timeline =
|
||||||
|
new FakeTimeline(new TimelineWindowDefinition(false, false, /* durationUs= */ 500_000),
|
||||||
|
new TimelineWindowDefinition(false, false, /* durationUs= */ 500_000));
|
||||||
|
MediaSource mediaSource =
|
||||||
|
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||||
|
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
|
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||||
|
FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||||
|
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setMediaSource(mediaSource)
|
||||||
|
.setRenderers(videoRenderer, audioRenderer)
|
||||||
|
.setTrackSelector(trackSelector)
|
||||||
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
||||||
|
List<FakeTrackSelection> createdTrackSelections = trackSelector.getSelectedTrackSelections();
|
||||||
|
int numSelectionsEnabled = 0;
|
||||||
|
// Assert that all tracks selection are disabled at the end of the playback.
|
||||||
|
for (FakeTrackSelection trackSelection : createdTrackSelections) {
|
||||||
|
assertFalse(trackSelection.isEnabled);
|
||||||
|
numSelectionsEnabled += trackSelection.enableCount;
|
||||||
|
}
|
||||||
|
// There are 2 renderers, and track selections are made twice (2 periods).
|
||||||
|
// Track selections are not reused, so there are 4 track selections made.
|
||||||
|
assertEquals(4, createdTrackSelections.size());
|
||||||
|
// There should be 4 track selections enabled in total.
|
||||||
|
assertEquals(4, numSelectionsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllActivatedTrackSelectionAreReleasedWhenTrackSelectionsAreRemade()
|
||||||
|
throws Exception {
|
||||||
|
Timeline timeline =
|
||||||
|
new FakeTimeline(new TimelineWindowDefinition(false, false, /* durationUs= */ 500_000));
|
||||||
|
MediaSource mediaSource =
|
||||||
|
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||||
|
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
|
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||||
|
final FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||||
|
ActionSchedule disableTrackAction = new ActionSchedule.Builder("testChangeTrackSelection")
|
||||||
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
|
.executeRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
trackSelector.setRendererDisabled(0, true);
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setMediaSource(mediaSource)
|
||||||
|
.setRenderers(videoRenderer, audioRenderer)
|
||||||
|
.setTrackSelector(trackSelector)
|
||||||
|
.setActionSchedule(disableTrackAction)
|
||||||
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
||||||
|
List<FakeTrackSelection> createdTrackSelections = trackSelector.getSelectedTrackSelections();
|
||||||
|
int numSelectionsEnabled = 0;
|
||||||
|
// Assert that all tracks selection are disabled at the end of the playback.
|
||||||
|
for (FakeTrackSelection trackSelection : createdTrackSelections) {
|
||||||
|
assertFalse(trackSelection.isEnabled);
|
||||||
|
numSelectionsEnabled += trackSelection.enableCount;
|
||||||
|
}
|
||||||
|
// There are 2 renderers, and track selections are made twice.
|
||||||
|
// Track selections are not reused, so there are 4 track selections made.
|
||||||
|
assertEquals(4, createdTrackSelections.size());
|
||||||
|
// Initially there are 2 track selections enabled.
|
||||||
|
// The second time one renderer is disabled, so only 1 track selection should be enabled.
|
||||||
|
assertEquals(3, numSelectionsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllActivatedTrackSelectionAreReleasedWhenTrackSelectionsAreUsed()
|
||||||
|
throws Exception {
|
||||||
|
Timeline timeline =
|
||||||
|
new FakeTimeline(new TimelineWindowDefinition(false, false, /* durationUs= */ 500_000));
|
||||||
|
MediaSource mediaSource =
|
||||||
|
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||||
|
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
|
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||||
|
final FakeTrackSelector trackSelector = new FakeTrackSelector(/* reuse track selection */ true);
|
||||||
|
ActionSchedule disableTrackAction = new ActionSchedule.Builder("testReuseTrackSelection")
|
||||||
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
|
.executeRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
trackSelector.setRendererDisabled(0, true);
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setMediaSource(mediaSource)
|
||||||
|
.setRenderers(videoRenderer, audioRenderer)
|
||||||
|
.setTrackSelector(trackSelector)
|
||||||
|
.setActionSchedule(disableTrackAction)
|
||||||
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
||||||
|
List<FakeTrackSelection> createdTrackSelections = trackSelector.getSelectedTrackSelections();
|
||||||
|
int numSelectionsEnabled = 0;
|
||||||
|
// Assert that all tracks selection are disabled at the end of the playback.
|
||||||
|
for (FakeTrackSelection trackSelection : createdTrackSelections) {
|
||||||
|
assertFalse(trackSelection.isEnabled);
|
||||||
|
numSelectionsEnabled += trackSelection.enableCount;
|
||||||
|
}
|
||||||
|
// There are 2 renderers, and track selections are made twice.
|
||||||
|
// TrackSelections are reused, so there are only 2 track selections made for 2 renderers.
|
||||||
|
assertEquals(2, createdTrackSelections.size());
|
||||||
|
// Initially there are 2 track selections enabled.
|
||||||
|
// The second time one renderer is disabled, so only 1 track selection should be enabled.
|
||||||
|
assertEquals(3, numSelectionsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1666,11 +1666,11 @@ import java.io.IOException;
|
|||||||
// Undo the effect of previous call to associate no-sample renderers with empty tracks
|
// Undo the effect of previous call to associate no-sample renderers with empty tracks
|
||||||
// so the mediaPeriod receives back whatever it sent us before.
|
// so the mediaPeriod receives back whatever it sent us before.
|
||||||
disassociateNoSampleRenderersWithEmptySampleStream(sampleStreams);
|
disassociateNoSampleRenderersWithEmptySampleStream(sampleStreams);
|
||||||
|
updatePeriodTrackSelectorResult(trackSelectorResult);
|
||||||
// Disable streams on the period and get new streams for updated/newly-enabled tracks.
|
// Disable streams on the period and get new streams for updated/newly-enabled tracks.
|
||||||
positionUs = mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags,
|
positionUs = mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags,
|
||||||
sampleStreams, streamResetFlags, positionUs);
|
sampleStreams, streamResetFlags, positionUs);
|
||||||
associateNoSampleRenderersWithEmptySampleStream(sampleStreams);
|
associateNoSampleRenderersWithEmptySampleStream(sampleStreams);
|
||||||
periodTrackSelectorResult = trackSelectorResult;
|
|
||||||
|
|
||||||
// Update whether we have enabled tracks and sanity check the expected streams are non-null.
|
// Update whether we have enabled tracks and sanity check the expected streams are non-null.
|
||||||
hasEnabledTracks = false;
|
hasEnabledTracks = false;
|
||||||
@ -1692,6 +1692,7 @@ import java.io.IOException;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void release() {
|
public void release() {
|
||||||
|
updatePeriodTrackSelectorResult(null);
|
||||||
try {
|
try {
|
||||||
if (info.endPositionUs != C.TIME_END_OF_SOURCE) {
|
if (info.endPositionUs != C.TIME_END_OF_SOURCE) {
|
||||||
mediaSource.releasePeriod(((ClippingMediaPeriod) mediaPeriod).mediaPeriod);
|
mediaSource.releasePeriod(((ClippingMediaPeriod) mediaPeriod).mediaPeriod);
|
||||||
@ -1704,6 +1705,36 @@ import java.io.IOException;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updatePeriodTrackSelectorResult(TrackSelectorResult trackSelectorResult) {
|
||||||
|
if (periodTrackSelectorResult != null) {
|
||||||
|
disableTrackSelectionsInResult(periodTrackSelectorResult);
|
||||||
|
}
|
||||||
|
periodTrackSelectorResult = trackSelectorResult;
|
||||||
|
if (periodTrackSelectorResult != null) {
|
||||||
|
enableTrackSelectionsInResult(periodTrackSelectorResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableTrackSelectionsInResult(TrackSelectorResult trackSelectorResult) {
|
||||||
|
for (int i = 0; i < trackSelectorResult.renderersEnabled.length; i++) {
|
||||||
|
boolean rendererEnabled = trackSelectorResult.renderersEnabled[i];
|
||||||
|
TrackSelection trackSelection = trackSelectorResult.selections.get(i);
|
||||||
|
if (rendererEnabled && trackSelection != null) {
|
||||||
|
trackSelection.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableTrackSelectionsInResult(TrackSelectorResult trackSelectorResult) {
|
||||||
|
for (int i = 0; i < trackSelectorResult.renderersEnabled.length; i++) {
|
||||||
|
boolean rendererEnabled = trackSelectorResult.renderersEnabled[i];
|
||||||
|
TrackSelection trackSelection = trackSelectorResult.selections.get(i);
|
||||||
|
if (rendererEnabled && trackSelection != null) {
|
||||||
|
trackSelection.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For each renderer of type {@link C#TRACK_TYPE_NONE}, we will remove the dummy
|
* For each renderer of type {@link C#TRACK_TYPE_NONE}, we will remove the dummy
|
||||||
* {@link EmptySampleStream} that was associated with it.
|
* {@link EmptySampleStream} that was associated with it.
|
||||||
|
@ -78,6 +78,16 @@ public abstract class BaseTrackSelection implements TrackSelection {
|
|||||||
blacklistUntilTimes = new long[length];
|
blacklistUntilTimes = new long[length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final TrackGroup getTrackGroup() {
|
public final TrackGroup getTrackGroup() {
|
||||||
return group;
|
return group;
|
||||||
|
@ -47,6 +47,20 @@ public interface TrackSelection {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the track selection.
|
||||||
|
* <p>
|
||||||
|
* This method may not be called when the track selection is already enabled.
|
||||||
|
*/
|
||||||
|
void enable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables this track selection.
|
||||||
|
* <p>
|
||||||
|
* This method may only be called when the track selection is already enabled.
|
||||||
|
*/
|
||||||
|
void disable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link TrackGroup} to which the selected tracks belong.
|
* Returns the {@link TrackGroup} to which the selected tracks belong.
|
||||||
*/
|
*/
|
||||||
@ -124,6 +138,8 @@ public interface TrackSelection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the selected track.
|
* Updates the selected track.
|
||||||
|
* <p>
|
||||||
|
* This method may only be called when the selection is enabled.
|
||||||
*
|
*
|
||||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||||
* period to which this track selection belongs has not yet started, the value will be the
|
* period to which this track selection belongs has not yet started, the value will be the
|
||||||
@ -150,7 +166,7 @@ public interface TrackSelection {
|
|||||||
* An example of a case where a smaller value may be returned is if network conditions have
|
* An example of a case where a smaller value may be returned is if network conditions have
|
||||||
* improved dramatically, allowing chunks to be discarded and re-buffered in a track of
|
* improved dramatically, allowing chunks to be discarded and re-buffered in a track of
|
||||||
* significantly higher quality. Discarding chunks may allow faster switching to a higher quality
|
* significantly higher quality. Discarding chunks may allow faster switching to a higher quality
|
||||||
* track in this case.
|
* track in this case. This method may only be called when the selection is enabled.
|
||||||
*
|
*
|
||||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||||
* period to which this track selection belongs has not yet started, the value will be the
|
* period to which this track selection belongs has not yet started, the value will be the
|
||||||
@ -167,6 +183,8 @@ public interface TrackSelection {
|
|||||||
* period of time. Blacklisting will fail if all other tracks are currently blacklisted. If
|
* period of time. Blacklisting will fail if all other tracks are currently blacklisted. If
|
||||||
* blacklisting the currently selected track, note that it will remain selected until the next
|
* blacklisting the currently selected track, note that it will remain selected until the next
|
||||||
* call to {@link #updateSelectedTrack(long, long, long)}.
|
* call to {@link #updateSelectedTrack(long, long, long)}.
|
||||||
|
* <p>
|
||||||
|
* This method may only be called when the selection is enabled.
|
||||||
*
|
*
|
||||||
* @param index The index of the track in the selection.
|
* @param index The index of the track in the selection.
|
||||||
* @param blacklistDurationMs The duration of time for which the track should be blacklisted, in
|
* @param blacklistDurationMs The duration of time for which the track should be blacklisted, in
|
||||||
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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.testutil;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
|
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||||
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
|
import java.util.List;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fake {@link TrackSelection} that only returns 1 fixed track, and allows querying the number
|
||||||
|
* of calls to its methods.
|
||||||
|
*/
|
||||||
|
public final class FakeTrackSelection implements TrackSelection {
|
||||||
|
|
||||||
|
private final TrackGroup rendererTrackGroup;
|
||||||
|
|
||||||
|
public int enableCount;
|
||||||
|
public int releaseCount;
|
||||||
|
public boolean isEnabled;
|
||||||
|
|
||||||
|
public FakeTrackSelection(TrackGroup rendererTrackGroup) {
|
||||||
|
this.rendererTrackGroup = rendererTrackGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
// assert that track selection is in disabled state before this call.
|
||||||
|
Assert.assertFalse(isEnabled);
|
||||||
|
enableCount++;
|
||||||
|
isEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
// assert that track selection is in enabled state before this call.
|
||||||
|
Assert.assertTrue(isEnabled);
|
||||||
|
releaseCount++;
|
||||||
|
isEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackGroup getTrackGroup() {
|
||||||
|
return rendererTrackGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return rendererTrackGroup.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Format getFormat(int index) {
|
||||||
|
return rendererTrackGroup.getFormat(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndexInTrackGroup(int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(Format format) {
|
||||||
|
Assert.assertTrue(isEnabled);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(int indexInTrackGroup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Format getSelectedFormat() {
|
||||||
|
return rendererTrackGroup.getFormat(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectedIndexInTrackGroup() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectedIndex() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectionReason() {
|
||||||
|
return C.SELECTION_REASON_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getSelectionData() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelectedTrack(long playbackPositionUs, long bufferedDurationUs,
|
||||||
|
long availableDurationUs) {
|
||||||
|
Assert.assertTrue(isEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue) {
|
||||||
|
Assert.assertTrue(isEnabled);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean blacklist(int index, long blacklistDurationMs) {
|
||||||
|
Assert.assertTrue(isEnabled);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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.testutil;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
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;
|
||||||
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fake {@link MappingTrackSelector} that returns {@link FakeTrackSelection}s.
|
||||||
|
*/
|
||||||
|
public class FakeTrackSelector extends MappingTrackSelector {
|
||||||
|
|
||||||
|
private final List<FakeTrackSelection> selectedTrackSelections = new ArrayList<>();
|
||||||
|
private final boolean mayReuseTrackSelection;
|
||||||
|
|
||||||
|
public FakeTrackSelector() {
|
||||||
|
this(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mayReuseTrackSelection Whether this {@link FakeTrackSelector} will reuse
|
||||||
|
* {@link TrackSelection}s during track selection, when it finds previously-selected track
|
||||||
|
* selection using the same {@link TrackGroup}.
|
||||||
|
*/
|
||||||
|
public FakeTrackSelector(boolean mayReuseTrackSelection) {
|
||||||
|
this.mayReuseTrackSelection = mayReuseTrackSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TrackSelection[] selectTracks(RendererCapabilities[] rendererCapabilities,
|
||||||
|
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
|
||||||
|
throws ExoPlaybackException {
|
||||||
|
List<FakeTrackSelection> resultList = new ArrayList<>();
|
||||||
|
for (TrackGroupArray trackGroupArray : rendererTrackGroupArrays) {
|
||||||
|
TrackGroup trackGroup = trackGroupArray.get(0);
|
||||||
|
FakeTrackSelection trackSelectionForRenderer = reuseOrCreateTrackSelection(trackGroup);
|
||||||
|
resultList.add(trackSelectionForRenderer);
|
||||||
|
}
|
||||||
|
return resultList.toArray(new TrackSelection[resultList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private FakeTrackSelection reuseOrCreateTrackSelection(TrackGroup trackGroup) {
|
||||||
|
FakeTrackSelection trackSelectionForRenderer = null;
|
||||||
|
if (mayReuseTrackSelection) {
|
||||||
|
for (FakeTrackSelection selectedTrackSelection : selectedTrackSelections) {
|
||||||
|
if (selectedTrackSelection.getTrackGroup().equals(trackGroup)) {
|
||||||
|
trackSelectionForRenderer = selectedTrackSelection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trackSelectionForRenderer == null) {
|
||||||
|
trackSelectionForRenderer = new FakeTrackSelection(trackGroup);
|
||||||
|
selectedTrackSelections.add(trackSelectionForRenderer);
|
||||||
|
}
|
||||||
|
return trackSelectionForRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns list of all {@link FakeTrackSelection}s that this track selector has made so far.
|
||||||
|
*/
|
||||||
|
public List<FakeTrackSelection> getSelectedTrackSelections() {
|
||||||
|
return selectedTrackSelections;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user