Commit 95d591e0 by tonihei Committed by Oliver Woodman

Handle default position in DeferredMediaPeriod.

When creating DeferredMediaPeriods, we don't know the actual timeline yet and
thus the default position is also unknown. We can still forward the correct
default position by forwarding it the deferred media period as soon as it
becomes known.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189763460
parent 6674f63b
...@@ -63,6 +63,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo ...@@ -63,6 +63,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
private final Map<MediaPeriod, MediaSourceHolder> mediaSourceByMediaPeriod; private final Map<MediaPeriod, MediaSourceHolder> mediaSourceByMediaPeriod;
private final List<EventDispatcher> pendingOnCompletionActions; private final List<EventDispatcher> pendingOnCompletionActions;
private final boolean isAtomic; private final boolean isAtomic;
private final Timeline.Window window;
private ExoPlayer player; private ExoPlayer player;
private boolean listenerNotificationScheduled; private boolean listenerNotificationScheduled;
...@@ -133,6 +134,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo ...@@ -133,6 +134,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
this.pendingOnCompletionActions = new ArrayList<>(); this.pendingOnCompletionActions = new ArrayList<>();
this.query = new MediaSourceHolder(/* mediaSource= */ null); this.query = new MediaSourceHolder(/* mediaSource= */ null);
this.isAtomic = isAtomic; this.isAtomic = isAtomic;
window = new Timeline.Window();
addMediaSources(Arrays.asList(mediaSources)); addMediaSources(Arrays.asList(mediaSources));
} }
...@@ -577,12 +579,17 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo ...@@ -577,12 +579,17 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
periodOffsetUpdate); periodOffsetUpdate);
} }
mediaSourceHolder.timeline = deferredTimeline.cloneWithNewTimeline(timeline); mediaSourceHolder.timeline = deferredTimeline.cloneWithNewTimeline(timeline);
if (!mediaSourceHolder.isPrepared) { if (!mediaSourceHolder.isPrepared && !timeline.isEmpty()) {
timeline.getWindow(/* windowIndex= */ 0, window);
long defaultPeriodPositionUs =
window.getPositionInFirstPeriodUs() + window.getDefaultPositionUs();
for (int i = 0; i < mediaSourceHolder.activeMediaPeriods.size(); i++) { for (int i = 0; i < mediaSourceHolder.activeMediaPeriods.size(); i++) {
mediaSourceHolder.activeMediaPeriods.get(i).createPeriod(); DeferredMediaPeriod deferredMediaPeriod = mediaSourceHolder.activeMediaPeriods.get(i);
deferredMediaPeriod.setDefaultPreparePositionUs(defaultPeriodPositionUs);
deferredMediaPeriod.createPeriod();
} }
mediaSourceHolder.isPrepared = true;
} }
mediaSourceHolder.isPrepared = true;
scheduleListenerNotification(/* actionOnCompletion= */ null); scheduleListenerNotification(/* actionOnCompletion= */ null);
} }
...@@ -859,14 +866,15 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo ...@@ -859,14 +866,15 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
@Override @Override
public Window getWindow( public Window getWindow(
int windowIndex, Window window, boolean setIds, long defaultPositionProjectionUs) { int windowIndex, Window window, boolean setIds, long defaultPositionProjectionUs) {
// Dynamic window to indicate pending timeline updates.
return window.set( return window.set(
/* id= */ null, /* id= */ null,
/* presentationStartTimeMs= */ C.TIME_UNSET, /* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET,
/* isSeekable= */ false, /* isSeekable= */ false,
// Dynamic window to indicate pending timeline updates.
/* isDynamic= */ true, /* isDynamic= */ true,
/* defaultPositionUs= */ 0, // Position can't be projected yet as the default position is still unknown.
/* defaultPositionUs= */ defaultPositionProjectionUs > 0 ? C.TIME_UNSET : 0,
/* durationUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET,
/* firstPeriodIndex= */ 0, /* firstPeriodIndex= */ 0,
/* lastPeriodIndex= */ 0, /* lastPeriodIndex= */ 0,
...@@ -885,7 +893,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo ...@@ -885,7 +893,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
/* uid= */ null, /* uid= */ null,
/* windowIndex= */ 0, /* windowIndex= */ 0,
/* durationUs = */ C.TIME_UNSET, /* durationUs = */ C.TIME_UNSET,
/* positionInWindowUs= */ C.TIME_UNSET); /* positionInWindowUs= */ 0);
} }
@Override @Override
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source; package com.google.android.exoplayer2.source;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
...@@ -49,6 +50,7 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -49,6 +50,7 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
private long preparePositionUs; private long preparePositionUs;
private @Nullable PrepareErrorListener listener; private @Nullable PrepareErrorListener listener;
private boolean notifiedPrepareError; private boolean notifiedPrepareError;
private long preparePositionOverrideUs;
/** /**
* Creates a new deferred media period. * Creates a new deferred media period.
...@@ -61,6 +63,7 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -61,6 +63,7 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
this.id = id; this.id = id;
this.allocator = allocator; this.allocator = allocator;
this.mediaSource = mediaSource; this.mediaSource = mediaSource;
preparePositionOverrideUs = C.TIME_UNSET;
} }
/** /**
...@@ -75,6 +78,25 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -75,6 +78,25 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
} }
/** /**
* Sets the default prepare position at which to prepare the media period. This value is only used
* if the call to {@link MediaPeriod#prepare(Callback, long)} is being deferred and the call was
* made with a (presumably default) prepare position of 0.
*
* <p>Note that this will override an intentional seek to zero in the corresponding non-seekable
* timeline window. This is unlikely to be a problem as a non-zero default position usually only
* occurs for live playbacks and seeking to zero in a live window would cause
* BehindLiveWindowExceptions anyway.
*
* @param defaultPreparePositionUs The actual default prepare position, in microseconds.
*/
public void setDefaultPreparePositionUs(long defaultPreparePositionUs) {
if (preparePositionUs == 0 && defaultPreparePositionUs != 0) {
preparePositionOverrideUs = defaultPreparePositionUs;
preparePositionUs = defaultPreparePositionUs;
}
}
/**
* Calls {@link MediaSource#createPeriod(MediaPeriodId, Allocator)} on the wrapped source then * Calls {@link MediaSource#createPeriod(MediaPeriodId, Allocator)} on the wrapped source then
* prepares it if {@link #prepare(Callback, long)} has been called. Call {@link #releasePeriod()} * prepares it if {@link #prepare(Callback, long)} has been called. Call {@link #releasePeriod()}
* to release the period. * to release the period.
...@@ -131,6 +153,10 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -131,6 +153,10 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override @Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags, public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) { SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
if (preparePositionOverrideUs != C.TIME_UNSET && positionUs == 0) {
positionUs = preparePositionOverrideUs;
preparePositionOverrideUs = C.TIME_UNSET;
}
return mediaPeriod.selectTracks(selections, mayRetainStreamFlags, streams, streamResetFlags, return mediaPeriod.selectTracks(selections, mayRetainStreamFlags, streams, streamResetFlags,
positionUs); positionUs);
} }
......
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