Commit 04c28c6d by olly Committed by Santiago Seifert

Minimal change to fix seeking before prepare + finalize API

- This change fixes seeking before the prepare (or more
  accurately, before the timeline is set). The fix a minimal
  one to fix the behavior. It's inefficient compared to
  posting the pending seek onto the playback thread, which
  will be the long term solution.
- As of this change, I think we can call V2 "done". There are
  some loose ends to tie up, but the API is effectively
  finalized and the implementation is in a state where you
  can take it, use it and expect it to work.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=132468107
parent 36df5bcd
...@@ -90,8 +90,8 @@ import java.util.Locale; ...@@ -90,8 +90,8 @@ import java.util.Locale;
} }
@Override @Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) { public void onPositionDiscontinuity() {
Log.d(TAG, "discontinuity [" + periodIndex + ", " + positionMs + "]"); Log.d(TAG, "positionDiscontinuity");
} }
@Override @Override
......
...@@ -427,7 +427,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi ...@@ -427,7 +427,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
} }
@Override @Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) { public void onPositionDiscontinuity() {
if (mediaController.isShowing()) { if (mediaController.isShowing()) {
// The MediaController is visible, so force it to show the updated position immediately. // The MediaController is visible, so force it to show the updated position immediately.
mediaController.show(); mediaController.show();
......
...@@ -91,7 +91,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase { ...@@ -91,7 +91,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
} }
@Override @Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) { public void onPositionDiscontinuity() {
// Do nothing. // Do nothing.
} }
......
...@@ -91,7 +91,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase { ...@@ -91,7 +91,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
} }
@Override @Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) { public void onPositionDiscontinuity() {
// Do nothing. // Do nothing.
} }
......
...@@ -110,7 +110,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ...@@ -110,7 +110,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
} }
@Override @Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) { public void onPositionDiscontinuity() {
// Do nothing. // Do nothing.
} }
......
...@@ -144,15 +144,12 @@ public interface ExoPlayer { ...@@ -144,15 +144,12 @@ public interface ExoPlayer {
*/ */
void onPlayerError(ExoPlaybackException error); void onPlayerError(ExoPlaybackException error);
// TODO: Should be windowIndex and position in the window.
/** /**
* Called when the player's position changes due to a discontinuity (i.e. due to seeking, * Called when a position discontinuity occurs. Position discontinuities occur when seeks are
* playback transitioning to the next window, or a source induced discontinuity). * performed, when playbacks transition from one period in the timeline to the next, and when
* * the player introduces discontinuities internally.
* @param periodIndex The index of the period being played.
* @param positionMs The playback position in that period, in milliseconds.
*/ */
void onPositionDiscontinuity(int periodIndex, long positionMs); void onPositionDiscontinuity();
} }
...@@ -309,17 +306,17 @@ public interface ExoPlayer { ...@@ -309,17 +306,17 @@ public interface ExoPlayer {
/** /**
* Seeks to a position specified in milliseconds in the current window. * Seeks to a position specified in milliseconds in the current window.
* *
* @param positionMs The seek position. * @param windowPositionMs The seek position in the current window.
*/ */
void seekTo(long positionMs); void seekTo(long windowPositionMs);
/** /**
* Seeks to a position specified in milliseconds in the specified window. * Seeks to a position specified in milliseconds in the specified window.
* *
* @param windowIndex The index of the window. * @param windowIndex The index of the window.
* @param positionMs The seek position relative to the start of the window. * @param windowPositionMs The seek position in the specified window.
*/ */
void seekTo(int windowIndex, long positionMs); void seekTo(int windowIndex, long windowPositionMs);
/** /**
* Stops playback. Use {@code setPlayWhenReady(false)} rather than this method if the intention * Stops playback. Use {@code setPlayWhenReady(false)} rather than this method if the intention
...@@ -357,19 +354,23 @@ public interface ExoPlayer { ...@@ -357,19 +354,23 @@ public interface ExoPlayer {
void blockingSendMessages(ExoPlayerMessage... messages); void blockingSendMessages(ExoPlayerMessage... messages);
/** /**
* Returns the current manifest. The type depends on the {@link MediaSource} passed to
* {@link #prepare}.
*/
Object getCurrentManifest();
/**
* Returns the current {@link Timeline}, or {@code null} if there is no timeline. * Returns the current {@link Timeline}, or {@code null} if there is no timeline.
*/ */
Timeline getCurrentTimeline(); Timeline getCurrentTimeline();
/** /**
* Returns the current manifest. The type depends on the {@link MediaSource} passed to * Returns the index of the period currently being played, or {@link C#INDEX_UNSET} if unknown.
* {@link #prepare}.
*/ */
Object getCurrentManifest(); int getCurrentPeriodIndex();
/** /**
* Returns the index of the window associated with the current period, or {@link C#INDEX_UNSET} if * Returns the index of the window currently being played.
* the timeline is not set.
*/ */
int getCurrentWindowIndex(); int getCurrentWindowIndex();
...@@ -380,14 +381,13 @@ public interface ExoPlayer { ...@@ -380,14 +381,13 @@ public interface ExoPlayer {
long getDuration(); long getDuration();
/** /**
* Returns the playback position in the current window, in milliseconds, or {@link C#TIME_UNSET} * Returns the playback position in the current window, in milliseconds.
* if the timeline is not set.
*/ */
long getCurrentPosition(); long getCurrentPosition();
/** /**
* Returns an estimate of the position in the current window up to which data is buffered, or * Returns an estimate of the position in the current window up to which data is buffered, in
* {@link C#TIME_UNSET} if no estimate is available. * milliseconds.
*/ */
long getBufferedPosition(); long getBufferedPosition();
......
...@@ -40,6 +40,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -40,6 +40,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
private final Timeline.Window window; private final Timeline.Window window;
private final Timeline.Period period; private final Timeline.Period period;
private boolean pendingInitialSeek;
private boolean playWhenReady; private boolean playWhenReady;
private int playbackState; private int playbackState;
private int pendingSeekAcks; private int pendingSeekAcks;
...@@ -137,7 +138,9 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -137,7 +138,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override @Override
public void seekToDefaultPosition(int windowIndex) { public void seekToDefaultPosition(int windowIndex) {
if (timeline == null) { if (timeline == null) {
// TODO: Handle seeks before the timeline is set. maskingWindowIndex = windowIndex;
maskingWindowPositionMs = C.TIME_UNSET;
pendingInitialSeek = true;
} else { } else {
Assertions.checkIndex(windowIndex, 0, timeline.getWindowCount()); Assertions.checkIndex(windowIndex, 0, timeline.getWindowCount());
pendingSeekAcks++; pendingSeekAcks++;
...@@ -157,7 +160,9 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -157,7 +160,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
if (positionMs == C.TIME_UNSET) { if (positionMs == C.TIME_UNSET) {
seekToDefaultPosition(windowIndex); seekToDefaultPosition(windowIndex);
} else if (timeline == null) { } else if (timeline == null) {
// TODO: Handle seeks before the timeline is set. maskingWindowIndex = windowIndex;
maskingWindowPositionMs = positionMs;
pendingInitialSeek = true;
} else { } else {
Assertions.checkIndex(windowIndex, 0, timeline.getWindowCount()); Assertions.checkIndex(windowIndex, 0, timeline.getWindowCount());
pendingSeekAcks++; pendingSeekAcks++;
...@@ -174,7 +179,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -174,7 +179,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
internalPlayer.seekTo(periodIndex, C.msToUs(periodPositionMs)); internalPlayer.seekTo(periodIndex, C.msToUs(periodPositionMs));
for (EventListener listener : listeners) { for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(periodIndex, periodPositionMs); listener.onPositionDiscontinuity();
} }
} }
} }
...@@ -201,10 +206,13 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -201,10 +206,13 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
@Override @Override
public int getCurrentPeriodIndex() {
return playbackInfo.periodIndex;
}
@Override
public int getCurrentWindowIndex() { public int getCurrentWindowIndex() {
if (timeline == null) { if (timeline == null || pendingSeekAcks > 0) {
return C.INDEX_UNSET;
} else if (pendingSeekAcks > 0) {
return maskingWindowIndex; return maskingWindowIndex;
} else { } else {
return timeline.getPeriod(playbackInfo.periodIndex, period).windowIndex; return timeline.getPeriod(playbackInfo.periodIndex, period).windowIndex;
...@@ -221,9 +229,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -221,9 +229,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override @Override
public long getCurrentPosition() { public long getCurrentPosition() {
if (timeline == null) { if (timeline == null || pendingSeekAcks > 0) {
return C.TIME_UNSET;
} else if (pendingSeekAcks > 0) {
return maskingWindowPositionMs; return maskingWindowPositionMs;
} else { } else {
timeline.getPeriod(playbackInfo.periodIndex, period); timeline.getPeriod(playbackInfo.periodIndex, period);
...@@ -234,9 +240,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -234,9 +240,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override @Override
public long getBufferedPosition() { public long getBufferedPosition() {
// TODO - Implement this properly. // TODO - Implement this properly.
if (timeline == null) { if (timeline == null || pendingSeekAcks > 0) {
return C.TIME_UNSET;
} else if (pendingSeekAcks > 0) {
return maskingWindowPositionMs; return maskingWindowPositionMs;
} else { } else {
int periodIndex = playbackInfo.periodIndex; int periodIndex = playbackInfo.periodIndex;
...@@ -293,9 +297,8 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -293,9 +297,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
case ExoPlayerImplInternal.MSG_SEEK_ACK: { case ExoPlayerImplInternal.MSG_SEEK_ACK: {
if (--pendingSeekAcks == 0) { if (--pendingSeekAcks == 0) {
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj; playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
long positionMs = C.usToMs(playbackInfo.startPositionUs);
for (EventListener listener : listeners) { for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(playbackInfo.periodIndex, positionMs); listener.onPositionDiscontinuity();
} }
} }
break; break;
...@@ -303,9 +306,8 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -303,9 +306,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
case ExoPlayerImplInternal.MSG_POSITION_DISCONTINUITY: { case ExoPlayerImplInternal.MSG_POSITION_DISCONTINUITY: {
if (pendingSeekAcks == 0) { if (pendingSeekAcks == 0) {
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj; playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
long positionMs = C.usToMs(playbackInfo.startPositionUs);
for (EventListener listener : listeners) { for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(playbackInfo.periodIndex, positionMs); listener.onPositionDiscontinuity();
} }
} }
break; break;
...@@ -315,6 +317,10 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -315,6 +317,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
Pair<Timeline, Object> timelineAndManifest = (Pair<Timeline, Object>) msg.obj; Pair<Timeline, Object> timelineAndManifest = (Pair<Timeline, Object>) msg.obj;
timeline = timelineAndManifest.first; timeline = timelineAndManifest.first;
manifest = timelineAndManifest.second; manifest = timelineAndManifest.second;
if (pendingInitialSeek) {
pendingInitialSeek = false;
seekTo(maskingWindowIndex, maskingWindowPositionMs);
}
for (EventListener listener : listeners) { for (EventListener listener : listeners) {
listener.onTimelineChanged(timeline, manifest); listener.onTimelineChanged(timeline, manifest);
} }
......
...@@ -461,6 +461,11 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -461,6 +461,11 @@ public final class SimpleExoPlayer implements ExoPlayer {
} }
@Override @Override
public int getCurrentPeriodIndex() {
return player.getCurrentPeriodIndex();
}
@Override
public int getCurrentWindowIndex() { public int getCurrentWindowIndex() {
return player.getCurrentWindowIndex(); return player.getCurrentWindowIndex();
} }
......
...@@ -84,7 +84,7 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe ...@@ -84,7 +84,7 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
} }
@Override @Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) { public void onPositionDiscontinuity() {
updateAndPost(); updateAndPost();
} }
......
...@@ -210,7 +210,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -210,7 +210,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
} }
@Override @Override
public final void onPositionDiscontinuity(int periodIndex, long positionMs) { public final void onPositionDiscontinuity() {
// Do nothing. // Do nothing.
} }
......
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