Move HLS extractor construction to HlsMediaChunk
This allows ID3 PRIV timestamp extraction and Extractor Sniffing. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=140209568
This commit is contained in:
parent
2e3ffe1e94
commit
c3c176d93c
@ -17,17 +17,9 @@ package com.google.android.exoplayer2.source.hls;
|
|||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.extractor.Extractor;
|
|
||||||
import com.google.android.exoplayer2.extractor.TimestampAdjuster;
|
import com.google.android.exoplayer2.extractor.TimestampAdjuster;
|
||||||
import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
|
|
||||||
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
|
||||||
import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
|
|
||||||
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
|
|
||||||
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
|
|
||||||
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
|
|
||||||
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
import com.google.android.exoplayer2.source.chunk.Chunk;
|
import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||||
@ -41,7 +33,6 @@ import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
|
||||||
import com.google.android.exoplayer2.util.UriUtil;
|
import com.google.android.exoplayer2.util.UriUtil;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -89,14 +80,6 @@ import java.util.Locale;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String AAC_FILE_EXTENSION = ".aac";
|
|
||||||
private static final String AC3_FILE_EXTENSION = ".ac3";
|
|
||||||
private static final String EC3_FILE_EXTENSION = ".ec3";
|
|
||||||
private static final String MP3_FILE_EXTENSION = ".mp3";
|
|
||||||
private static final String MP4_FILE_EXTENSION = ".mp4";
|
|
||||||
private static final String VTT_FILE_EXTENSION = ".vtt";
|
|
||||||
private static final String WEBVTT_FILE_EXTENSION = ".webvtt";
|
|
||||||
|
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final TimestampAdjusterProvider timestampAdjusterProvider;
|
private final TimestampAdjusterProvider timestampAdjusterProvider;
|
||||||
private final HlsUrl[] variants;
|
private final HlsUrl[] variants;
|
||||||
@ -281,68 +264,10 @@ import java.util.Locale;
|
|||||||
if (previous != null && !switchingVariant) {
|
if (previous != null && !switchingVariant) {
|
||||||
startTimeUs = previous.getAdjustedEndTimeUs();
|
startTimeUs = previous.getAdjustedEndTimeUs();
|
||||||
}
|
}
|
||||||
Format format = variants[newVariantIndex].format;
|
|
||||||
|
|
||||||
Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
|
Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
|
||||||
|
|
||||||
// Set the extractor that will read the chunk.
|
TimestampAdjuster timestampAdjuster = timestampAdjusterProvider.getAdjuster(
|
||||||
Extractor extractor;
|
|
||||||
boolean needNewExtractor = previous == null
|
|
||||||
|| previous.discontinuitySequenceNumber != segment.discontinuitySequenceNumber
|
|
||||||
|| format != previous.trackFormat;
|
|
||||||
boolean extractorNeedsInit = true;
|
|
||||||
TimestampAdjuster timestampAdjuster = null;
|
|
||||||
String lastPathSegment = chunkUri.getLastPathSegment();
|
|
||||||
if (lastPathSegment.endsWith(AAC_FILE_EXTENSION)) {
|
|
||||||
// TODO: Inject a timestamp adjuster and use it along with ID3 PRIV tag values with owner
|
|
||||||
// identifier com.apple.streaming.transportStreamTimestamp. This may also apply to the MP3
|
|
||||||
// case below.
|
|
||||||
extractor = new AdtsExtractor(startTimeUs);
|
|
||||||
} else if (lastPathSegment.endsWith(AC3_FILE_EXTENSION)
|
|
||||||
|| lastPathSegment.endsWith(EC3_FILE_EXTENSION)) {
|
|
||||||
extractor = new Ac3Extractor(startTimeUs);
|
|
||||||
} else if (lastPathSegment.endsWith(MP3_FILE_EXTENSION)) {
|
|
||||||
extractor = new Mp3Extractor(startTimeUs);
|
|
||||||
} else if (lastPathSegment.endsWith(WEBVTT_FILE_EXTENSION)
|
|
||||||
|| lastPathSegment.endsWith(VTT_FILE_EXTENSION)) {
|
|
||||||
timestampAdjuster = timestampAdjusterProvider.getAdjuster(segment.discontinuitySequenceNumber,
|
|
||||||
startTimeUs);
|
|
||||||
extractor = new WebvttExtractor(format.language, timestampAdjuster);
|
|
||||||
} else if (lastPathSegment.endsWith(MP4_FILE_EXTENSION)) {
|
|
||||||
if (needNewExtractor) {
|
|
||||||
timestampAdjuster = timestampAdjusterProvider.getAdjuster(
|
|
||||||
segment.discontinuitySequenceNumber, startTimeUs);
|
segment.discontinuitySequenceNumber, startTimeUs);
|
||||||
extractor = new FragmentedMp4Extractor(0, timestampAdjuster);
|
|
||||||
} else {
|
|
||||||
extractorNeedsInit = false;
|
|
||||||
extractor = previous.extractor;
|
|
||||||
}
|
|
||||||
} else if (needNewExtractor) {
|
|
||||||
// MPEG-2 TS segments, but we need a new extractor.
|
|
||||||
timestampAdjuster = timestampAdjusterProvider.getAdjuster(
|
|
||||||
segment.discontinuitySequenceNumber, startTimeUs);
|
|
||||||
// This flag ensures the change of pid between streams does not affect the sample queues.
|
|
||||||
@DefaultTsPayloadReaderFactory.Flags
|
|
||||||
int esReaderFactoryFlags = 0;
|
|
||||||
String codecs = format.codecs;
|
|
||||||
if (!TextUtils.isEmpty(codecs)) {
|
|
||||||
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really
|
|
||||||
// exist. If we know from the codec attribute that they don't exist, then we can
|
|
||||||
// explicitly ignore them even if they're declared.
|
|
||||||
if (!MimeTypes.AUDIO_AAC.equals(MimeTypes.getAudioMediaMimeType(codecs))) {
|
|
||||||
esReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_IGNORE_AAC_STREAM;
|
|
||||||
}
|
|
||||||
if (!MimeTypes.VIDEO_H264.equals(MimeTypes.getVideoMediaMimeType(codecs))) {
|
|
||||||
esReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extractor = new TsExtractor(timestampAdjuster,
|
|
||||||
new DefaultTsPayloadReaderFactory(esReaderFactoryFlags), true);
|
|
||||||
} else {
|
|
||||||
// MPEG-2 TS segments, and we need to continue using the same extractor.
|
|
||||||
extractor = previous.extractor;
|
|
||||||
extractorNeedsInit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSpec initDataSpec = null;
|
DataSpec initDataSpec = null;
|
||||||
Segment initSegment = mediaPlaylist.initializationSegment;
|
Segment initSegment = mediaPlaylist.initializationSegment;
|
||||||
@ -356,9 +281,9 @@ import java.util.Locale;
|
|||||||
DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength,
|
DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength,
|
||||||
null);
|
null);
|
||||||
out.chunk = new HlsMediaChunk(dataSource, dataSpec, initDataSpec, variants[newVariantIndex],
|
out.chunk = new HlsMediaChunk(dataSource, dataSpec, initDataSpec, variants[newVariantIndex],
|
||||||
trackSelection.getSelectionReason(), trackSelection.getSelectionData(),
|
trackSelection.getSelectionReason(), trackSelection.getSelectionData(), segment,
|
||||||
segment, chunkMediaSequence, isTimestampMaster, timestampAdjuster, extractor,
|
chunkMediaSequence, isTimestampMaster, timestampAdjuster, previous, encryptionKey,
|
||||||
extractorNeedsInit, switchingVariant, encryptionKey, encryptionIv);
|
encryptionIv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,15 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.source.hls;
|
package com.google.android.exoplayer2.source.hls;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
||||||
import com.google.android.exoplayer2.extractor.Extractor;
|
import com.google.android.exoplayer2.extractor.Extractor;
|
||||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||||
import com.google.android.exoplayer2.extractor.TimestampAdjuster;
|
import com.google.android.exoplayer2.extractor.TimestampAdjuster;
|
||||||
|
import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
|
||||||
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -35,6 +43,14 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
private static final AtomicInteger UID_SOURCE = new AtomicInteger();
|
private static final AtomicInteger UID_SOURCE = new AtomicInteger();
|
||||||
|
|
||||||
|
private static final String AAC_FILE_EXTENSION = ".aac";
|
||||||
|
private static final String AC3_FILE_EXTENSION = ".ac3";
|
||||||
|
private static final String EC3_FILE_EXTENSION = ".ec3";
|
||||||
|
private static final String MP3_FILE_EXTENSION = ".mp3";
|
||||||
|
private static final String MP4_FILE_EXTENSION = ".mp4";
|
||||||
|
private static final String VTT_FILE_EXTENSION = ".vtt";
|
||||||
|
private static final String WEBVTT_FILE_EXTENSION = ".webvtt";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unique identifier for the chunk.
|
* A unique identifier for the chunk.
|
||||||
*/
|
*/
|
||||||
@ -45,11 +61,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
*/
|
*/
|
||||||
public final int discontinuitySequenceNumber;
|
public final int discontinuitySequenceNumber;
|
||||||
|
|
||||||
/**
|
|
||||||
* The extractor into which this chunk is being consumed.
|
|
||||||
*/
|
|
||||||
public final Extractor extractor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The url of the playlist from which this chunk was obtained.
|
* The url of the playlist from which this chunk was obtained.
|
||||||
*/
|
*/
|
||||||
@ -58,11 +69,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
private final DataSource initDataSource;
|
private final DataSource initDataSource;
|
||||||
private final DataSpec initDataSpec;
|
private final DataSpec initDataSpec;
|
||||||
private final boolean isEncrypted;
|
private final boolean isEncrypted;
|
||||||
private final boolean extractorNeedsInit;
|
|
||||||
private final boolean shouldSpliceIn;
|
|
||||||
private final boolean isMasterTimestampSource;
|
private final boolean isMasterTimestampSource;
|
||||||
private final TimestampAdjuster timestampAdjuster;
|
private final TimestampAdjuster timestampAdjuster;
|
||||||
|
private final HlsMediaChunk previousChunk;
|
||||||
|
|
||||||
|
private Extractor extractor;
|
||||||
private int initSegmentBytesLoaded;
|
private int initSegmentBytesLoaded;
|
||||||
private int bytesLoaded;
|
private int bytesLoaded;
|
||||||
private boolean initLoadCompleted;
|
private boolean initLoadCompleted;
|
||||||
@ -82,19 +93,14 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
* @param chunkIndex The media sequence number of the chunk.
|
* @param chunkIndex The media sequence number of the chunk.
|
||||||
* @param isMasterTimestampSource True if the chunk can initialize the timestamp adjuster.
|
* @param isMasterTimestampSource True if the chunk can initialize the timestamp adjuster.
|
||||||
* @param timestampAdjuster Adjuster corresponding to the provided discontinuity sequence number.
|
* @param timestampAdjuster Adjuster corresponding to the provided discontinuity sequence number.
|
||||||
* @param extractor The extractor to decode samples from the data.
|
* @param previousChunk The {@link HlsMediaChunk} that preceded this one. May be null.
|
||||||
* @param extractorNeedsInit Whether the extractor needs initializing with the target
|
|
||||||
* {@link HlsSampleStreamWrapper}.
|
|
||||||
* @param shouldSpliceIn Whether the samples parsed from this chunk should be spliced into any
|
|
||||||
* samples already queued to the {@link HlsSampleStreamWrapper}.
|
|
||||||
* @param encryptionKey For AES encryption chunks, the encryption key.
|
* @param encryptionKey For AES encryption chunks, the encryption key.
|
||||||
* @param encryptionIv For AES encryption chunks, the encryption initialization vector.
|
* @param encryptionIv For AES encryption chunks, the encryption initialization vector.
|
||||||
*/
|
*/
|
||||||
public HlsMediaChunk(DataSource dataSource, DataSpec dataSpec, DataSpec initDataSpec,
|
public HlsMediaChunk(DataSource dataSource, DataSpec dataSpec, DataSpec initDataSpec,
|
||||||
HlsUrl hlsUrl, int trackSelectionReason, Object trackSelectionData, Segment segment,
|
HlsUrl hlsUrl, int trackSelectionReason, Object trackSelectionData, Segment segment,
|
||||||
int chunkIndex, boolean isMasterTimestampSource, TimestampAdjuster timestampAdjuster,
|
int chunkIndex, boolean isMasterTimestampSource, TimestampAdjuster timestampAdjuster,
|
||||||
Extractor extractor, boolean extractorNeedsInit, boolean shouldSpliceIn, byte[] encryptionKey,
|
HlsMediaChunk previousChunk, byte[] encryptionKey, byte[] encryptionIv) {
|
||||||
byte[] encryptionIv) {
|
|
||||||
super(buildDataSource(dataSource, encryptionKey, encryptionIv), dataSpec, hlsUrl.format,
|
super(buildDataSource(dataSource, encryptionKey, encryptionIv), dataSpec, hlsUrl.format,
|
||||||
trackSelectionReason, trackSelectionData, segment.startTimeUs,
|
trackSelectionReason, trackSelectionData, segment.startTimeUs,
|
||||||
segment.startTimeUs + segment.durationUs, chunkIndex);
|
segment.startTimeUs + segment.durationUs, chunkIndex);
|
||||||
@ -102,9 +108,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
this.hlsUrl = hlsUrl;
|
this.hlsUrl = hlsUrl;
|
||||||
this.isMasterTimestampSource = isMasterTimestampSource;
|
this.isMasterTimestampSource = isMasterTimestampSource;
|
||||||
this.timestampAdjuster = timestampAdjuster;
|
this.timestampAdjuster = timestampAdjuster;
|
||||||
this.extractor = extractor;
|
this.previousChunk = previousChunk;
|
||||||
this.extractorNeedsInit = extractorNeedsInit;
|
|
||||||
this.shouldSpliceIn = shouldSpliceIn;
|
|
||||||
// Note: this.dataSource and dataSource may be different.
|
// Note: this.dataSource and dataSource may be different.
|
||||||
this.isEncrypted = this.dataSource instanceof Aes128DataSource;
|
this.isEncrypted = this.dataSource instanceof Aes128DataSource;
|
||||||
initDataSource = dataSource;
|
initDataSource = dataSource;
|
||||||
@ -121,10 +125,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
*/
|
*/
|
||||||
public void init(HlsSampleStreamWrapper output) {
|
public void init(HlsSampleStreamWrapper output) {
|
||||||
extractorOutput = output;
|
extractorOutput = output;
|
||||||
output.init(uid, shouldSpliceIn);
|
output.init(uid, previousChunk != null && previousChunk.hlsUrl != hlsUrl);
|
||||||
if (extractorNeedsInit) {
|
|
||||||
extractor.init(output);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,6 +166,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() throws IOException, InterruptedException {
|
public void load() throws IOException, InterruptedException {
|
||||||
|
if (extractor == null) {
|
||||||
|
extractor = buildExtractor();
|
||||||
|
}
|
||||||
maybeLoadInitData();
|
maybeLoadInitData();
|
||||||
if (!loadCanceled) {
|
if (!loadCanceled) {
|
||||||
loadMedia();
|
loadMedia();
|
||||||
@ -173,8 +177,62 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
// Private methods.
|
// Private methods.
|
||||||
|
|
||||||
|
private Extractor buildExtractor() {
|
||||||
|
// Set the extractor that will read the chunk.
|
||||||
|
Extractor extractor;
|
||||||
|
boolean needNewExtractor = previousChunk == null
|
||||||
|
|| previousChunk.discontinuitySequenceNumber != discontinuitySequenceNumber
|
||||||
|
|| trackFormat != previousChunk.trackFormat;
|
||||||
|
boolean usingNewExtractor = true;
|
||||||
|
String lastPathSegment = dataSpec.uri.getLastPathSegment();
|
||||||
|
if (lastPathSegment.endsWith(AAC_FILE_EXTENSION)) {
|
||||||
|
// TODO: Inject a timestamp adjuster and use it along with ID3 PRIV tag values with owner
|
||||||
|
// identifier com.apple.streaming.transportStreamTimestamp. This may also apply to the MP3
|
||||||
|
// case below.
|
||||||
|
extractor = new AdtsExtractor(startTimeUs);
|
||||||
|
} else if (lastPathSegment.endsWith(AC3_FILE_EXTENSION)
|
||||||
|
|| lastPathSegment.endsWith(EC3_FILE_EXTENSION)) {
|
||||||
|
extractor = new Ac3Extractor(startTimeUs);
|
||||||
|
} else if (lastPathSegment.endsWith(MP3_FILE_EXTENSION)) {
|
||||||
|
extractor = new Mp3Extractor(startTimeUs);
|
||||||
|
} else if (lastPathSegment.endsWith(WEBVTT_FILE_EXTENSION)
|
||||||
|
|| lastPathSegment.endsWith(VTT_FILE_EXTENSION)) {
|
||||||
|
extractor = new WebvttExtractor(trackFormat.language, timestampAdjuster);
|
||||||
|
} else if (!needNewExtractor) {
|
||||||
|
// Only reuse TS and fMP4 extractors.
|
||||||
|
usingNewExtractor = false;
|
||||||
|
extractor = previousChunk.extractor;
|
||||||
|
} else if (lastPathSegment.endsWith(MP4_FILE_EXTENSION)) {
|
||||||
|
extractor = new FragmentedMp4Extractor(0, timestampAdjuster);
|
||||||
|
} else {
|
||||||
|
// MPEG-2 TS segments, but we need a new extractor.
|
||||||
|
// This flag ensures the change of pid between streams does not affect the sample queues.
|
||||||
|
@DefaultTsPayloadReaderFactory.Flags
|
||||||
|
int esReaderFactoryFlags = 0;
|
||||||
|
String codecs = trackFormat.codecs;
|
||||||
|
if (!TextUtils.isEmpty(codecs)) {
|
||||||
|
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really
|
||||||
|
// exist. If we know from the codec attribute that they don't exist, then we can
|
||||||
|
// explicitly ignore them even if they're declared.
|
||||||
|
if (!MimeTypes.AUDIO_AAC.equals(MimeTypes.getAudioMediaMimeType(codecs))) {
|
||||||
|
esReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_IGNORE_AAC_STREAM;
|
||||||
|
}
|
||||||
|
if (!MimeTypes.VIDEO_H264.equals(MimeTypes.getVideoMediaMimeType(codecs))) {
|
||||||
|
esReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extractor = new TsExtractor(timestampAdjuster,
|
||||||
|
new DefaultTsPayloadReaderFactory(esReaderFactoryFlags), true);
|
||||||
|
}
|
||||||
|
if (usingNewExtractor) {
|
||||||
|
extractor.init(extractorOutput);
|
||||||
|
}
|
||||||
|
return extractor;
|
||||||
|
}
|
||||||
|
|
||||||
private void maybeLoadInitData() throws IOException, InterruptedException {
|
private void maybeLoadInitData() throws IOException, InterruptedException {
|
||||||
if (!extractorNeedsInit || initLoadCompleted || initDataSpec == null) {
|
if (previousChunk == null || previousChunk.extractor != extractor || initLoadCompleted
|
||||||
|
|| initDataSpec == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DataSpec initSegmentDataSpec = Util.getRemainderDataSpec(initDataSpec, initSegmentBytesLoaded);
|
DataSpec initSegmentDataSpec = Util.getRemainderDataSpec(initDataSpec, initSegmentBytesLoaded);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user