mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Fix init data loading for non-reused extractors
PiperOrigin-RevId: 317322247
This commit is contained in:
parent
457b215565
commit
a8bf7e217b
3 changed files with 32 additions and 22 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@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
|
||||||
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;
|
||||||
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;
|
||||||
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;
|
||||||
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;
|
||||||
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 {
|
||||||
/** 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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue