Commit 9b39268e by christosts Committed by kim-vde

Mark DataSpec with FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED

Set the FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED on live load DataSpecs
for segments that are not yet fully available.

PiperOrigin-RevId: 333712684
parent 851ca20c
......@@ -50,14 +50,18 @@ public final class DashUtil {
*
* @param representation The {@link Representation} to which the request belongs.
* @param requestUri The {@link RangedUri} of the data to request.
* @param flags Flags to be set on the returned {@link DataSpec}. See {@link
* DataSpec.Builder#setFlags(int)}.
* @return The {@link DataSpec}.
*/
public static DataSpec buildDataSpec(Representation representation, RangedUri requestUri) {
public static DataSpec buildDataSpec(
Representation representation, RangedUri requestUri, int flags) {
return new DataSpec.Builder()
.setUri(requestUri.resolveUri(representation.baseUrl))
.setPosition(requestUri.start)
.setLength(requestUri.length)
.setKey(representation.getCacheKey())
.setFlags(flags)
.build();
}
......@@ -194,7 +198,7 @@ public final class DashUtil {
ChunkExtractor chunkExtractor,
RangedUri requestUri)
throws IOException {
DataSpec dataSpec = DashUtil.buildDataSpec(representation, requestUri);
DataSpec dataSpec = DashUtil.buildDataSpec(representation, requestUri, /* flags= */ 0);
InitializationChunk initializationChunk =
new InitializationChunk(
dataSource,
......
......@@ -302,7 +302,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
} else {
chunkIterators[i] =
new RepresentationSegmentIterator(
representationHolder, segmentNum, lastAvailableSegmentNum);
representationHolder, segmentNum, lastAvailableSegmentNum, nowUnixTimeUs);
}
}
}
......@@ -394,7 +394,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
trackSelection.getSelectionData(),
segmentNum,
maxSegmentCount,
seekTimeUs);
seekTimeUs,
nowUnixTimeUs);
}
@Override
......@@ -516,7 +517,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
} else {
requestUri = indexUri;
}
DataSpec dataSpec = DashUtil.buildDataSpec(representation, requestUri);
DataSpec dataSpec = DashUtil.buildDataSpec(representation, requestUri, /* flags= */ 0);
return new InitializationChunk(
dataSource,
dataSpec,
......@@ -535,14 +536,19 @@ public class DefaultDashChunkSource implements DashChunkSource {
Object trackSelectionData,
long firstSegmentNum,
int maxSegmentCount,
long seekTimeUs) {
long seekTimeUs,
long nowUnixTimeUs) {
Representation representation = representationHolder.representation;
long startTimeUs = representationHolder.getSegmentStartTimeUs(firstSegmentNum);
RangedUri segmentUri = representationHolder.getSegmentUrl(firstSegmentNum);
String baseUrl = representation.baseUrl;
if (representationHolder.chunkExtractor == null) {
long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum);
DataSpec dataSpec = DashUtil.buildDataSpec(representation, segmentUri);
int flags =
representationHolder.isSegmentAvailableAtFullNetworkSpeed(firstSegmentNum, nowUnixTimeUs)
? 0
: DataSpec.FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED;
DataSpec dataSpec = DashUtil.buildDataSpec(representation, segmentUri, flags);
return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason,
trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, trackType, trackFormat);
} else {
......@@ -557,13 +563,18 @@ public class DefaultDashChunkSource implements DashChunkSource {
segmentUri = mergedSegmentUri;
segmentCount++;
}
long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum + segmentCount - 1);
long segmentNum = firstSegmentNum + segmentCount - 1;
long endTimeUs = representationHolder.getSegmentEndTimeUs(segmentNum);
long periodDurationUs = representationHolder.periodDurationUs;
long clippedEndTimeUs =
periodDurationUs != C.TIME_UNSET && periodDurationUs <= endTimeUs
? periodDurationUs
: C.TIME_UNSET;
DataSpec dataSpec = DashUtil.buildDataSpec(representation, segmentUri);
int flags =
representationHolder.isSegmentAvailableAtFullNetworkSpeed(segmentNum, nowUnixTimeUs)
? 0
: DataSpec.FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED;
DataSpec dataSpec = DashUtil.buildDataSpec(representation, segmentUri, flags);
long sampleOffsetUs = -representation.presentationTimeOffsetUs;
return new ContainerMediaChunk(
dataSource,
......@@ -588,6 +599,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
protected static final class RepresentationSegmentIterator extends BaseMediaChunkIterator {
private final RepresentationHolder representationHolder;
private final long currentUnixTimeUs;
/**
* Creates iterator.
......@@ -595,20 +607,29 @@ public class DefaultDashChunkSource implements DashChunkSource {
* @param representation The {@link RepresentationHolder} to wrap.
* @param firstAvailableSegmentNum The number of the first available segment.
* @param lastAvailableSegmentNum The number of the last available segment.
* @param currentUnixTimeUs The current time in microseconds since the epoch used for
* calculating if segments are available at full network speed.
*/
public RepresentationSegmentIterator(
RepresentationHolder representation,
long firstAvailableSegmentNum,
long lastAvailableSegmentNum) {
long lastAvailableSegmentNum,
long currentUnixTimeUs) {
super(/* fromIndex= */ firstAvailableSegmentNum, /* toIndex= */ lastAvailableSegmentNum);
this.representationHolder = representation;
this.currentUnixTimeUs = currentUnixTimeUs;
}
@Override
public DataSpec getDataSpec() {
checkInBounds();
RangedUri segmentUri = representationHolder.getSegmentUrl(getCurrentIndex());
return DashUtil.buildDataSpec(representationHolder.representation, segmentUri);
long currentIndex = getCurrentIndex();
RangedUri segmentUri = representationHolder.getSegmentUrl(currentIndex);
int flags =
representationHolder.isSegmentAvailableAtFullNetworkSpeed(currentIndex, currentUnixTimeUs)
? 0
: DataSpec.FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED;
return DashUtil.buildDataSpec(representationHolder.representation, segmentUri, flags);
}
@Override
......@@ -768,6 +789,10 @@ public class DefaultDashChunkSource implements DashChunkSource {
- 1;
}
public boolean isSegmentAvailableAtFullNetworkSpeed(long segmentNum, long nowUnixTimeUs) {
return getSegmentEndTimeUs(segmentNum) <= nowUnixTimeUs;
}
@Nullable
private static ChunkExtractor createChunkExtractor(
int trackType,
......
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