use of com.google.android.exoplayer2.source.dash.manifest.RangedUri in project ExoPlayer by google.
the class RepresentationTest method testGetCacheKey.
public void testGetCacheKey() {
String uri = "http://www.google.com";
SegmentBase base = new SingleSegmentBase(new RangedUri(null, 0, 1), 1, 0, 1, 1);
Format format = Format.createVideoContainerFormat("0", MimeTypes.APPLICATION_MP4, null, MimeTypes.VIDEO_H264, 2500000, 1920, 1080, Format.NO_VALUE, null, 0);
Representation representation = Representation.newInstance("test_stream_1", 3, format, uri, base);
assertEquals("test_stream_1.0.3", representation.getCacheKey());
format = Format.createVideoContainerFormat("150", MimeTypes.APPLICATION_MP4, null, MimeTypes.VIDEO_H264, 2500000, 1920, 1080, Format.NO_VALUE, null, 0);
representation = Representation.newInstance("test_stream_1", Representation.REVISION_ID_DEFAULT, format, uri, base);
assertEquals("test_stream_1.150.-1", representation.getCacheKey());
}
use of com.google.android.exoplayer2.source.dash.manifest.RangedUri in project ExoPlayer by google.
the class DefaultDashChunkSource method getNextChunk.
@Override
public final void getNextChunk(MediaChunk previous, long playbackPositionUs, ChunkHolder out) {
if (fatalError != null) {
return;
}
long bufferedDurationUs = previous != null ? (previous.endTimeUs - playbackPositionUs) : 0;
trackSelection.updateSelectedTrack(bufferedDurationUs);
RepresentationHolder representationHolder = representationHolders[trackSelection.getSelectedIndex()];
Representation selectedRepresentation = representationHolder.representation;
DashSegmentIndex segmentIndex = representationHolder.segmentIndex;
RangedUri pendingInitializationUri = null;
RangedUri pendingIndexUri = null;
if (representationHolder.extractorWrapper.getSampleFormats() == null) {
pendingInitializationUri = selectedRepresentation.getInitializationUri();
}
if (segmentIndex == null) {
pendingIndexUri = selectedRepresentation.getIndexUri();
}
if (pendingInitializationUri != null || pendingIndexUri != null) {
// We have initialization and/or index requests to make.
out.chunk = newInitializationChunk(representationHolder, dataSource, trackSelection.getSelectedFormat(), trackSelection.getSelectionReason(), trackSelection.getSelectionData(), pendingInitializationUri, pendingIndexUri);
return;
}
long nowUs = getNowUnixTimeUs();
int availableSegmentCount = representationHolder.getSegmentCount();
if (availableSegmentCount == 0) {
// The index doesn't define any segments.
out.endOfStream = !manifest.dynamic || (periodIndex < manifest.getPeriodCount() - 1);
return;
}
int firstAvailableSegmentNum = representationHolder.getFirstSegmentNum();
int lastAvailableSegmentNum;
if (availableSegmentCount == DashSegmentIndex.INDEX_UNBOUNDED) {
// The index is itself unbounded. We need to use the current time to calculate the range of
// available segments.
long liveEdgeTimeUs = nowUs - manifest.availabilityStartTime * 1000;
long periodStartUs = manifest.getPeriod(periodIndex).startMs * 1000;
long liveEdgeTimeInPeriodUs = liveEdgeTimeUs - periodStartUs;
if (manifest.timeShiftBufferDepth != C.TIME_UNSET) {
long bufferDepthUs = manifest.timeShiftBufferDepth * 1000;
firstAvailableSegmentNum = Math.max(firstAvailableSegmentNum, representationHolder.getSegmentNum(liveEdgeTimeInPeriodUs - bufferDepthUs));
}
// getSegmentNum(liveEdgeTimestampUs) will not be completed yet, so subtract one to get the
// index of the last completed segment.
lastAvailableSegmentNum = representationHolder.getSegmentNum(liveEdgeTimeInPeriodUs) - 1;
} else {
lastAvailableSegmentNum = firstAvailableSegmentNum + availableSegmentCount - 1;
}
int segmentNum;
if (previous == null) {
segmentNum = Util.constrainValue(representationHolder.getSegmentNum(playbackPositionUs), firstAvailableSegmentNum, lastAvailableSegmentNum);
} else {
segmentNum = previous.getNextChunkIndex();
if (segmentNum < firstAvailableSegmentNum) {
// This is before the first chunk in the current manifest.
fatalError = new BehindLiveWindowException();
return;
}
}
if (segmentNum > lastAvailableSegmentNum || (missingLastSegment && segmentNum >= lastAvailableSegmentNum)) {
// This is beyond the last chunk in the current manifest.
out.endOfStream = !manifest.dynamic || (periodIndex < manifest.getPeriodCount() - 1);
return;
}
int maxSegmentCount = Math.min(maxSegmentsPerLoad, lastAvailableSegmentNum - segmentNum + 1);
out.chunk = newMediaChunk(representationHolder, dataSource, trackSelection.getSelectedFormat(), trackSelection.getSelectionReason(), trackSelection.getSelectionData(), segmentNum, maxSegmentCount);
}
use of com.google.android.exoplayer2.source.dash.manifest.RangedUri in project ExoPlayer by google.
the class DefaultDashChunkSource method newMediaChunk.
private static Chunk newMediaChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, int firstSegmentNum, int maxSegmentCount) {
Representation representation = representationHolder.representation;
long startTimeUs = representationHolder.getSegmentStartTimeUs(firstSegmentNum);
RangedUri segmentUri = representationHolder.getSegmentUrl(firstSegmentNum);
String baseUrl = representation.baseUrl;
if (representationHolder.extractorWrapper == null) {
long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum);
DataSpec dataSpec = new DataSpec(segmentUri.resolveUri(baseUrl), segmentUri.start, segmentUri.length, representation.getCacheKey());
return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, representationHolder.trackType, trackFormat);
} else {
int segmentCount = 1;
for (int i = 1; i < maxSegmentCount; i++) {
RangedUri nextSegmentUri = representationHolder.getSegmentUrl(firstSegmentNum + i);
RangedUri mergedSegmentUri = segmentUri.attemptMerge(nextSegmentUri, baseUrl);
if (mergedSegmentUri == null) {
// Unable to merge segment fetches because the URIs do not merge.
break;
}
segmentUri = mergedSegmentUri;
segmentCount++;
}
long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum + segmentCount - 1);
DataSpec dataSpec = new DataSpec(segmentUri.resolveUri(baseUrl), segmentUri.start, segmentUri.length, representation.getCacheKey());
long sampleOffsetUs = -representation.presentationTimeOffsetUs;
return new ContainerMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, segmentCount, sampleOffsetUs, representationHolder.extractorWrapper);
}
}
use of com.google.android.exoplayer2.source.dash.manifest.RangedUri in project ExoPlayer by google.
the class DashUtil method loadInitializationData.
private static void loadInitializationData(DataSource dataSource, Representation representation, int baseUrlIndex, ChunkExtractor chunkExtractor, RangedUri requestUri) throws IOException {
DataSpec dataSpec = DashUtil.buildDataSpec(representation, representation.baseUrls.get(baseUrlIndex).url, requestUri, /* flags= */
0);
InitializationChunk initializationChunk = new InitializationChunk(dataSource, dataSpec, representation.format, C.SELECTION_REASON_UNKNOWN, null, /* trackSelectionData */
chunkExtractor);
initializationChunk.load();
}
use of com.google.android.exoplayer2.source.dash.manifest.RangedUri in project ExoPlayer by google.
the class DefaultDashChunkSource method newMediaChunk.
protected Chunk newMediaChunk(RepresentationHolder representationHolder, DataSource dataSource, @C.TrackType int trackType, Format trackFormat, @C.SelectionReason int trackSelectionReason, Object trackSelectionData, long firstSegmentNum, int maxSegmentCount, long seekTimeUs, long nowPeriodTimeUs) {
Representation representation = representationHolder.representation;
long startTimeUs = representationHolder.getSegmentStartTimeUs(firstSegmentNum);
RangedUri segmentUri = representationHolder.getSegmentUrl(firstSegmentNum);
if (representationHolder.chunkExtractor == null) {
long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum);
int flags = representationHolder.isSegmentAvailableAtFullNetworkSpeed(firstSegmentNum, nowPeriodTimeUs) ? 0 : DataSpec.FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED;
DataSpec dataSpec = DashUtil.buildDataSpec(representation, representationHolder.selectedBaseUrl.url, segmentUri, flags);
return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, trackType, trackFormat);
} else {
int segmentCount = 1;
for (int i = 1; i < maxSegmentCount; i++) {
RangedUri nextSegmentUri = representationHolder.getSegmentUrl(firstSegmentNum + i);
@Nullable RangedUri mergedSegmentUri = segmentUri.attemptMerge(nextSegmentUri, representationHolder.selectedBaseUrl.url);
if (mergedSegmentUri == null) {
// Unable to merge segment fetches because the URIs do not merge.
break;
}
segmentUri = mergedSegmentUri;
segmentCount++;
}
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;
int flags = representationHolder.isSegmentAvailableAtFullNetworkSpeed(segmentNum, nowPeriodTimeUs) ? 0 : DataSpec.FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED;
DataSpec dataSpec = DashUtil.buildDataSpec(representation, representationHolder.selectedBaseUrl.url, segmentUri, flags);
long sampleOffsetUs = -representation.presentationTimeOffsetUs;
return new ContainerMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, seekTimeUs, clippedEndTimeUs, firstSegmentNum, segmentCount, sampleOffsetUs, representationHolder.chunkExtractor);
}
}
Aggregations