Commit e4ee1951 by andrewlewis Committed by Oliver Woodman

Remove ExoPlayer.STATE_PREPARING.

prepare(SampleSource) is renamed to setSource(SampleSource). The player
immediately transitions to STATE_BUFFERING when the source is set, at which
point doSomeWork is called.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=119838825
parent 2b0f2ec3
...@@ -233,8 +233,6 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener ...@@ -233,8 +233,6 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
return "E"; return "E";
case ExoPlayer.STATE_IDLE: case ExoPlayer.STATE_IDLE:
return "I"; return "I";
case ExoPlayer.STATE_PREPARING:
return "P";
case ExoPlayer.STATE_READY: case ExoPlayer.STATE_READY:
return "R"; return "R";
default: default:
......
...@@ -324,7 +324,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, ...@@ -324,7 +324,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
debugViewHelper.start(); debugViewHelper.start();
} }
if (playerNeedsPrepare) { if (playerNeedsPrepare) {
player.prepare(); player.setSource();
playerNeedsPrepare = false; playerNeedsPrepare = false;
updateButtonVisibilities(); updateButtonVisibilities();
} }
...@@ -367,9 +367,6 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, ...@@ -367,9 +367,6 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
case ExoPlayer.STATE_IDLE: case ExoPlayer.STATE_IDLE:
text += "idle"; text += "idle";
break; break;
case ExoPlayer.STATE_PREPARING:
text += "preparing";
break;
case ExoPlayer.STATE_READY: case ExoPlayer.STATE_READY:
text += "ready"; text += "ready";
break; break;
......
...@@ -61,7 +61,7 @@ public class DashSourceBuilder implements SourceBuilder { ...@@ -61,7 +61,7 @@ public class DashSourceBuilder implements SourceBuilder {
} }
@Override @Override
public SampleSource buildRenderers(DemoPlayer player) { public SampleSource buildSource(DemoPlayer player) {
MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser(); MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser();
DataSource manifestDataSource = dataSourceFactory.createDataSource(); DataSource manifestDataSource = dataSourceFactory.createDataSource();
// TODO[REFACTOR]: This needs releasing. // TODO[REFACTOR]: This needs releasing.
......
...@@ -75,10 +75,10 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even ...@@ -75,10 +75,10 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
/** /**
* Builds a source to play. * Builds a source to play.
* *
* @param player The player for which renderers are being built. * @param player The player for which a source is being built.
* @return SampleSource The source to play. * @return SampleSource The source to play.
*/ */
SampleSource buildRenderers(DemoPlayer player); SampleSource buildSource(DemoPlayer player);
} }
/** /**
...@@ -143,7 +143,6 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even ...@@ -143,7 +143,6 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
// Constants pulled into this class for convenience. // Constants pulled into this class for convenience.
public static final int STATE_IDLE = ExoPlayer.STATE_IDLE; public static final int STATE_IDLE = ExoPlayer.STATE_IDLE;
public static final int STATE_PREPARING = ExoPlayer.STATE_PREPARING;
public static final int STATE_BUFFERING = ExoPlayer.STATE_BUFFERING; public static final int STATE_BUFFERING = ExoPlayer.STATE_BUFFERING;
public static final int STATE_READY = ExoPlayer.STATE_READY; public static final int STATE_READY = ExoPlayer.STATE_READY;
public static final int STATE_ENDED = ExoPlayer.STATE_ENDED; public static final int STATE_ENDED = ExoPlayer.STATE_ENDED;
...@@ -247,8 +246,8 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even ...@@ -247,8 +246,8 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
return trackInfo; return trackInfo;
} }
public void prepare() { public void setSource() {
player.prepare(sourceBuilder.buildRenderers(this)); player.setSource(sourceBuilder.buildSource(this));
} }
public void setPlayWhenReady(boolean playWhenReady) { public void setPlayWhenReady(boolean playWhenReady) {
......
...@@ -43,7 +43,7 @@ public class ExtractorSourceBuilder implements SourceBuilder { ...@@ -43,7 +43,7 @@ public class ExtractorSourceBuilder implements SourceBuilder {
} }
@Override @Override
public SampleSource buildRenderers(DemoPlayer player) { public SampleSource buildSource(DemoPlayer player) {
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
DataSource dataSource = dataSourceFactory.createDataSource(player.getBandwidthMeter()); DataSource dataSource = dataSourceFactory.createDataSource(player.getBandwidthMeter());
return new ExtractorSampleSource(uri, dataSource, allocator, return new ExtractorSampleSource(uri, dataSource, allocator,
......
...@@ -56,7 +56,7 @@ public class HlsSourceBuilder implements SourceBuilder { ...@@ -56,7 +56,7 @@ public class HlsSourceBuilder implements SourceBuilder {
} }
@Override @Override
public SampleSource buildRenderers(DemoPlayer player) { public SampleSource buildSource(DemoPlayer player) {
HlsPlaylistParser parser = new HlsPlaylistParser(); HlsPlaylistParser parser = new HlsPlaylistParser();
DataSource manifestDataSource = dataSourceFactory.createDataSource(); DataSource manifestDataSource = dataSourceFactory.createDataSource();
// TODO[REFACTOR]: This needs releasing. // TODO[REFACTOR]: This needs releasing.
......
...@@ -61,7 +61,7 @@ public class SmoothStreamingSourceBuilder implements SourceBuilder { ...@@ -61,7 +61,7 @@ public class SmoothStreamingSourceBuilder implements SourceBuilder {
} }
@Override @Override
public SampleSource buildRenderers(DemoPlayer player) { public SampleSource buildSource(DemoPlayer player) {
SmoothStreamingManifestParser parser = new SmoothStreamingManifestParser(); SmoothStreamingManifestParser parser = new SmoothStreamingManifestParser();
// TODO[REFACTOR]: This needs releasing. // TODO[REFACTOR]: This needs releasing.
DataSource manifestDataSource = dataSourceFactory.createDataSource(); DataSource manifestDataSource = dataSourceFactory.createDataSource();
......
...@@ -84,7 +84,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase { ...@@ -84,7 +84,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
false), false),
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT, new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
new MatroskaExtractor()); new MatroskaExtractor());
player.prepare(sampleSource); player.setSource(sampleSource);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
Looper.loop(); Looper.loop();
} }
......
...@@ -84,7 +84,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase { ...@@ -84,7 +84,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
false), false),
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT, new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
new MatroskaExtractor()); new MatroskaExtractor());
player.prepare(sampleSource); player.setSource(sampleSource);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
Looper.loop(); Looper.loop();
} }
......
...@@ -102,7 +102,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ...@@ -102,7 +102,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
new MatroskaExtractor()); new MatroskaExtractor());
player.sendMessage(videoRenderer, LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER, player.sendMessage(videoRenderer, LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER,
new VpxVideoSurfaceView(context)); new VpxVideoSurfaceView(context));
player.prepare(sampleSource); player.setSource(sampleSource);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
Looper.loop(); Looper.loop();
} }
......
...@@ -19,7 +19,7 @@ import android.os.Looper; ...@@ -19,7 +19,7 @@ import android.os.Looper;
/** /**
* An extensible media player exposing traditional high-level media player functionality, such as * An extensible media player exposing traditional high-level media player functionality, such as
* the ability to prepare, play, pause and seek. * the ability to buffer media, play, pause and seek.
* *
* <p>Topics covered here are: * <p>Topics covered here are:
* <ol> * <ol>
...@@ -35,7 +35,7 @@ import android.os.Looper; ...@@ -35,7 +35,7 @@ import android.os.Looper;
* on) the type of the media being played, how and where it is stored, or how it is rendered. * on) the type of the media being played, how and where it is stored, or how it is rendered.
* Rather than implementing the loading and rendering of media directly, {@link ExoPlayer} instead * Rather than implementing the loading and rendering of media directly, {@link ExoPlayer} instead
* delegates this work to one or more {@link TrackRenderer}s, which are injected when the player * delegates this work to one or more {@link TrackRenderer}s, which are injected when the player
* is prepared. Hence {@link ExoPlayer} is capable of loading and playing any media for which a * is created. Hence {@link ExoPlayer} is capable of loading and playing any media for which a
* {@link TrackRenderer} implementation can be provided. * {@link TrackRenderer} implementation can be provided.
* *
* <p>{@link MediaCodecAudioTrackRenderer} and {@link MediaCodecVideoTrackRenderer} can be used for * <p>{@link MediaCodecAudioTrackRenderer} and {@link MediaCodecVideoTrackRenderer} can be used for
...@@ -86,7 +86,7 @@ import android.os.Looper; ...@@ -86,7 +86,7 @@ import android.os.Looper;
* *
* <p>The possible playback state transitions are shown below. Transitions can be triggered either * <p>The possible playback state transitions are shown below. Transitions can be triggered either
* by changes in the state of the {@link TrackRenderer}s being used, or as a result of * by changes in the state of the {@link TrackRenderer}s being used, or as a result of
* {@link #prepare(SampleSource)}, {@link #stop()} or {@link #release()} being invoked.</p> * {@link #setSource(SampleSource)}, {@link #stop()} or {@link #release()} being invoked.</p>
* <p align="center"><img src="../../../../../images/exoplayer_playbackstate.png" * <p align="center"><img src="../../../../../images/exoplayer_playbackstate.png"
* alt="ExoPlayer playback state transitions" * alt="ExoPlayer playback state transitions"
* border="0"/></p> * border="0"/></p>
...@@ -200,28 +200,24 @@ public interface ExoPlayer { ...@@ -200,28 +200,24 @@ public interface ExoPlayer {
} }
/** /**
* The player is neither prepared or being prepared. * The player does not have a source to load, so it is neither buffering nor ready to play.
*/ */
int STATE_IDLE = 1; int STATE_IDLE = 1;
/** /**
* The player is being prepared. * The player not able to immediately play from the current position. The cause is
* {@link TrackRenderer} specific, but this state typically occurs when more data needs to be
* loaded to be ready to play, or more data needs to be buffered for playback to resume.
*/ */
int STATE_PREPARING = 2; int STATE_BUFFERING = 2;
/** /**
* The player is prepared but not able to immediately play from the current position. The cause * The player is able to immediately play from the current position. The player will be playing if
* is {@link TrackRenderer} specific, but this state typically occurs when more data needs * {@link #getPlayWhenReady()} returns true, and paused otherwise.
* to be buffered for playback to start.
*/ */
int STATE_BUFFERING = 3; int STATE_READY = 3;
/**
* The player is prepared and able to immediately play from the current position. The player will
* be playing if {@link #getPlayWhenReady()} returns true, and paused otherwise.
*/
int STATE_READY = 4;
/** /**
* The player has finished playing the media. * The player has finished playing the media.
*/ */
int STATE_ENDED = 5; int STATE_ENDED = 4;
/** /**
* Represents an unknown time or duration. * Represents an unknown time or duration.
...@@ -258,11 +254,12 @@ public interface ExoPlayer { ...@@ -258,11 +254,12 @@ public interface ExoPlayer {
int getPlaybackState(); int getPlaybackState();
/** /**
* Prepares the player for playback. * Sets the player's source. The player will transition to {@link #STATE_BUFFERING} until it is
* ready to play the new source.
* *
* @param sampleSource The {@link SampleSource} to play. * @param sampleSource The {@link SampleSource} to play.
*/ */
void prepare(SampleSource sampleSource); void setSource(SampleSource sampleSource);
/** /**
* Sets whether playback should proceed when {@link #getPlaybackState()} == {@link #STATE_READY}. * Sets whether playback should proceed when {@link #getPlaybackState()} == {@link #STATE_READY}.
...@@ -305,7 +302,7 @@ public interface ExoPlayer { ...@@ -305,7 +302,7 @@ public interface ExoPlayer {
* <p> * <p>
* Calling this method does not reset the playback position. If this player instance will be used * Calling this method does not reset the playback position. If this player instance will be used
* to play another video from its start, then {@code seekTo(0)} should be called after stopping * to play another video from its start, then {@code seekTo(0)} should be called after stopping
* the player and before preparing it for the next video. * the player and before setting the next source.
*/ */
void stop(); void stop();
......
...@@ -91,8 +91,8 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -91,8 +91,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
@Override @Override
public void prepare(SampleSource source) { public void setSource(SampleSource source) {
internalPlayer.prepare(source); internalPlayer.setSource(source);
} }
@Override @Override
......
...@@ -49,17 +49,16 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -49,17 +49,16 @@ import java.util.concurrent.atomic.AtomicInteger;
public static final int MSG_ERROR = 3; public static final int MSG_ERROR = 3;
// Internal messages // Internal messages
private static final int MSG_PREPARE = 1; private static final int MSG_SET_SOURCE = 0;
private static final int MSG_INCREMENTAL_PREPARE = 2; private static final int MSG_SET_PLAY_WHEN_READY = 1;
private static final int MSG_SET_PLAY_WHEN_READY = 3; private static final int MSG_DO_SOME_WORK = 2;
private static final int MSG_SEEK_TO = 3;
private static final int MSG_STOP = 4; private static final int MSG_STOP = 4;
private static final int MSG_RELEASE = 5; private static final int MSG_RELEASE = 5;
private static final int MSG_SEEK_TO = 6; private static final int MSG_TRACK_SELECTION_INVALIDATED = 6;
private static final int MSG_DO_SOME_WORK = 7; private static final int MSG_CUSTOM = 7;
private static final int MSG_TRACK_SELECTION_INVALIDATED = 8;
private static final int MSG_CUSTOM = 9;
private static final int PREPARE_INTERVAL_MS = 10; private static final int PREPARING_SOURCE_INTERVAL_MS = 10;
private static final int RENDERING_INTERVAL_MS = 10; private static final int RENDERING_INTERVAL_MS = 10;
private static final int IDLE_INTERVAL_MS = 1000; private static final int IDLE_INTERVAL_MS = 1000;
...@@ -78,6 +77,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -78,6 +77,7 @@ import java.util.concurrent.atomic.AtomicInteger;
private MediaClock rendererMediaClock; private MediaClock rendererMediaClock;
private SampleSource source; private SampleSource source;
private TrackRenderer[] enabledRenderers; private TrackRenderer[] enabledRenderers;
private boolean preparedSource;
private boolean released; private boolean released;
private boolean playWhenReady; private boolean playWhenReady;
private boolean rebuffering; private boolean rebuffering;
...@@ -140,8 +140,8 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -140,8 +140,8 @@ import java.util.concurrent.atomic.AtomicInteger;
return durationUs == C.UNKNOWN_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000; return durationUs == C.UNKNOWN_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000;
} }
public void prepare(SampleSource sampleSource) { public void setSource(SampleSource sampleSource) {
handler.obtainMessage(MSG_PREPARE, sampleSource).sendToTarget(); handler.obtainMessage(MSG_SET_SOURCE, sampleSource).sendToTarget();
} }
public void setPlayWhenReady(boolean playWhenReady) { public void setPlayWhenReady(boolean playWhenReady) {
...@@ -205,12 +205,8 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -205,12 +205,8 @@ import java.util.concurrent.atomic.AtomicInteger;
public boolean handleMessage(Message msg) { public boolean handleMessage(Message msg) {
try { try {
switch (msg.what) { switch (msg.what) {
case MSG_PREPARE: { case MSG_SET_SOURCE: {
prepareInternal((SampleSource) msg.obj); setSourceInternal((SampleSource) msg.obj);
return true;
}
case MSG_INCREMENTAL_PREPARE: {
incrementalPrepareInternal();
return true; return true;
} }
case MSG_SET_PLAY_WHEN_READY: { case MSG_SET_PLAY_WHEN_READY: {
...@@ -270,26 +266,6 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -270,26 +266,6 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
} }
private void prepareInternal(SampleSource sampleSource) throws ExoPlaybackException, IOException {
resetInternal();
setState(ExoPlayer.STATE_PREPARING);
this.source = sampleSource;
incrementalPrepareInternal();
}
private void incrementalPrepareInternal() throws ExoPlaybackException, IOException {
long operationStartTimeMs = SystemClock.elapsedRealtime();
if (!source.prepare(positionUs)) {
// We're still waiting for the source to be prepared.
scheduleNextOperation(MSG_INCREMENTAL_PREPARE, operationStartTimeMs, PREPARE_INTERVAL_MS);
return;
}
durationUs = source.getDurationUs();
selectTracksInternal();
resumeInternal();
}
private boolean isReadyOrEnded(TrackRenderer renderer) { private boolean isReadyOrEnded(TrackRenderer renderer) {
return renderer.isReady() || renderer.isEnded(); return renderer.isReady() || renderer.isEnded();
} }
...@@ -303,6 +279,13 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -303,6 +279,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|| (durationUs != C.UNKNOWN_TIME_US && bufferedPositionUs >= durationUs); || (durationUs != C.UNKNOWN_TIME_US && bufferedPositionUs >= durationUs);
} }
private void setSourceInternal(SampleSource source) {
resetInternal();
this.source = source;
setState(ExoPlayer.STATE_BUFFERING);
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
private void setPlayWhenReadyInternal(boolean playWhenReady) throws ExoPlaybackException { private void setPlayWhenReadyInternal(boolean playWhenReady) throws ExoPlaybackException {
try { try {
rebuffering = false; rebuffering = false;
...@@ -357,8 +340,21 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -357,8 +340,21 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
private void doSomeWork() throws ExoPlaybackException, IOException { private void doSomeWork() throws ExoPlaybackException, IOException {
TraceUtil.beginSection("doSomeWork");
long operationStartTimeMs = SystemClock.elapsedRealtime(); long operationStartTimeMs = SystemClock.elapsedRealtime();
if (!preparedSource) {
preparedSource = source.prepare(positionUs);
if (preparedSource) {
durationUs = source.getDurationUs();
selectTracksInternal();
resumeInternal();
} else {
// We're still waiting for the source to be prepared.
scheduleNextOperation(MSG_DO_SOME_WORK, operationStartTimeMs, PREPARING_SOURCE_INTERVAL_MS);
}
return;
}
TraceUtil.beginSection("doSomeWork");
// Process resets. // Process resets.
for (TrackRenderer renderer : enabledRenderers) { for (TrackRenderer renderer : enabledRenderers) {
...@@ -435,7 +431,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -435,7 +431,7 @@ import java.util.concurrent.atomic.AtomicInteger;
positionUs = positionMs * 1000; positionUs = positionMs * 1000;
standaloneMediaClock.stop(); standaloneMediaClock.stop();
standaloneMediaClock.setPositionUs(positionUs); standaloneMediaClock.setPositionUs(positionUs);
if (state == ExoPlayer.STATE_IDLE || state == ExoPlayer.STATE_PREPARING) { if (!preparedSource) {
return; return;
} }
...@@ -494,7 +490,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -494,7 +490,7 @@ import java.util.concurrent.atomic.AtomicInteger;
private void resetInternal() { private void resetInternal() {
handler.removeMessages(MSG_DO_SOME_WORK); handler.removeMessages(MSG_DO_SOME_WORK);
handler.removeMessages(MSG_INCREMENTAL_PREPARE); preparedSource = false;
rebuffering = false; rebuffering = false;
trackSelections = null; trackSelections = null;
standaloneMediaClock.stop(); standaloneMediaClock.stop();
...@@ -527,7 +523,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -527,7 +523,7 @@ import java.util.concurrent.atomic.AtomicInteger;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Pair<ExoPlayerComponent, Object> targetAndMessage = (Pair<ExoPlayerComponent, Object>) obj; Pair<ExoPlayerComponent, Object> targetAndMessage = (Pair<ExoPlayerComponent, Object>) obj;
targetAndMessage.first.handleMessage(what, targetAndMessage.second); targetAndMessage.first.handleMessage(what, targetAndMessage.second);
if (state != ExoPlayer.STATE_IDLE && state != ExoPlayer.STATE_PREPARING) { if (preparedSource) {
// The message may have caused something to change that now requires us to do work. // The message may have caused something to change that now requires us to do work.
handler.sendEmptyMessage(MSG_DO_SOME_WORK); handler.sendEmptyMessage(MSG_DO_SOME_WORK);
} }
...@@ -636,7 +632,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -636,7 +632,7 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
private void reselectTracksInternal() throws ExoPlaybackException { private void reselectTracksInternal() throws ExoPlaybackException {
if (state == ExoPlayer.STATE_IDLE || state == ExoPlayer.STATE_PREPARING) { if (!preparedSource) {
// We don't have tracks yet, so we don't care. // We don't have tracks yet, so we don't care.
return; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment