diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 56e913b357..b87f83c336 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -814,24 +814,14 @@ import java.util.Set; @Override public TrackOutput track(int id, int type) { - int trackCount = sampleQueues.length; - if (MAPPABLE_TYPES.contains(type)) { // Track types in MAPPABLE_TYPES are handled manually to ignore IDs. - int sampleQueueIndex = sampleQueueIndicesByType.get(type, C.INDEX_UNSET); - if (sampleQueueIndex != C.INDEX_UNSET) { - if (sampleQueueMappingDoneByType.contains(type)) { - return sampleQueueTrackIds[sampleQueueIndex] == id - ? sampleQueues[sampleQueueIndex] - : createDummyTrackOutput(id, type); - } else { - sampleQueueMappingDoneByType.add(type); - sampleQueueTrackIds[sampleQueueIndex] = id; - return sampleQueues[sampleQueueIndex]; - } + @Nullable TrackOutput mappedTrackOutput = getMappedTrackOutput(id, type); + if (mappedTrackOutput != null) { + return mappedTrackOutput; } } else /* sparse track */ { - for (int i = 0; i < trackCount; i++) { + for (int i = 0; i < sampleQueues.length; i++) { if (sampleQueueTrackIds[i] == id) { return sampleQueues[i]; } @@ -840,6 +830,8 @@ import java.util.Set; if (tracksEnded) { return createDummyTrackOutput(id, type); } + + int trackCount = sampleQueues.length; SampleQueue trackOutput = new FormatAdjustingSampleQueue(allocator, overridingDrmInitData); trackOutput.setSampleOffsetUs(sampleOffsetUs); trackOutput.sourceId(chunkUid); @@ -865,6 +857,37 @@ import java.util.Set; return trackOutput; } + /** + * Returns the {@link TrackOutput} for the provided {@code type} and {@code id}, or null if none + * has been created yet. + * + *
If a {@link SampleQueue} for {@code type} has been created and is mapped, but it has a + * different ID, then return a {@link DummyTrackOutput} that does nothing. + * + *
If a {@link SampleQueue} for {@code type} has been created but is not mapped, then map it to + * this {@code id} and return it. This situation can happen after a call to {@link #init} with + * {@code reusingExtractor=false}. + * + * @param id The ID of the track. + * @param type The type of the track, must be one of {@link #MAPPABLE_TYPES}. + * @return The the mapped {@link TrackOutput}, or null if it's not been created yet. + */ + @Nullable + private TrackOutput getMappedTrackOutput(int id, int type) { + Assertions.checkArgument(MAPPABLE_TYPES.contains(type)); + int sampleQueueIndex = sampleQueueIndicesByType.get(type, C.INDEX_UNSET); + if (sampleQueueIndex == C.INDEX_UNSET) { + return null; + } + + if (sampleQueueMappingDoneByType.add(type)) { + sampleQueueTrackIds[sampleQueueIndex] = id; + } + return sampleQueueTrackIds[sampleQueueIndex] == id + ? sampleQueues[sampleQueueIndex] + : createDummyTrackOutput(id, type); + } + @Override public void endTracks() { tracksEnded = true;