Tighten when various SampleSource methods can be called.

This removes the need for each SampleSource implementation to
implement 3x "if(condition) {noop}" tests (ChunkSampleSource
and SingleSampleSource were missing some of these checks).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=118036233
This commit is contained in:
olly 2016-03-24 09:39:05 -07:00 committed by Oliver Woodman
parent 050b0b66da
commit 98fb6d150d
7 changed files with 52 additions and 39 deletions

View file

@ -125,11 +125,13 @@ import java.util.concurrent.atomic.AtomicInteger;
}
public long getBufferedPosition() {
long bufferedPositionUs = this.bufferedPositionUs;
return bufferedPositionUs == C.UNKNOWN_TIME_US ? ExoPlayer.UNKNOWN_TIME
: bufferedPositionUs / 1000;
}
public long getDuration() {
long durationUs = this.durationUs;
return durationUs == C.UNKNOWN_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000;
}
@ -279,7 +281,6 @@ import java.util.concurrent.atomic.AtomicInteger;
}
durationUs = source.getDurationUs();
bufferedPositionUs = source.getBufferedPositionUs();
selectTracksInternal(true);
boolean allRenderersEnded = true;
@ -363,6 +364,13 @@ import java.util.concurrent.atomic.AtomicInteger;
elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
}
private void updateBufferedPositionUs() {
long sourceBufferedPositionUs = enabledRenderers.length > 0 ? source.getBufferedPositionUs()
: C.END_OF_SOURCE_US;
bufferedPositionUs = sourceBufferedPositionUs == C.END_OF_SOURCE_US
&& durationUs != C.UNKNOWN_TIME_US ? durationUs : sourceBufferedPositionUs;
}
private void doSomeWork() throws ExoPlaybackException, IOException {
TraceUtil.beginSection("doSomeWork");
long operationStartTimeMs = SystemClock.elapsedRealtime();
@ -373,8 +381,10 @@ import java.util.concurrent.atomic.AtomicInteger;
}
updatePositionUs();
bufferedPositionUs = source.getBufferedPositionUs();
source.continueBuffering(positionUs);
updateBufferedPositionUs();
if (enabledRenderers.length > 0) {
source.continueBuffering(positionUs);
}
boolean allRenderersEnded = true;
boolean allRenderersReadyOrEnded = true;
@ -444,13 +454,14 @@ import java.util.concurrent.atomic.AtomicInteger;
return;
}
for (TrackRenderer renderer : enabledRenderers) {
ensureStopped(renderer);
}
setState(ExoPlayer.STATE_BUFFERING);
source.seekToUs(positionUs);
for (TrackRenderer renderer : enabledRenderers) {
renderer.checkForReset();
if (enabledRenderers != null) {
for (TrackRenderer renderer : enabledRenderers) {
ensureStopped(renderer);
}
source.seekToUs(positionUs);
for (TrackRenderer renderer : enabledRenderers) {
renderer.checkForReset();
}
}
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
@ -622,6 +633,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
source.endTrackSelection(positionUs);
updateBufferedPositionUs();
}
private void reselectTracksInternal() throws ExoPlaybackException {

View file

@ -20,6 +20,7 @@ import com.google.android.exoplayer.util.Assertions;
import android.util.Pair;
import java.io.IOException;
import java.util.Arrays;
import java.util.IdentityHashMap;
/**
@ -28,14 +29,17 @@ import java.util.IdentityHashMap;
public final class MultiSampleSource implements SampleSource {
private final SampleSource[] sources;
private final int[] sourceEnabledTrackCounts;
private final IdentityHashMap<TrackStream, Integer> trackStreamSourceIndices;
private int state;
private long durationUs;
private TrackGroupArray trackGroups;
private SampleSource[] enabledSources;
public MultiSampleSource(SampleSource... sources) {
this.sources = sources;
sourceEnabledTrackCounts = new int[sources.length];
trackStreamSourceIndices = new IdentityHashMap<>();
state = STATE_UNPREPARED;
}
@ -100,7 +104,9 @@ public final class MultiSampleSource implements SampleSource {
Pair<Integer, Integer> sourceAndGroup = getSourceAndTrackGroupIndices(selection.group);
TrackStream trackStream = sources[sourceAndGroup.first].selectTrack(
new TrackSelection(sourceAndGroup.second, selection.getTracks()), positionUs);
trackStreamSourceIndices.put(trackStream, sourceAndGroup.first);
int sourceIndex = sourceAndGroup.first;
sourceEnabledTrackCounts[sourceIndex]++;
trackStreamSourceIndices.put(trackStream, sourceIndex);
return trackStream;
}
@ -109,27 +115,34 @@ public final class MultiSampleSource implements SampleSource {
Assertions.checkState(state == STATE_SELECTING_TRACKS);
int sourceIndex = trackStreamSourceIndices.remove(trackStream);
sources[sourceIndex].unselectTrack(trackStream);
sourceEnabledTrackCounts[sourceIndex]--;
}
@Override
public void endTrackSelection(long positionUs) {
Assertions.checkState(state == STATE_SELECTING_TRACKS);
state = STATE_READING;
for (SampleSource source : sources) {
source.endTrackSelection(positionUs);
int newEnabledSourceCount = 0;
SampleSource[] newEnabledSources = new SampleSource[sources.length];
for (int i = 0; i < sources.length; i++) {
sources[i].endTrackSelection(positionUs);
if (sourceEnabledTrackCounts[i] > 0) {
newEnabledSources[newEnabledSourceCount++] = sources[i];
}
}
enabledSources = Arrays.copyOf(newEnabledSources, newEnabledSourceCount);
}
@Override
public void continueBuffering(long positionUs) {
for (SampleSource source : sources) {
for (SampleSource source : enabledSources) {
source.continueBuffering(positionUs);
}
}
@Override
public void seekToUs(long positionUs) {
for (SampleSource source : sources) {
for (SampleSource source : enabledSources) {
source.seekToUs(positionUs);
}
}
@ -142,7 +155,7 @@ public final class MultiSampleSource implements SampleSource {
@Override
public long getBufferedPositionUs() {
long bufferedPositionUs = durationUs != C.UNKNOWN_TIME_US ? durationUs : Long.MAX_VALUE;
for (SampleSource source : sources) {
for (SampleSource source : enabledSources) {
long rendererBufferedPositionUs = source.getBufferedPositionUs();
if (rendererBufferedPositionUs == C.UNKNOWN_TIME_US) {
return C.UNKNOWN_TIME_US;

View file

@ -132,7 +132,8 @@ public interface SampleSource {
/**
* Indicates to the source that it should continue buffering data for its enabled tracks.
* <p>
* This method should only be called when the state is {@link #STATE_READING}.
* This method should only be called when the state is {@link #STATE_READING} and at least one
* track is selected.
*
* @param positionUs The current playback position.
*/
@ -141,19 +142,20 @@ public interface SampleSource {
/**
* Returns an estimate of the position up to which data is buffered for the enabled tracks.
* <p>
* This method should only be called when the state is {@link #STATE_READING}.
* This method should only be called when the state is {@link #STATE_READING} and at least one
* track is selected.
*
* @return An estimate of the absolute position in microseconds up to which data is buffered,
* or {@link C#END_OF_SOURCE_US} if the track is fully buffered, or {@link C#UNKNOWN_TIME_US}
* if no estimate is available. If no tracks are enabled then {@link C#END_OF_SOURCE_US} is
* returned.
* if no estimate is available.
*/
long getBufferedPositionUs();
/**
* Seeks to the specified time in microseconds.
* <p>
* This method should only be called when the state is {@link #STATE_READING}.
* This method should only be called when the state is {@link #STATE_READING} and at least one
* track is selected.
*
* @param positionUs The seek position in microseconds.
*/

View file

@ -220,7 +220,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
@Override
public long getBufferedPositionUs() {
return streamState == STREAM_STATE_END_OF_STREAM || loadingFinished ? C.END_OF_SOURCE_US : 0;
return loadingFinished ? C.END_OF_SOURCE_US : 0;
}
@Override

View file

@ -326,7 +326,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
@Override
public long getBufferedPositionUs() {
if (!trackEnabled || loadingFinished) {
if (loadingFinished) {
return C.END_OF_SOURCE_US;
} else if (isPendingReset()) {
return pendingResetPositionUs;

View file

@ -423,9 +423,6 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
@Override
public void continueBuffering(long playbackPositionUs) {
if (enabledTrackCount == 0) {
return;
}
downstreamPositionUs = playbackPositionUs;
discardSamplesForDisabledTracks(downstreamPositionUs);
if (loadingFinished) {
@ -504,9 +501,6 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
@Override
public void seekToUs(long positionUs) {
if (enabledTrackCount == 0) {
return;
}
seekToInternal(positionUs);
}
@ -529,7 +523,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
@Override
public long getBufferedPositionUs() {
if (enabledTrackCount == 0 || loadingFinished) {
if (loadingFinished) {
return C.END_OF_SOURCE_US;
} else if (isPendingReset()) {
return pendingResetPositionUs;

View file

@ -258,9 +258,6 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
@Override
public void continueBuffering(long playbackPositionUs) {
if (enabledTrackCount == 0) {
return;
}
downstreamPositionUs = playbackPositionUs;
if (!extractors.isEmpty()) {
discardSamplesForDisabledTracks(getCurrentExtractor(), downstreamPositionUs);
@ -360,17 +357,12 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
@Override
public void seekToUs(long positionUs) {
if (enabledTrackCount == 0) {
return;
}
seekToInternal(positionUs);
}
@Override
public long getBufferedPositionUs() {
if (enabledTrackCount == 0) {
return C.END_OF_SOURCE_US;
} else if (isPendingReset()) {
if (isPendingReset()) {
return pendingResetPositionUs;
} else if (loadingFinished) {
return C.END_OF_SOURCE_US;