mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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:
parent
04341394a3
commit
c8af6d176f
@ -486,16 +486,16 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean pendingReset = isPendingReset();
|
boolean pendingReset = isPendingReset();
|
||||||
MediaChunk previousChunk;
|
List<BaseMediaChunk> chunkQueue;
|
||||||
long loadPositionUs;
|
long loadPositionUs;
|
||||||
if (pendingReset) {
|
if (pendingReset) {
|
||||||
previousChunk = null;
|
chunkQueue = Collections.emptyList();
|
||||||
loadPositionUs = pendingResetPositionUs;
|
loadPositionUs = pendingResetPositionUs;
|
||||||
} else {
|
} else {
|
||||||
previousChunk = getLastMediaChunk();
|
chunkQueue = readOnlyMediaChunks;
|
||||||
loadPositionUs = previousChunk.endTimeUs;
|
loadPositionUs = getLastMediaChunk().endTimeUs;
|
||||||
}
|
}
|
||||||
chunkSource.getNextChunk(previousChunk, positionUs, loadPositionUs, nextChunkHolder);
|
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
|
||||||
boolean endOfStream = nextChunkHolder.endOfStream;
|
boolean endOfStream = nextChunkHolder.endOfStream;
|
||||||
Chunk loadable = nextChunkHolder.chunk;
|
Chunk loadable = nextChunkHolder.chunk;
|
||||||
nextChunkHolder.clear();
|
nextChunkHolder.clear();
|
||||||
|
@ -59,22 +59,25 @@ public interface ChunkSource {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next chunk to load.
|
* 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
|
* 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.
|
* 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
|
* @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
|
* 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
|
* starting position in the period minus the duration of any media in previous periods still
|
||||||
* to be played.
|
* 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
|
* 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.
|
* @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);
|
ChunkHolder out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,7 +238,10 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getNextChunk(MediaChunk previous, long playbackPositionUs, long loadPositionUs,
|
public void getNextChunk(
|
||||||
|
long playbackPositionUs,
|
||||||
|
long loadPositionUs,
|
||||||
|
List<? extends MediaChunk> queue,
|
||||||
ChunkHolder out) {
|
ChunkHolder out) {
|
||||||
if (fatalError != null) {
|
if (fatalError != null) {
|
||||||
return;
|
return;
|
||||||
@ -311,11 +314,11 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||||||
updateLiveEdgeTimeUs(representationHolder, lastAvailableSegmentNum);
|
updateLiveEdgeTimeUs(representationHolder, lastAvailableSegmentNum);
|
||||||
|
|
||||||
long segmentNum;
|
long segmentNum;
|
||||||
if (previous == null) {
|
if (queue.isEmpty()) {
|
||||||
segmentNum = Util.constrainValue(representationHolder.getSegmentNum(loadPositionUs),
|
segmentNum = Util.constrainValue(representationHolder.getSegmentNum(loadPositionUs),
|
||||||
firstAvailableSegmentNum, lastAvailableSegmentNum);
|
firstAvailableSegmentNum, lastAvailableSegmentNum);
|
||||||
} else {
|
} else {
|
||||||
segmentNum = previous.getNextChunkIndex();
|
segmentNum = queue.get(queue.size() - 1).getNextChunkIndex();
|
||||||
if (segmentNum < firstAvailableSegmentNum) {
|
if (segmentNum < firstAvailableSegmentNum) {
|
||||||
// This is before the first chunk in the current manifest.
|
// This is before the first chunk in the current manifest.
|
||||||
fatalError = new BehindLiveWindowException();
|
fatalError = new BehindLiveWindowException();
|
||||||
@ -332,7 +335,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||||||
|
|
||||||
int maxSegmentCount =
|
int maxSegmentCount =
|
||||||
(int) Math.min(maxSegmentsPerLoad, lastAvailableSegmentNum - segmentNum + 1);
|
(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 =
|
out.chunk =
|
||||||
newMediaChunk(
|
newMediaChunk(
|
||||||
representationHolder,
|
representationHolder,
|
||||||
|
@ -204,18 +204,20 @@ import java.util.List;
|
|||||||
* but the end of the stream has not been reached, {@link HlsChunkHolder#playlist} is set to
|
* 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.
|
* 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
|
* @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
|
* 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
|
* started, the value will be the starting position in the period minus the duration of any
|
||||||
* media in previous periods still to be played.
|
* media in previous periods still to be played.
|
||||||
* @param loadPositionUs The current load position relative to the period start in microseconds.
|
* @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
|
* If {@code queue} is empty, this is the starting position from which chunks should be
|
||||||
* provided. Else it's equal to {@code previous.endTimeUs}.
|
* 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.
|
* @param out A holder to populate.
|
||||||
*/
|
*/
|
||||||
public void getNextChunk(
|
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
|
int oldVariantIndex = previous == null ? C.INDEX_UNSET
|
||||||
: trackGroup.indexOf(previous.trackFormat);
|
: trackGroup.indexOf(previous.trackFormat);
|
||||||
long bufferedDurationUs = loadPositionUs - playbackPositionUs;
|
long bufferedDurationUs = loadPositionUs - playbackPositionUs;
|
||||||
|
@ -49,6 +49,8 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads {@link HlsMediaChunk}s obtained from a {@link HlsChunkSource}, and provides
|
* 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 EventDispatcher eventDispatcher;
|
||||||
private final HlsChunkSource.HlsChunkHolder nextChunkHolder;
|
private final HlsChunkSource.HlsChunkHolder nextChunkHolder;
|
||||||
private final ArrayList<HlsMediaChunk> mediaChunks;
|
private final ArrayList<HlsMediaChunk> mediaChunks;
|
||||||
|
private final List<HlsMediaChunk> readOnlyMediaChunks;
|
||||||
private final Runnable maybeFinishPrepareRunnable;
|
private final Runnable maybeFinishPrepareRunnable;
|
||||||
private final Runnable onTracksEndedRunnable;
|
private final Runnable onTracksEndedRunnable;
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
@ -168,6 +171,7 @@ import java.util.Arrays;
|
|||||||
sampleQueueIsAudioVideoFlags = new boolean[0];
|
sampleQueueIsAudioVideoFlags = new boolean[0];
|
||||||
sampleQueuesEnabledStates = new boolean[0];
|
sampleQueuesEnabledStates = new boolean[0];
|
||||||
mediaChunks = new ArrayList<>();
|
mediaChunks = new ArrayList<>();
|
||||||
|
readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks);
|
||||||
hlsSampleStreams = new ArrayList<>();
|
hlsSampleStreams = new ArrayList<>();
|
||||||
maybeFinishPrepareRunnable =
|
maybeFinishPrepareRunnable =
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@ -527,16 +531,16 @@ import java.util.Arrays;
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HlsMediaChunk previousChunk;
|
List<HlsMediaChunk> chunkQueue;
|
||||||
long loadPositionUs;
|
long loadPositionUs;
|
||||||
if (isPendingReset()) {
|
if (isPendingReset()) {
|
||||||
previousChunk = null;
|
chunkQueue = Collections.emptyList();
|
||||||
loadPositionUs = pendingResetPositionUs;
|
loadPositionUs = pendingResetPositionUs;
|
||||||
} else {
|
} else {
|
||||||
previousChunk = getLastMediaChunk();
|
chunkQueue = readOnlyMediaChunks;
|
||||||
loadPositionUs = previousChunk.endTimeUs;
|
loadPositionUs = getLastMediaChunk().endTimeUs;
|
||||||
}
|
}
|
||||||
chunkSource.getNextChunk(previousChunk, positionUs, loadPositionUs, nextChunkHolder);
|
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
|
||||||
boolean endOfStream = nextChunkHolder.endOfStream;
|
boolean endOfStream = nextChunkHolder.endOfStream;
|
||||||
Chunk loadable = nextChunkHolder.chunk;
|
Chunk loadable = nextChunkHolder.chunk;
|
||||||
HlsMasterPlaylist.HlsUrl playlistToLoad = nextChunkHolder.playlist;
|
HlsMasterPlaylist.HlsUrl playlistToLoad = nextChunkHolder.playlist;
|
||||||
|
@ -166,7 +166,10 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
ChunkHolder out) {
|
||||||
if (fatalError != null) {
|
if (fatalError != null) {
|
||||||
return;
|
return;
|
||||||
@ -180,10 +183,11 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int chunkIndex;
|
int chunkIndex;
|
||||||
if (previous == null) {
|
if (queue.isEmpty()) {
|
||||||
chunkIndex = streamElement.getChunkIndex(loadPositionUs);
|
chunkIndex = streamElement.getChunkIndex(loadPositionUs);
|
||||||
} else {
|
} else {
|
||||||
chunkIndex = (int) (previous.getNextChunkIndex() - currentManifestChunkOffset);
|
chunkIndex =
|
||||||
|
(int) (queue.get(queue.size() - 1).getNextChunkIndex() - currentManifestChunkOffset);
|
||||||
if (chunkIndex < 0) {
|
if (chunkIndex < 0) {
|
||||||
// This is before the first chunk in the current manifest.
|
// This is before the first chunk in the current manifest.
|
||||||
fatalError = new BehindLiveWindowException();
|
fatalError = new BehindLiveWindowException();
|
||||||
@ -203,7 +207,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||||||
|
|
||||||
long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
|
long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
|
||||||
long chunkEndTimeUs = chunkStartTimeUs + streamElement.getChunkDurationUs(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 currentAbsoluteChunkIndex = chunkIndex + currentManifestChunkOffset;
|
||||||
|
|
||||||
int trackSelectionIndex = trackSelection.getSelectedIndex();
|
int trackSelectionIndex = trackSelection.getSelectedIndex();
|
||||||
|
@ -95,14 +95,17 @@ public final class FakeChunkSource implements ChunkSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getNextChunk(MediaChunk previous, long playbackPositionUs, long loadPositionUs,
|
public void getNextChunk(
|
||||||
|
long playbackPositionUs,
|
||||||
|
long loadPositionUs,
|
||||||
|
List<? extends MediaChunk> queue,
|
||||||
ChunkHolder out) {
|
ChunkHolder out) {
|
||||||
long bufferedDurationUs = loadPositionUs - playbackPositionUs;
|
long bufferedDurationUs = loadPositionUs - playbackPositionUs;
|
||||||
trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, C.TIME_UNSET);
|
trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, C.TIME_UNSET);
|
||||||
int chunkIndex =
|
int chunkIndex =
|
||||||
previous == null
|
queue.isEmpty()
|
||||||
? dataSet.getChunkIndexByPosition(playbackPositionUs)
|
? dataSet.getChunkIndexByPosition(playbackPositionUs)
|
||||||
: (int) previous.getNextChunkIndex();
|
: (int) queue.get(queue.size() - 1).getNextChunkIndex();
|
||||||
if (chunkIndex >= dataSet.getChunkCount()) {
|
if (chunkIndex >= dataSet.getChunkCount()) {
|
||||||
out.endOfStream = true;
|
out.endOfStream = true;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user