mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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
This commit is contained in:
parent
851ca20cc0
commit
9b39268e0b
2 changed files with 41 additions and 12 deletions
|
|
@ -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 {
|
||||||
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 {
|
||||||
} 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 {
|
||||||
trackSelection.getSelectionData(),
|
trackSelection.getSelectionData(),
|
||||||
segmentNum,
|
segmentNum,
|
||||||
maxSegmentCount,
|
maxSegmentCount,
|
||||||
seekTimeUs);
|
seekTimeUs,
|
||||||
|
nowUnixTimeUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
* @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 {
|
||||||
- 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,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue