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