Add nullness annotations to DefaultDashChunkSource

#fixit

PiperOrigin-RevId: 559405572
This commit is contained in:
rohks 2023-08-23 14:27:43 +01:00 committed by Ian Baker
parent 2ad37d2e37
commit e2ee8ae1b0

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.exoplayer.dash;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkStateNotNull;
import static java.lang.Math.max;
import static java.lang.Math.min;
@ -62,6 +64,8 @@ import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
/** A default {@link DashChunkSource} implementation. */
@UnstableApi
@ -510,7 +514,9 @@ public class DefaultDashChunkSource implements DashChunkSource {
// from the stream. If the manifest defines an index then the stream shouldn't, but in cases
// where it does we should ignore it.
if (representationHolder.segmentIndex == null) {
@Nullable ChunkIndex chunkIndex = representationHolder.chunkExtractor.getChunkIndex();
@Nullable
ChunkIndex chunkIndex =
checkStateNotNull(representationHolder.chunkExtractor).getChunkIndex();
if (chunkIndex != null) {
representationHolders[trackIndex] =
representationHolder.copyWithNewSegmentIndex(
@ -636,7 +642,9 @@ public class DefaultDashChunkSource implements DashChunkSource {
lastAvailableSegmentNum);
}
private ArrayList<Representation> getRepresentations() {
@RequiresNonNull({"manifest", "adaptationSetIndices"})
private ArrayList<Representation> getRepresentations(
@UnknownInitialization DefaultDashChunkSource this) {
List<AdaptationSet> manifestAdaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
ArrayList<Representation> representations = new ArrayList<>();
for (int adaptationSetIndex : adaptationSetIndices) {
@ -664,6 +672,21 @@ public class DefaultDashChunkSource implements DashChunkSource {
manifest.availabilityStartTimeMs + manifest.getPeriod(periodIndex).startMs);
}
/**
* Creates a new {@link Chunk} for initialization.
*
* @param representationHolder The {@link Representation} holder for initialization.
* @param dataSource The source from which the data should be loaded.
* @param trackFormat The format of the track to which this chunk belongs.
* @param trackSelectionReason One of the {@link C.SelectionReason selection reasons}.
* @param trackSelectionData Additional data related to track selection.
* @param initializationUri The URI pointing to initialization data. Can be {@code null} if {@code
* indexUri} is not {@code null}.
* @param indexUri The URI pointing to index data. Can be {@code null} if {@code
* initializationUri} is not {@code null}.
* @param cmcdHeadersFactory The {@link CmcdHeadersFactory} for generating CMCD data.
*/
@RequiresNonNull("#1.chunkExtractor")
protected Chunk newInitializationChunk(
RepresentationHolder representationHolder,
DataSource dataSource,
@ -674,7 +697,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
@Nullable RangedUri indexUri,
@Nullable CmcdHeadersFactory cmcdHeadersFactory) {
Representation representation = representationHolder.representation;
@Nullable RangedUri requestUri;
RangedUri requestUri;
if (initializationUri != null) {
// It's common for initialization and index data to be stored adjacently. Attempt to merge
// the two requests together to request both at once.
@ -684,7 +707,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
requestUri = initializationUri;
}
} else {
requestUri = indexUri;
requestUri = checkNotNull(indexUri);
}
ImmutableMap<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders =
cmcdHeadersFactory == null
@ -714,7 +737,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
@C.TrackType int trackType,
Format trackFormat,
@C.SelectionReason int trackSelectionReason,
Object trackSelectionData,
@Nullable Object trackSelectionData,
long firstSegmentNum,
int maxSegmentCount,
long seekTimeUs,
@ -733,13 +756,17 @@ public class DefaultDashChunkSource implements DashChunkSource {
ImmutableMap<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders =
ImmutableMap.of();
if (cmcdHeadersFactory != null) {
Pair<String, String> nextObjectAndRangeRequest =
getNextObjectAndRangeRequest(firstSegmentNum, segmentUri, representationHolder);
cmcdHeadersFactory
.setChunkDurationUs(endTimeUs - startTimeUs)
.setObjectType(CmcdHeadersFactory.getObjectType(trackSelection))
.setObjectType(CmcdHeadersFactory.getObjectType(trackSelection));
@Nullable
Pair<String, String> nextObjectAndRangeRequest =
getNextObjectAndRangeRequest(firstSegmentNum, segmentUri, representationHolder);
if (nextObjectAndRangeRequest != null) {
cmcdHeadersFactory
.setNextObjectRequest(nextObjectAndRangeRequest.first)
.setNextRangeRequest(nextObjectAndRangeRequest.second);
}
httpRequestHeaders = cmcdHeadersFactory.createHttpRequestHeaders();
}
DataSpec dataSpec =
@ -788,13 +815,17 @@ public class DefaultDashChunkSource implements DashChunkSource {
ImmutableMap<@CmcdConfiguration.HeaderKey String, String> httpRequestHeaders =
ImmutableMap.of();
if (cmcdHeadersFactory != null) {
Pair<String, String> nextObjectAndRangeRequest =
getNextObjectAndRangeRequest(segmentNum, segmentUri, representationHolder);
cmcdHeadersFactory
.setChunkDurationUs(endTimeUs - startTimeUs)
.setObjectType(CmcdHeadersFactory.getObjectType(trackSelection))
.setObjectType(CmcdHeadersFactory.getObjectType(trackSelection));
@Nullable
Pair<String, String> nextObjectAndRangeRequest =
getNextObjectAndRangeRequest(firstSegmentNum, segmentUri, representationHolder);
if (nextObjectAndRangeRequest != null) {
cmcdHeadersFactory
.setNextObjectRequest(nextObjectAndRangeRequest.first)
.setNextRangeRequest(nextObjectAndRangeRequest.second);
}
httpRequestHeaders = cmcdHeadersFactory.createHttpRequestHeaders();
}
DataSpec dataSpec =
@ -822,9 +853,12 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
}
@Nullable
private Pair<String, String> getNextObjectAndRangeRequest(
long segmentNum, RangedUri segmentUri, RepresentationHolder representationHolder) {
if (segmentNum + 1 < representationHolder.getSegmentCount()) {
if (segmentNum + 1 >= representationHolder.getSegmentCount()) {
return null;
}
RangedUri nextSegmentUri = representationHolder.getSegmentUrl(segmentNum + 1);
Uri uri = segmentUri.resolveUri(representationHolder.selectedBaseUrl.url);
Uri nextUri = nextSegmentUri.resolveUri(representationHolder.selectedBaseUrl.url);
@ -836,8 +870,6 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
return new Pair<>(nextObjectRequest, nextRangeRequest);
}
return new Pair<>(null, null);
}
private RepresentationHolder updateSelectedBaseUrl(int trackIndex) {
RepresentationHolder representationHolder = representationHolders[trackIndex];
@ -976,6 +1008,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
newIndex);
}
checkStateNotNull(newIndex);
long oldIndexFirstSegmentNum = oldIndex.getFirstSegmentNum();
long oldIndexStartTimeUs = oldIndex.getTimeUs(oldIndexFirstSegmentNum);
long oldIndexLastSegmentNum = oldIndexFirstSegmentNum + oldIndexSegmentCount - 1;
@ -1036,43 +1070,47 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
public long getFirstSegmentNum() {
return segmentIndex.getFirstSegmentNum() + segmentNumShift;
return checkStateNotNull(segmentIndex).getFirstSegmentNum() + segmentNumShift;
}
public long getFirstAvailableSegmentNum(long nowUnixTimeUs) {
return segmentIndex.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs)
return checkStateNotNull(segmentIndex)
.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs)
+ segmentNumShift;
}
public long getSegmentCount() {
return segmentIndex.getSegmentCount(periodDurationUs);
return checkStateNotNull(segmentIndex).getSegmentCount(periodDurationUs);
}
public long getSegmentStartTimeUs(long segmentNum) {
return segmentIndex.getTimeUs(segmentNum - segmentNumShift);
return checkStateNotNull(segmentIndex).getTimeUs(segmentNum - segmentNumShift);
}
public long getSegmentEndTimeUs(long segmentNum) {
return getSegmentStartTimeUs(segmentNum)
+ segmentIndex.getDurationUs(segmentNum - segmentNumShift, periodDurationUs);
+ checkStateNotNull(segmentIndex)
.getDurationUs(segmentNum - segmentNumShift, periodDurationUs);
}
public long getSegmentNum(long positionUs) {
return segmentIndex.getSegmentNum(positionUs, periodDurationUs) + segmentNumShift;
return checkStateNotNull(segmentIndex).getSegmentNum(positionUs, periodDurationUs)
+ segmentNumShift;
}
public RangedUri getSegmentUrl(long segmentNum) {
return segmentIndex.getSegmentUrl(segmentNum - segmentNumShift);
return checkStateNotNull(segmentIndex).getSegmentUrl(segmentNum - segmentNumShift);
}
public long getLastAvailableSegmentNum(long nowUnixTimeUs) {
return getFirstAvailableSegmentNum(nowUnixTimeUs)
+ segmentIndex.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs)
+ checkStateNotNull(segmentIndex)
.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs)
- 1;
}
public boolean isSegmentAvailableAtFullNetworkSpeed(long segmentNum, long nowPeriodTimeUs) {
if (segmentIndex.isExplicit()) {
if (checkStateNotNull(segmentIndex).isExplicit()) {
// We don't support segment availability for explicit indices (internal ref: b/172894901).
// Hence, also assume all segments in explicit indices are always available at full network
// speed even if they end in the future.