Forward queue of media chunks to getNextChunk.

This allows to use this queue in the track selection in the future.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=202954871
This commit is contained in:
tonihei 2018-07-02 08:31:21 -07:00 committed by Oliver Woodman
parent 04341394a3
commit c8af6d176f
7 changed files with 50 additions and 31 deletions

View File

@ -486,16 +486,16 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
}
boolean pendingReset = isPendingReset();
MediaChunk previousChunk;
List<BaseMediaChunk> chunkQueue;
long loadPositionUs;
if (pendingReset) {
previousChunk = null;
chunkQueue = Collections.emptyList();
loadPositionUs = pendingResetPositionUs;
} else {
previousChunk = getLastMediaChunk();
loadPositionUs = previousChunk.endTimeUs;
chunkQueue = readOnlyMediaChunks;
loadPositionUs = getLastMediaChunk().endTimeUs;
}
chunkSource.getNextChunk(previousChunk, positionUs, loadPositionUs, nextChunkHolder);
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
boolean endOfStream = nextChunkHolder.endOfStream;
Chunk loadable = nextChunkHolder.chunk;
nextChunkHolder.clear();

View File

@ -59,22 +59,25 @@ public interface ChunkSource {
/**
* Returns the next chunk to load.
* <p>
* If a chunk is available then {@link ChunkHolder#chunk} is set. If the end of the stream has
*
* <p>If a chunk is available then {@link ChunkHolder#chunk} is set. If the end of the stream has
* been reached then {@link ChunkHolder#endOfStream} is set. If a chunk is not available but the
* end of the stream has not been reached, the {@link ChunkHolder} is not modified.
*
* @param previous The most recently loaded media chunk.
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this chunk source belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param loadPositionUs The current load position in microseconds. If {@code previous} is null,
* @param loadPositionUs The current load position in microseconds. If {@code queue} is empty,
* this is the starting position from which chunks should be provided. Else it's equal to
* {@code previous.endTimeUs}.
* {@link MediaChunk#endTimeUs} of the last chunk in the {@code queue}.
* @param queue The queue of buffered {@link MediaChunk}s.
* @param out A holder to populate.
*/
void getNextChunk(MediaChunk previous, long playbackPositionUs, long loadPositionUs,
void getNextChunk(
long playbackPositionUs,
long loadPositionUs,
List<? extends MediaChunk> queue,
ChunkHolder out);
/**

View File

@ -238,7 +238,10 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
@Override
public void getNextChunk(MediaChunk previous, long playbackPositionUs, long loadPositionUs,
public void getNextChunk(
long playbackPositionUs,
long loadPositionUs,
List<? extends MediaChunk> queue,
ChunkHolder out) {
if (fatalError != null) {
return;
@ -311,11 +314,11 @@ public class DefaultDashChunkSource implements DashChunkSource {
updateLiveEdgeTimeUs(representationHolder, lastAvailableSegmentNum);
long segmentNum;
if (previous == null) {
if (queue.isEmpty()) {
segmentNum = Util.constrainValue(representationHolder.getSegmentNum(loadPositionUs),
firstAvailableSegmentNum, lastAvailableSegmentNum);
} else {
segmentNum = previous.getNextChunkIndex();
segmentNum = queue.get(queue.size() - 1).getNextChunkIndex();
if (segmentNum < firstAvailableSegmentNum) {
// This is before the first chunk in the current manifest.
fatalError = new BehindLiveWindowException();
@ -332,7 +335,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
int maxSegmentCount =
(int) Math.min(maxSegmentsPerLoad, lastAvailableSegmentNum - segmentNum + 1);
long seekTimeUs = previous == null ? loadPositionUs : C.TIME_UNSET;
long seekTimeUs = queue.isEmpty() ? loadPositionUs : C.TIME_UNSET;
out.chunk =
newMediaChunk(
representationHolder,

View File

@ -204,18 +204,20 @@ import java.util.List;
* but the end of the stream has not been reached, {@link HlsChunkHolder#playlist} is set to
* contain the {@link HlsUrl} that refers to the playlist that needs refreshing.
*
* @param previous The most recently loaded media chunk.
* @param playbackPositionUs The current playback position relative to the period start in
* microseconds. If playback of the period to which this chunk source belongs has not yet
* started, the value will be the starting position in the period minus the duration of any
* media in previous periods still to be played.
* @param loadPositionUs The current load position relative to the period start in microseconds.
* If {@code previous} is null, this is the starting position from which chunks should be
* provided. Else it's equal to {@code previous.endTimeUs}.
* If {@code queue} is empty, this is the starting position from which chunks should be
* provided. Else it's equal to {@link HlsMediaChunk#endTimeUs} of the last chunk in the
* {@code queue}.
* @param queue The queue of buffered {@link HlsMediaChunk}s.
* @param out A holder to populate.
*/
public void getNextChunk(
HlsMediaChunk previous, long playbackPositionUs, long loadPositionUs, HlsChunkHolder out) {
long playbackPositionUs, long loadPositionUs, List<HlsMediaChunk> queue, HlsChunkHolder out) {
HlsMediaChunk previous = queue.isEmpty() ? null : queue.get(queue.size() - 1);
int oldVariantIndex = previous == null ? C.INDEX_UNSET
: trackGroup.indexOf(previous.trackFormat);
long bufferedDurationUs = loadPositionUs - playbackPositionUs;

View File

@ -49,6 +49,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Loads {@link HlsMediaChunk}s obtained from a {@link HlsChunkSource}, and provides
@ -100,6 +102,7 @@ import java.util.Arrays;
private final EventDispatcher eventDispatcher;
private final HlsChunkSource.HlsChunkHolder nextChunkHolder;
private final ArrayList<HlsMediaChunk> mediaChunks;
private final List<HlsMediaChunk> readOnlyMediaChunks;
private final Runnable maybeFinishPrepareRunnable;
private final Runnable onTracksEndedRunnable;
private final Handler handler;
@ -168,6 +171,7 @@ import java.util.Arrays;
sampleQueueIsAudioVideoFlags = new boolean[0];
sampleQueuesEnabledStates = new boolean[0];
mediaChunks = new ArrayList<>();
readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks);
hlsSampleStreams = new ArrayList<>();
maybeFinishPrepareRunnable =
new Runnable() {
@ -527,16 +531,16 @@ import java.util.Arrays;
return false;
}
HlsMediaChunk previousChunk;
List<HlsMediaChunk> chunkQueue;
long loadPositionUs;
if (isPendingReset()) {
previousChunk = null;
chunkQueue = Collections.emptyList();
loadPositionUs = pendingResetPositionUs;
} else {
previousChunk = getLastMediaChunk();
loadPositionUs = previousChunk.endTimeUs;
chunkQueue = readOnlyMediaChunks;
loadPositionUs = getLastMediaChunk().endTimeUs;
}
chunkSource.getNextChunk(previousChunk, positionUs, loadPositionUs, nextChunkHolder);
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
boolean endOfStream = nextChunkHolder.endOfStream;
Chunk loadable = nextChunkHolder.chunk;
HlsMasterPlaylist.HlsUrl playlistToLoad = nextChunkHolder.playlist;

View File

@ -166,7 +166,10 @@ public class DefaultSsChunkSource implements SsChunkSource {
}
@Override
public final void getNextChunk(MediaChunk previous, long playbackPositionUs, long loadPositionUs,
public final void getNextChunk(
long playbackPositionUs,
long loadPositionUs,
List<? extends MediaChunk> queue,
ChunkHolder out) {
if (fatalError != null) {
return;
@ -180,10 +183,11 @@ public class DefaultSsChunkSource implements SsChunkSource {
}
int chunkIndex;
if (previous == null) {
if (queue.isEmpty()) {
chunkIndex = streamElement.getChunkIndex(loadPositionUs);
} else {
chunkIndex = (int) (previous.getNextChunkIndex() - currentManifestChunkOffset);
chunkIndex =
(int) (queue.get(queue.size() - 1).getNextChunkIndex() - currentManifestChunkOffset);
if (chunkIndex < 0) {
// This is before the first chunk in the current manifest.
fatalError = new BehindLiveWindowException();
@ -203,7 +207,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
long chunkEndTimeUs = chunkStartTimeUs + streamElement.getChunkDurationUs(chunkIndex);
long chunkSeekTimeUs = previous == null ? loadPositionUs : C.TIME_UNSET;
long chunkSeekTimeUs = queue.isEmpty() ? loadPositionUs : C.TIME_UNSET;
int currentAbsoluteChunkIndex = chunkIndex + currentManifestChunkOffset;
int trackSelectionIndex = trackSelection.getSelectedIndex();

View File

@ -95,14 +95,17 @@ public final class FakeChunkSource implements ChunkSource {
}
@Override
public void getNextChunk(MediaChunk previous, long playbackPositionUs, long loadPositionUs,
public void getNextChunk(
long playbackPositionUs,
long loadPositionUs,
List<? extends MediaChunk> queue,
ChunkHolder out) {
long bufferedDurationUs = loadPositionUs - playbackPositionUs;
trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, C.TIME_UNSET);
int chunkIndex =
previous == null
queue.isEmpty()
? dataSet.getChunkIndexByPosition(playbackPositionUs)
: (int) previous.getNextChunkIndex();
: (int) queue.get(queue.size() - 1).getNextChunkIndex();
if (chunkIndex >= dataSet.getChunkCount()) {
out.endOfStream = true;
} else {