Commit a8bf7e21 by aquilescanta Committed by Andrew Lewis

Fix init data loading for non-reused extractors

PiperOrigin-RevId: 317322247
parent 457b2155
...@@ -27,6 +27,7 @@ import com.google.android.exoplayer2.extractor.ts.Ac3Extractor; ...@@ -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.Ac4Extractor;
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor; import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
import com.google.android.exoplayer2.extractor.ts.TsExtractor; import com.google.android.exoplayer2.extractor.ts.TsExtractor;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.TimestampAdjuster; import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.io.IOException; import java.io.IOException;
...@@ -75,11 +76,13 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract ...@@ -75,11 +76,13 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
} }
@Override @Override
public HlsMediaChunkExtractor reuseOrRecreate() { public boolean isReusable() {
if (extractor instanceof TsExtractor || extractor instanceof FragmentedMp4Extractor) { return extractor instanceof TsExtractor || extractor instanceof FragmentedMp4Extractor;
// We can reuse this instance. }
return this;
} @Override
public HlsMediaChunkExtractor recreate() {
Assertions.checkState(!isReusable());
Extractor newExtractorInstance; Extractor newExtractorInstance;
if (extractor instanceof WebvttExtractor) { if (extractor instanceof WebvttExtractor) {
newExtractorInstance = new WebvttExtractor(masterPlaylistFormat.language, timestampAdjuster); newExtractorInstance = new WebvttExtractor(masterPlaylistFormat.language, timestampAdjuster);
...@@ -93,7 +96,7 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract ...@@ -93,7 +96,7 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
newExtractorInstance = new Mp3Extractor(); newExtractorInstance = new Mp3Extractor();
} else { } else {
throw new IllegalStateException( throw new IllegalStateException(
"Unexpected previousExtractor type: " + extractor.getClass().getSimpleName()); "Unexpected extractor type for recreation: " + extractor.getClass().getSimpleName());
} }
return new BundledHlsMediaChunkExtractor( return new BundledHlsMediaChunkExtractor(
newExtractorInstance, masterPlaylistFormat, timestampAdjuster); newExtractorInstance, masterPlaylistFormat, timestampAdjuster);
......
...@@ -134,10 +134,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -134,10 +134,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
boolean shouldSpliceIn; boolean shouldSpliceIn;
ImmutableMap<SampleQueue, Integer> sampleQueueDiscardFromIndices = ImmutableMap.of(); ImmutableMap<SampleQueue, Integer> sampleQueueDiscardFromIndices = ImmutableMap.of();
if (previousChunk != null) { if (previousChunk != null) {
boolean isFollowingChunk =
playlistUrl.equals(previousChunk.playlistUrl) && previousChunk.loadCompleted;
id3Decoder = previousChunk.id3Decoder; id3Decoder = previousChunk.id3Decoder;
scratchId3Data = previousChunk.scratchId3Data; scratchId3Data = previousChunk.scratchId3Data;
boolean canContinueWithoutSplice = boolean canContinueWithoutSplice =
(playlistUrl.equals(previousChunk.playlistUrl) && previousChunk.loadCompleted) isFollowingChunk
|| (mediaPlaylist.hasIndependentSegments || (mediaPlaylist.hasIndependentSegments
&& segmentStartTimeInPeriodUs >= previousChunk.endTimeUs); && segmentStartTimeInPeriodUs >= previousChunk.endTimeUs);
shouldSpliceIn = !canContinueWithoutSplice; shouldSpliceIn = !canContinueWithoutSplice;
...@@ -145,8 +147,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -145,8 +147,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
sampleQueueDiscardFromIndices = previousChunk.sampleQueueDiscardFromIndices; sampleQueueDiscardFromIndices = previousChunk.sampleQueueDiscardFromIndices;
} }
previousExtractor = previousExtractor =
previousChunk.discontinuitySequenceNumber == discontinuitySequenceNumber isFollowingChunk
&& !shouldSpliceIn && previousChunk.discontinuitySequenceNumber == discontinuitySequenceNumber
? previousChunk.extractor ? previousChunk.extractor
: null; : null;
} else { } else {
...@@ -334,9 +336,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -334,9 +336,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public void load() throws IOException { public void load() throws IOException {
// output == null means init() hasn't been called. // output == null means init() hasn't been called.
Assertions.checkNotNull(output); Assertions.checkNotNull(output);
if (extractor == null && previousExtractor != null) { if (extractor == null && previousExtractor != null && previousExtractor.isReusable()) {
extractor = previousExtractor.reuseOrRecreate(); extractor = previousExtractor;
initDataLoadRequired = extractor != previousExtractor; initDataLoadRequired = false;
} }
maybeLoadInitData(); maybeLoadInitData();
if (!loadCanceled) { if (!loadCanceled) {
...@@ -426,13 +428,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -426,13 +428,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
extractorInput.resetPeekPosition(); extractorInput.resetPeekPosition();
extractor = extractor =
extractorFactory.createExtractor( previousExtractor != null
dataSpec.uri, ? previousExtractor.recreate()
trackFormat, : extractorFactory.createExtractor(
muxedCaptionFormats, dataSpec.uri,
timestampAdjuster, trackFormat,
dataSource.getResponseHeaders(), muxedCaptionFormats,
extractorInput); timestampAdjuster,
dataSource.getResponseHeaders(),
extractorInput);
if (extractor.isPackedAudioExtractor()) { if (extractor.isPackedAudioExtractor()) {
output.setSampleOffsetUs( output.setSampleOffsetUs(
id3Timestamp != C.TIME_UNSET id3Timestamp != C.TIME_UNSET
......
...@@ -51,9 +51,12 @@ public interface HlsMediaChunkExtractor { ...@@ -51,9 +51,12 @@ public interface HlsMediaChunkExtractor {
/** Returns whether this is a packed audio extractor, as defined in RFC 8216, Section 3.4. */ /** Returns whether this is a packed audio extractor, as defined in RFC 8216, Section 3.4. */
boolean isPackedAudioExtractor(); 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. * Returns a new instance for extracting the same type of media as this one. Can only be called on
* Otherwise, returns a new instance for extracting the same type of media. * instances that are not {@link #isReusable() reusable}.
*/ */
HlsMediaChunkExtractor reuseOrRecreate(); HlsMediaChunkExtractor recreate();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment