Make HLS behind-live-window behavior consistent.

- Propagate BehindLiveWindowException if we fall off the back
  of an HLS live stream.
- Consolidate seekPositionUs and playbackPositionUs into a
  single parameter.

Issue: #765
This commit is contained in:
Oliver Woodman 2015-11-27 15:57:20 +00:00
parent 81040e8d23
commit c62e535cf0
2 changed files with 13 additions and 18 deletions

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer.hls; package com.google.android.exoplayer.hls;
import com.google.android.exoplayer.BehindLiveWindowException;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.chunk.BaseChunkSampleSourceEventListener; import com.google.android.exoplayer.chunk.BaseChunkSampleSourceEventListener;
@ -249,14 +250,14 @@ public class HlsChunkSource {
* be performed by the calling {@link HlsSampleSource}. * be performed by the calling {@link HlsSampleSource}.
* *
* @param previousTsChunk The previously loaded chunk that the next chunk should follow. * @param previousTsChunk The previously loaded chunk that the next chunk should follow.
* @param seekPositionUs If there is no previous chunk, this parameter must specify the seek * @param playbackPositionUs The current playback position. If previousTsChunk is null then this
* position. If there is a previous chunk then this parameter is ignored. * parameter is the position from which playback is expected to start (or restart) and hence
* @param playbackPositionUs The current playback position. * should be interpreted as a seek position.
* @param out The holder to populate with the result. {@link ChunkOperationHolder#queueSize} is * @param out The holder to populate with the result. {@link ChunkOperationHolder#queueSize} is
* unused. * unused.
*/ */
public void getChunkOperation(TsChunk previousTsChunk, long seekPositionUs, public void getChunkOperation(TsChunk previousTsChunk, long playbackPositionUs,
long playbackPositionUs, ChunkOperationHolder out) { ChunkOperationHolder out) {
int nextVariantIndex; int nextVariantIndex;
boolean switchingVariantSpliced; boolean switchingVariantSpliced;
if (adaptiveMode == ADAPTIVE_MODE_NONE) { if (adaptiveMode == ADAPTIVE_MODE_NONE) {
@ -286,22 +287,15 @@ public class HlsChunkSource {
chunkMediaSequence = switchingVariantSpliced chunkMediaSequence = switchingVariantSpliced
? previousTsChunk.chunkIndex : previousTsChunk.chunkIndex + 1; ? previousTsChunk.chunkIndex : previousTsChunk.chunkIndex + 1;
if (chunkMediaSequence < mediaPlaylist.mediaSequence) { if (chunkMediaSequence < mediaPlaylist.mediaSequence) {
// TODO: Decide what we want to do with: https://github.com/google/ExoPlayer/issues/765 fatalError = new BehindLiveWindowException();
// if (allowSkipAhead) { return;
// If the chunk is no longer in the playlist. Skip ahead and start again.
chunkMediaSequence = getLiveStartChunkMediaSequence(nextVariantIndex);
liveDiscontinuity = true;
// } else {
// fatalError = new BehindLiveWindowException();
// return null;
// }
} }
} }
} else { } else {
// Not live. // Not live.
if (previousTsChunk == null) { if (previousTsChunk == null) {
chunkMediaSequence = Util.binarySearchFloor(mediaPlaylist.segments, seekPositionUs, true, chunkMediaSequence = Util.binarySearchFloor(mediaPlaylist.segments, playbackPositionUs,
true) + mediaPlaylist.mediaSequence; true, true) + mediaPlaylist.mediaSequence;
} else { } else {
chunkMediaSequence = switchingVariantSpliced chunkMediaSequence = switchingVariantSpliced
? previousTsChunk.chunkIndex : previousTsChunk.chunkIndex + 1; ? previousTsChunk.chunkIndex : previousTsChunk.chunkIndex + 1;

View File

@ -538,8 +538,9 @@ public final class HlsSampleSource implements SampleSource, SampleSourceReader,
return; return;
} }
chunkSource.getChunkOperation(previousTsLoadable, pendingResetPositionUs, chunkSource.getChunkOperation(previousTsLoadable,
downstreamPositionUs, chunkOperationHolder); pendingResetPositionUs != NO_RESET_PENDING ? pendingResetPositionUs : downstreamPositionUs,
chunkOperationHolder);
boolean endOfStream = chunkOperationHolder.endOfStream; boolean endOfStream = chunkOperationHolder.endOfStream;
Chunk nextLoadable = chunkOperationHolder.chunk; Chunk nextLoadable = chunkOperationHolder.chunk;
chunkOperationHolder.clear(); chunkOperationHolder.clear();