private static Chunk newInitializationChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, RangedUri initializationUri, RangedUri indexUri) { RangedUri requestUri; String baseUrl = representationHolder.representation.baseUrl; 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. requestUri = initializationUri.attemptMerge(indexUri, baseUrl); if (requestUri == null) { requestUri = initializationUri; } } else { requestUri = indexUri; } DataSpec dataSpec = new DataSpec(requestUri.resolveUri(baseUrl), requestUri.start, requestUri.length, representationHolder.representation.getCacheKey()); return new InitializationChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, representationHolder.extractorWrapper); }
private Chunk newInitializationChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, RangedUri initializationUri, RangedUri indexUri) { 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. requestUri = initializationUri.attemptMerge(indexUri); if (requestUri == null) { requestUri = initializationUri; } } else { requestUri = indexUri; } DataSpec dataSpec = new DataSpec(requestUri.getUri(), requestUri.start, requestUri.length, representationHolder.representation.getCacheKey()); return new InitializationChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, representationHolder.extractorWrapper); }
private Chunk newMediaChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, Format sampleFormat, int segmentNum) { Representation representation = representationHolder.representation; long startTimeUs = representationHolder.getSegmentStartTimeUs(segmentNum); long endTimeUs = representationHolder.getSegmentEndTimeUs(segmentNum); RangedUri segmentUri = representationHolder.getSegmentUrl(segmentNum); DataSpec dataSpec = new DataSpec(segmentUri.getUri(), segmentUri.start, segmentUri.length, representation.getCacheKey()); if (representationHolder.extractorWrapper == null) { return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, segmentNum, trackFormat); } else { long sampleOffsetUs = -representation.presentationTimeOffsetUs; return new ContainerMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, segmentNum, sampleOffsetUs, representationHolder.extractorWrapper, sampleFormat); } }
protected static Chunk newInitializationChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, RangedUri initializationUri, RangedUri indexUri) { RangedUri requestUri; String baseUrl = representationHolder.representation.baseUrl; 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. requestUri = initializationUri.attemptMerge(indexUri, baseUrl); if (requestUri == null) { requestUri = initializationUri; } } else { requestUri = indexUri; } DataSpec dataSpec = new DataSpec(requestUri.resolveUri(baseUrl), requestUri.start, requestUri.length, representationHolder.representation.getCacheKey()); return new InitializationChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, representationHolder.extractorWrapper); }
/** * Loads initialization data for the {@code representation} and optionally index data then * returns a {@link ChunkExtractorWrapper} which contains the output. * * @param dataSource The source from which the data should be loaded. * @param representation The representation which initialization chunk belongs to. * @param loadIndex Whether to load index data too. * @return A {@link ChunkExtractorWrapper} for the {@code representation}, or null if no * initialization or (if requested) index data exists. * @throws IOException Thrown when there is an error while loading. * @throws InterruptedException Thrown if the thread was interrupted. */ private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource, Representation representation, boolean loadIndex) throws IOException, InterruptedException { RangedUri initializationUri = representation.getInitializationUri(); if (initializationUri == null) { return null; } ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(representation.format); RangedUri requestUri; if (loadIndex) { RangedUri indexUri = representation.getIndexUri(); if (indexUri == null) { return 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. requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrl); if (requestUri == null) { loadInitializationData(dataSource, representation, extractorWrapper, initializationUri); requestUri = indexUri; } } else { requestUri = initializationUri; } loadInitializationData(dataSource, representation, extractorWrapper, requestUri); return extractorWrapper; }
private static void loadInitializationData(DataSource dataSource, Representation representation, ChunkExtractorWrapper extractorWrapper, RangedUri requestUri) throws IOException, InterruptedException { DataSpec dataSpec = new DataSpec(requestUri.resolveUri(representation.baseUrl), requestUri.start, requestUri.length, representation.getCacheKey()); InitializationChunk initializationChunk = new InitializationChunk(dataSource, dataSpec, representation.format, C.SELECTION_REASON_UNKNOWN, null /* trackSelectionData */, extractorWrapper); initializationChunk.load(); }
/** * Loads initialization data for the {@code representation} and optionally index data then * returns a {@link ChunkExtractorWrapper} which contains the output. * * @param dataSource The source from which the data should be loaded. * @param trackType The type of the representation. Typically one of the * {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants. * @param representation The representation which initialization chunk belongs to. * @param loadIndex Whether to load index data too. * @return A {@link ChunkExtractorWrapper} for the {@code representation}, or null if no * initialization or (if requested) index data exists. * @throws IOException Thrown when there is an error while loading. * @throws InterruptedException Thrown if the thread was interrupted. */ private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource, int trackType, Representation representation, boolean loadIndex) throws IOException, InterruptedException { RangedUri initializationUri = representation.getInitializationUri(); if (initializationUri == null) { return null; } ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(trackType, representation.format); RangedUri requestUri; if (loadIndex) { RangedUri indexUri = representation.getIndexUri(); if (indexUri == null) { return 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. requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrl); if (requestUri == null) { loadInitializationData(dataSource, representation, extractorWrapper, initializationUri); requestUri = indexUri; } } else { requestUri = initializationUri; } loadInitializationData(dataSource, representation, extractorWrapper, requestUri); return extractorWrapper; }
public RangedUri getSegmentUrl(int segmentNum) { return segmentIndex.getSegmentUrl(segmentNum - segmentNumShift); }
@Override public RangedUri getSegmentUrl(int segmentNum) { return new RangedUri(null, chunkIndex.offsets[segmentNum], chunkIndex.sizes[segmentNum]); }
@Override public RangedUri getSegmentUrl(int segmentNum) { return new RangedUri(uri, null, chunkIndex.offsets[segmentNum], chunkIndex.sizes[segmentNum]); }
@Override protected List<Segment> getSegments(DataSource dataSource, DashManifest manifest, RepresentationKey[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException { ArrayList<Segment> segments = new ArrayList<>(); for (RepresentationKey key : keys) { DashSegmentIndex index; try { index = getSegmentIndex(dataSource, manifest, key); if (index == null) { // Loading succeeded but there was no index. This is always a failure. throw new DownloadException("No index for representation: " + key); } } catch (IOException e) { if (allowIndexLoadErrors) { // Loading failed, but load errors are allowed. Advance to the next key. continue; } else { throw e; } } int segmentCount = index.getSegmentCount(C.TIME_UNSET); if (segmentCount == DashSegmentIndex.INDEX_UNBOUNDED) { throw new DownloadException("Unbounded index for representation: " + key); } Period period = manifest.getPeriod(key.periodIndex); Representation representation = period.adaptationSets.get(key.adaptationSetIndex) .representations.get(key.representationIndex); long startUs = C.msToUs(period.startMs); String baseUrl = representation.baseUrl; RangedUri initializationUri = representation.getInitializationUri(); if (initializationUri != null) { addSegment(segments, startUs, baseUrl, initializationUri); } RangedUri indexUri = representation.getIndexUri(); if (indexUri != null) { addSegment(segments, startUs, baseUrl, indexUri); } int firstSegmentNum = index.getFirstSegmentNum(); int lastSegmentNum = firstSegmentNum + segmentCount - 1; for (int j = firstSegmentNum; j <= lastSegmentNum; j++) { addSegment(segments, startUs + index.getTimeUs(j), baseUrl, index.getSegmentUrl(j)); } } return segments; }
private static void addSegment(ArrayList<Segment> segments, long startTimeUs, String baseUrl, RangedUri rangedUri) { DataSpec dataSpec = new DataSpec(rangedUri.resolveUri(baseUrl), rangedUri.start, rangedUri.length, null); segments.add(new Segment(startTimeUs, dataSpec)); }
/** * Returns a {@link RangedUri} defining the location of a segment. * * @param segmentNum The segment number. * @return The {@link RangedUri} defining the location of the data. */ RangedUri getSegmentUrl(int segmentNum);