Optimize extractors sniffing order
Issue: #6410 PiperOrigin-RevId: 305436352
This commit is contained in:
parent
4e2a0f6032
commit
703fb777c4
@ -109,6 +109,9 @@
|
|||||||
* Cast extension: Implement playlist API and deprecate the old queue
|
* Cast extension: Implement playlist API and deprecate the old queue
|
||||||
manipulation API.
|
manipulation API.
|
||||||
* Demo app: Retain previous position in list of samples.
|
* Demo app: Retain previous position in list of samples.
|
||||||
|
* Change the order of extractors for sniffing to reduce start-up latency in
|
||||||
|
`DefaultExtractorsFactory` and `DefaultHlsExtractorsFactory`
|
||||||
|
([#6410](https://github.com/google/ExoPlayer/issues/6410)).
|
||||||
|
|
||||||
### 2.11.4 (2020-04-08)
|
### 2.11.4 (2020-04-08)
|
||||||
|
|
||||||
|
@ -241,44 +241,46 @@ public final class DefaultExtractorsFactory implements ExtractorsFactory {
|
|||||||
@Override
|
@Override
|
||||||
public synchronized Extractor[] createExtractors() {
|
public synchronized Extractor[] createExtractors() {
|
||||||
Extractor[] extractors = new Extractor[14];
|
Extractor[] extractors = new Extractor[14];
|
||||||
extractors[0] = new MatroskaExtractor(matroskaFlags);
|
// Extractors order is optimized according to
|
||||||
extractors[1] = new FragmentedMp4Extractor(fragmentedMp4Flags);
|
// https://docs.google.com/document/d/1w2mKaWMxfz2Ei8-LdxqbPs1VLe_oudB-eryXXw9OvQQ.
|
||||||
extractors[2] = new Mp4Extractor(mp4Flags);
|
extractors[0] = new FlvExtractor();
|
||||||
extractors[3] =
|
|
||||||
new Mp3Extractor(
|
|
||||||
mp3Flags
|
|
||||||
| (constantBitrateSeekingEnabled
|
|
||||||
? Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
|
|
||||||
: 0));
|
|
||||||
extractors[4] =
|
|
||||||
new AdtsExtractor(
|
|
||||||
adtsFlags
|
|
||||||
| (constantBitrateSeekingEnabled
|
|
||||||
? AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
|
|
||||||
: 0));
|
|
||||||
extractors[5] = new Ac3Extractor();
|
|
||||||
extractors[6] = new TsExtractor(tsMode, tsFlags);
|
|
||||||
extractors[7] = new FlvExtractor();
|
|
||||||
extractors[8] = new OggExtractor();
|
|
||||||
extractors[9] = new PsExtractor();
|
|
||||||
extractors[10] = new WavExtractor();
|
|
||||||
extractors[11] =
|
|
||||||
new AmrExtractor(
|
|
||||||
amrFlags
|
|
||||||
| (constantBitrateSeekingEnabled
|
|
||||||
? AmrExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
|
|
||||||
: 0));
|
|
||||||
extractors[12] = new Ac4Extractor();
|
|
||||||
if (FLAC_EXTENSION_EXTRACTOR_CONSTRUCTOR != null) {
|
if (FLAC_EXTENSION_EXTRACTOR_CONSTRUCTOR != null) {
|
||||||
try {
|
try {
|
||||||
extractors[13] = FLAC_EXTENSION_EXTRACTOR_CONSTRUCTOR.newInstance();
|
extractors[1] = FLAC_EXTENSION_EXTRACTOR_CONSTRUCTOR.newInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Should never happen.
|
// Should never happen.
|
||||||
throw new IllegalStateException("Unexpected error creating FLAC extractor", e);
|
throw new IllegalStateException("Unexpected error creating FLAC extractor", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
extractors[13] = new FlacExtractor(coreFlacFlags);
|
extractors[1] = new FlacExtractor(coreFlacFlags);
|
||||||
}
|
}
|
||||||
|
extractors[2] = new WavExtractor();
|
||||||
|
extractors[3] = new FragmentedMp4Extractor(fragmentedMp4Flags);
|
||||||
|
extractors[4] = new Mp4Extractor(mp4Flags);
|
||||||
|
extractors[5] =
|
||||||
|
new AmrExtractor(
|
||||||
|
amrFlags
|
||||||
|
| (constantBitrateSeekingEnabled
|
||||||
|
? AmrExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
|
||||||
|
: 0));
|
||||||
|
extractors[6] = new PsExtractor();
|
||||||
|
extractors[7] = new OggExtractor();
|
||||||
|
extractors[8] = new TsExtractor(tsMode, tsFlags);
|
||||||
|
extractors[9] = new MatroskaExtractor(matroskaFlags);
|
||||||
|
extractors[10] =
|
||||||
|
new AdtsExtractor(
|
||||||
|
adtsFlags
|
||||||
|
| (constantBitrateSeekingEnabled
|
||||||
|
? AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
|
||||||
|
: 0));
|
||||||
|
extractors[11] = new Ac3Extractor();
|
||||||
|
extractors[12] = new Ac4Extractor();
|
||||||
|
extractors[13] =
|
||||||
|
new Mp3Extractor(
|
||||||
|
mp3Flags
|
||||||
|
| (constantBitrateSeekingEnabled
|
||||||
|
? Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
|
||||||
|
: 0));
|
||||||
return extractors;
|
return extractors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
|
|||||||
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
|
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
|
||||||
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
|
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
|
||||||
import com.google.android.exoplayer2.metadata.Metadata;
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
@ -51,6 +52,8 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
|
|||||||
public static final String M4_FILE_EXTENSION_PREFIX = ".m4";
|
public static final String M4_FILE_EXTENSION_PREFIX = ".m4";
|
||||||
public static final String MP4_FILE_EXTENSION_PREFIX = ".mp4";
|
public static final String MP4_FILE_EXTENSION_PREFIX = ".mp4";
|
||||||
public static final String CMF_FILE_EXTENSION_PREFIX = ".cmf";
|
public static final String CMF_FILE_EXTENSION_PREFIX = ".cmf";
|
||||||
|
public static final String TS_FILE_EXTENSION = ".ts";
|
||||||
|
public static final String TS_FILE_EXTENSION_PREFIX = ".ts";
|
||||||
public static final String VTT_FILE_EXTENSION = ".vtt";
|
public static final String VTT_FILE_EXTENSION = ".vtt";
|
||||||
public static final String WEBVTT_FILE_EXTENSION = ".webvtt";
|
public static final String WEBVTT_FILE_EXTENSION = ".webvtt";
|
||||||
|
|
||||||
@ -94,7 +97,7 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
if (previousExtractor != null) {
|
if (previousExtractor != null) {
|
||||||
// A extractor has already been successfully used. Return one of the same type.
|
// An extractor has already been successfully used. Return one of the same type.
|
||||||
if (isReusable(previousExtractor)) {
|
if (isReusable(previousExtractor)) {
|
||||||
return buildResult(previousExtractor);
|
return buildResult(previousExtractor);
|
||||||
} else {
|
} else {
|
||||||
@ -108,15 +111,29 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try selecting the extractor by the file extension.
|
// Try selecting the extractor by the file extension.
|
||||||
|
@Nullable
|
||||||
Extractor extractorByFileExtension =
|
Extractor extractorByFileExtension =
|
||||||
createExtractorByFileExtension(uri, format, muxedCaptionFormats, timestampAdjuster);
|
createExtractorByFileExtension(uri, format, muxedCaptionFormats, timestampAdjuster);
|
||||||
extractorInput.resetPeekPosition();
|
extractorInput.resetPeekPosition();
|
||||||
if (sniffQuietly(extractorByFileExtension, extractorInput)) {
|
if (extractorByFileExtension != null
|
||||||
|
&& sniffQuietly(extractorByFileExtension, extractorInput)) {
|
||||||
return buildResult(extractorByFileExtension);
|
return buildResult(extractorByFileExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to manually sniff each known type, without retrying the one selected by file
|
// We need to manually sniff each known type, without retrying the one selected by file
|
||||||
// extension.
|
// extension. Extractors order is optimized according to
|
||||||
|
// https://docs.google.com/document/d/1w2mKaWMxfz2Ei8-LdxqbPs1VLe_oudB-eryXXw9OvQQ.
|
||||||
|
|
||||||
|
// Extractor to be used if the type is not recognized.
|
||||||
|
@Nullable Extractor fallBackExtractor = extractorByFileExtension;
|
||||||
|
|
||||||
|
if (!(extractorByFileExtension instanceof FragmentedMp4Extractor)) {
|
||||||
|
FragmentedMp4Extractor fragmentedMp4Extractor =
|
||||||
|
createFragmentedMp4Extractor(timestampAdjuster, format, muxedCaptionFormats);
|
||||||
|
if (sniffQuietly(fragmentedMp4Extractor, extractorInput)) {
|
||||||
|
return buildResult(fragmentedMp4Extractor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(extractorByFileExtension instanceof WebvttExtractor)) {
|
if (!(extractorByFileExtension instanceof WebvttExtractor)) {
|
||||||
WebvttExtractor webvttExtractor = new WebvttExtractor(format.language, timestampAdjuster);
|
WebvttExtractor webvttExtractor = new WebvttExtractor(format.language, timestampAdjuster);
|
||||||
@ -125,6 +142,22 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(extractorByFileExtension instanceof TsExtractor)) {
|
||||||
|
TsExtractor tsExtractor =
|
||||||
|
createTsExtractor(
|
||||||
|
payloadReaderFactoryFlags,
|
||||||
|
exposeCea608WhenMissingDeclarations,
|
||||||
|
format,
|
||||||
|
muxedCaptionFormats,
|
||||||
|
timestampAdjuster);
|
||||||
|
if (sniffQuietly(tsExtractor, extractorInput)) {
|
||||||
|
return buildResult(tsExtractor);
|
||||||
|
}
|
||||||
|
if (fallBackExtractor == null) {
|
||||||
|
fallBackExtractor = tsExtractor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(extractorByFileExtension instanceof AdtsExtractor)) {
|
if (!(extractorByFileExtension instanceof AdtsExtractor)) {
|
||||||
AdtsExtractor adtsExtractor = new AdtsExtractor();
|
AdtsExtractor adtsExtractor = new AdtsExtractor();
|
||||||
if (sniffQuietly(adtsExtractor, extractorInput)) {
|
if (sniffQuietly(adtsExtractor, extractorInput)) {
|
||||||
@ -154,31 +187,10 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(extractorByFileExtension instanceof FragmentedMp4Extractor)) {
|
return buildResult(Assertions.checkNotNull(fallBackExtractor));
|
||||||
FragmentedMp4Extractor fragmentedMp4Extractor =
|
|
||||||
createFragmentedMp4Extractor(timestampAdjuster, format, muxedCaptionFormats);
|
|
||||||
if (sniffQuietly(fragmentedMp4Extractor, extractorInput)) {
|
|
||||||
return buildResult(fragmentedMp4Extractor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(extractorByFileExtension instanceof TsExtractor)) {
|
|
||||||
TsExtractor tsExtractor =
|
|
||||||
createTsExtractor(
|
|
||||||
payloadReaderFactoryFlags,
|
|
||||||
exposeCea608WhenMissingDeclarations,
|
|
||||||
format,
|
|
||||||
muxedCaptionFormats,
|
|
||||||
timestampAdjuster);
|
|
||||||
if (sniffQuietly(tsExtractor, extractorInput)) {
|
|
||||||
return buildResult(tsExtractor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fall back on the extractor created by file extension.
|
|
||||||
return buildResult(extractorByFileExtension);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Extractor createExtractorByFileExtension(
|
private Extractor createExtractorByFileExtension(
|
||||||
Uri uri,
|
Uri uri,
|
||||||
Format format,
|
Format format,
|
||||||
@ -206,14 +218,16 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
|
|||||||
|| lastPathSegment.startsWith(MP4_FILE_EXTENSION_PREFIX, lastPathSegment.length() - 5)
|
|| lastPathSegment.startsWith(MP4_FILE_EXTENSION_PREFIX, lastPathSegment.length() - 5)
|
||||||
|| lastPathSegment.startsWith(CMF_FILE_EXTENSION_PREFIX, lastPathSegment.length() - 5)) {
|
|| lastPathSegment.startsWith(CMF_FILE_EXTENSION_PREFIX, lastPathSegment.length() - 5)) {
|
||||||
return createFragmentedMp4Extractor(timestampAdjuster, format, muxedCaptionFormats);
|
return createFragmentedMp4Extractor(timestampAdjuster, format, muxedCaptionFormats);
|
||||||
} else {
|
} else if (lastPathSegment.endsWith(TS_FILE_EXTENSION)
|
||||||
// For any other file extension, we assume TS format.
|
|| lastPathSegment.startsWith(TS_FILE_EXTENSION_PREFIX, lastPathSegment.length() - 4)) {
|
||||||
return createTsExtractor(
|
return createTsExtractor(
|
||||||
payloadReaderFactoryFlags,
|
payloadReaderFactoryFlags,
|
||||||
exposeCea608WhenMissingDeclarations,
|
exposeCea608WhenMissingDeclarations,
|
||||||
format,
|
format,
|
||||||
muxedCaptionFormats,
|
muxedCaptionFormats,
|
||||||
timestampAdjuster);
|
timestampAdjuster);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user