Fix init data loading for non-reused extractors

PiperOrigin-RevId: 317322247
This commit is contained in:
aquilescanta 2020-06-19 17:31:38 +01:00 committed by Andrew Lewis
parent 457b215565
commit a8bf7e217b
3 changed files with 32 additions and 22 deletions

View file

@ -27,6 +27,7 @@ import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
import com.google.android.exoplayer2.extractor.ts.Ac4Extractor;
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.io.IOException;
@ -75,11 +76,13 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
}
@Override
public HlsMediaChunkExtractor reuseOrRecreate() {
if (extractor instanceof TsExtractor || extractor instanceof FragmentedMp4Extractor) {
// We can reuse this instance.
return this;
}
public boolean isReusable() {
return extractor instanceof TsExtractor || extractor instanceof FragmentedMp4Extractor;
}
@Override
public HlsMediaChunkExtractor recreate() {
Assertions.checkState(!isReusable());
Extractor newExtractorInstance;
if (extractor instanceof WebvttExtractor) {
newExtractorInstance = new WebvttExtractor(masterPlaylistFormat.language, timestampAdjuster);
@ -93,7 +96,7 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
newExtractorInstance = new Mp3Extractor();
} else {
throw new IllegalStateException(
"Unexpected previousExtractor type: " + extractor.getClass().getSimpleName());
"Unexpected extractor type for recreation: " + extractor.getClass().getSimpleName());
}
return new BundledHlsMediaChunkExtractor(
newExtractorInstance, masterPlaylistFormat, timestampAdjuster);

View file

@ -134,10 +134,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
boolean shouldSpliceIn;
ImmutableMap<SampleQueue, Integer> sampleQueueDiscardFromIndices = ImmutableMap.of();
if (previousChunk != null) {
boolean isFollowingChunk =
playlistUrl.equals(previousChunk.playlistUrl) && previousChunk.loadCompleted;
id3Decoder = previousChunk.id3Decoder;
scratchId3Data = previousChunk.scratchId3Data;
boolean canContinueWithoutSplice =
(playlistUrl.equals(previousChunk.playlistUrl) && previousChunk.loadCompleted)
isFollowingChunk
|| (mediaPlaylist.hasIndependentSegments
&& segmentStartTimeInPeriodUs >= previousChunk.endTimeUs);
shouldSpliceIn = !canContinueWithoutSplice;
@ -145,8 +147,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
sampleQueueDiscardFromIndices = previousChunk.sampleQueueDiscardFromIndices;
}
previousExtractor =
previousChunk.discontinuitySequenceNumber == discontinuitySequenceNumber
&& !shouldSpliceIn
isFollowingChunk
&& previousChunk.discontinuitySequenceNumber == discontinuitySequenceNumber
? previousChunk.extractor
: null;
} else {
@ -334,9 +336,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public void load() throws IOException {
// output == null means init() hasn't been called.
Assertions.checkNotNull(output);
if (extractor == null && previousExtractor != null) {
extractor = previousExtractor.reuseOrRecreate();
initDataLoadRequired = extractor != previousExtractor;
if (extractor == null && previousExtractor != null && previousExtractor.isReusable()) {
extractor = previousExtractor;
initDataLoadRequired = false;
}
maybeLoadInitData();
if (!loadCanceled) {
@ -426,13 +428,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
extractorInput.resetPeekPosition();
extractor =
extractorFactory.createExtractor(
dataSpec.uri,
trackFormat,
muxedCaptionFormats,
timestampAdjuster,
dataSource.getResponseHeaders(),
extractorInput);
previousExtractor != null
? previousExtractor.recreate()
: extractorFactory.createExtractor(
dataSpec.uri,
trackFormat,
muxedCaptionFormats,
timestampAdjuster,
dataSource.getResponseHeaders(),
extractorInput);
if (extractor.isPackedAudioExtractor()) {
output.setSampleOffsetUs(
id3Timestamp != C.TIME_UNSET

View file

@ -51,9 +51,12 @@ public interface HlsMediaChunkExtractor {
/** Returns whether this is a packed audio extractor, as defined in RFC 8216, Section 3.4. */
boolean isPackedAudioExtractor();
/** Returns whether this instance can be used for extracting multiple continuous segments. */
boolean isReusable();
/**
* If this instance can be used for extracting multiple continuous segments, returns itself.
* Otherwise, returns a new instance for extracting the same type of media.
* Returns a new instance for extracting the same type of media as this one. Can only be called on
* instances that are not {@link #isReusable() reusable}.
*/
HlsMediaChunkExtractor reuseOrRecreate();
HlsMediaChunkExtractor recreate();
}