mirror of
https://github.com/androidx/media.git
synced 2025-05-15 03:29:53 +08:00
Enforce sliding window of available segments for DASH DVB.
This commit is contained in:
parent
978a4d857a
commit
595147de9b
@ -326,13 +326,30 @@ public class DashChunkSource implements ChunkSource {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastSegmentNum = segmentIndex.getLastSegmentNum();
|
// TODO: Use UtcTimingElement where possible.
|
||||||
boolean indexUnbounded = lastSegmentNum == DashSegmentIndex.INDEX_UNBOUNDED;
|
long nowUs = System.currentTimeMillis() * 1000;
|
||||||
|
|
||||||
|
int firstAvailableSegmentNum = segmentIndex.getFirstSegmentNum();
|
||||||
|
int lastAvailableSegmentNum = segmentIndex.getLastSegmentNum();
|
||||||
|
boolean indexUnbounded = lastAvailableSegmentNum == DashSegmentIndex.INDEX_UNBOUNDED;
|
||||||
|
if (indexUnbounded) {
|
||||||
|
// The index is itself unbounded. We need to use the current time to calculate the range of
|
||||||
|
// available segments.
|
||||||
|
long liveEdgeTimestampUs = nowUs - currentManifest.availabilityStartTime * 1000;
|
||||||
|
if (currentManifest.timeShiftBufferDepth != -1) {
|
||||||
|
long bufferDepthUs = currentManifest.timeShiftBufferDepth * 1000;
|
||||||
|
firstAvailableSegmentNum = Math.max(firstAvailableSegmentNum,
|
||||||
|
segmentIndex.getSegmentNum(liveEdgeTimestampUs - bufferDepthUs));
|
||||||
|
}
|
||||||
|
// getSegmentNum(liveEdgeTimestampUs) will not be completed yet, so subtract one to get the
|
||||||
|
// index of the last completed segment.
|
||||||
|
lastAvailableSegmentNum = segmentIndex.getSegmentNum(liveEdgeTimestampUs) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
int segmentNum;
|
int segmentNum;
|
||||||
if (queue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
if (currentManifest.dynamic) {
|
if (currentManifest.dynamic) {
|
||||||
seekPositionUs = getLiveSeekPosition(indexUnbounded);
|
seekPositionUs = getLiveSeekPosition(nowUs, indexUnbounded);
|
||||||
}
|
}
|
||||||
segmentNum = segmentIndex.getSegmentNum(seekPositionUs);
|
segmentNum = segmentIndex.getSegmentNum(seekPositionUs);
|
||||||
} else {
|
} else {
|
||||||
@ -340,20 +357,20 @@ public class DashChunkSource implements ChunkSource {
|
|||||||
- representationHolder.segmentNumShift;
|
- representationHolder.segmentNumShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: For unbounded manifests, we need to enforce that we don't try and request chunks
|
|
||||||
// behind or in front of the live window.
|
|
||||||
if (currentManifest.dynamic) {
|
if (currentManifest.dynamic) {
|
||||||
if (segmentNum < segmentIndex.getFirstSegmentNum()) {
|
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();
|
||||||
return;
|
return;
|
||||||
} else if (!indexUnbounded && segmentNum > lastSegmentNum) {
|
} else if (segmentNum > lastAvailableSegmentNum) {
|
||||||
// This is beyond the last chunk in the current manifest.
|
// This chunk is beyond the last chunk in the current manifest. If the index is bounded
|
||||||
finishedCurrentManifest = true;
|
// we'll need to refresh it. If it's unbounded we just need to wait for a while before
|
||||||
|
// attempting to load the chunk.
|
||||||
|
finishedCurrentManifest = !indexUnbounded;
|
||||||
return;
|
return;
|
||||||
} else if (!indexUnbounded && segmentNum == lastSegmentNum) {
|
} else if (!indexUnbounded && segmentNum == lastAvailableSegmentNum) {
|
||||||
// This is the last chunk in the current manifest. Mark the manifest as being finished,
|
// This is the last chunk in a dynamic bounded manifest. We'll need to refresh the manifest
|
||||||
// but continue to return the final chunk.
|
// to obtain the next chunk.
|
||||||
finishedCurrentManifest = true;
|
finishedCurrentManifest = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,15 +474,14 @@ public class DashChunkSource implements ChunkSource {
|
|||||||
* For live playbacks, determines the seek position that snaps playback to be
|
* For live playbacks, determines the seek position that snaps playback to be
|
||||||
* {@link #liveEdgeLatencyUs} behind the live edge of the current manifest
|
* {@link #liveEdgeLatencyUs} behind the live edge of the current manifest
|
||||||
*
|
*
|
||||||
|
* @param nowUs An estimate of the current server time, in microseconds.
|
||||||
* @param indexUnbounded True if the segment index for this source is unbounded. False otherwise.
|
* @param indexUnbounded True if the segment index for this source is unbounded. False otherwise.
|
||||||
* @return The seek position in microseconds.
|
* @return The seek position in microseconds.
|
||||||
*/
|
*/
|
||||||
private long getLiveSeekPosition(boolean indexUnbounded) {
|
private long getLiveSeekPosition(long nowUs, boolean indexUnbounded) {
|
||||||
long liveEdgeTimestampUs;
|
long liveEdgeTimestampUs;
|
||||||
if (indexUnbounded) {
|
if (indexUnbounded) {
|
||||||
// TODO: Use UtcTimingElement where possible.
|
liveEdgeTimestampUs = nowUs - currentManifest.availabilityStartTime * 1000;
|
||||||
long nowMs = System.currentTimeMillis();
|
|
||||||
liveEdgeTimestampUs = (nowMs - currentManifest.availabilityStartTime) * 1000;
|
|
||||||
} else {
|
} else {
|
||||||
liveEdgeTimestampUs = Long.MIN_VALUE;
|
liveEdgeTimestampUs = Long.MIN_VALUE;
|
||||||
for (RepresentationHolder representationHolder : representationHolders.values()) {
|
for (RepresentationHolder representationHolder : representationHolders.values()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user