use of com.google.android.exoplayer2.extractor.ExtractorOutput in project ExoPlayer by google.
the class HlsMediaChunk method buildPackedAudioExtractor.
private Extractor buildPackedAudioExtractor(long startTimeUs) {
Extractor extractor;
if (lastPathSegment.endsWith(AAC_FILE_EXTENSION)) {
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(0, startTimeUs);
} else {
throw new IllegalArgumentException("Unkown extension for audio file: " + lastPathSegment);
}
extractor.init(extractorOutput);
return extractor;
}
use of com.google.android.exoplayer2.extractor.ExtractorOutput in project ExoPlayer by google.
the class Mp4Extractor method processMoovAtom.
/**
* Updates the stored track metadata to reflect the contents of the specified moov atom.
*/
private void processMoovAtom(ContainerAtom moov) throws ParserException {
int firstVideoTrackIndex = C.INDEX_UNSET;
long durationUs = C.TIME_UNSET;
List<Mp4Track> tracks = new ArrayList<>();
// Process metadata.
@Nullable Metadata udtaMetaMetadata = null;
@Nullable Metadata smtaMetadata = null;
boolean isQuickTime = fileType == FILE_TYPE_QUICKTIME;
GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
@Nullable Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
if (udta != null) {
Pair<@NullableType Metadata, @NullableType Metadata> udtaMetadata = AtomParsers.parseUdta(udta);
udtaMetaMetadata = udtaMetadata.first;
smtaMetadata = udtaMetadata.second;
if (udtaMetaMetadata != null) {
gaplessInfoHolder.setFromMetadata(udtaMetaMetadata);
}
}
@Nullable Metadata mdtaMetadata = null;
@Nullable Atom.ContainerAtom meta = moov.getContainerAtomOfType(Atom.TYPE_meta);
if (meta != null) {
mdtaMetadata = AtomParsers.parseMdtaFromMeta(meta);
}
boolean ignoreEditLists = (flags & FLAG_WORKAROUND_IGNORE_EDIT_LISTS) != 0;
List<TrackSampleTable> trackSampleTables = parseTraks(moov, gaplessInfoHolder, /* duration= */
C.TIME_UNSET, /* drmInitData= */
null, ignoreEditLists, isQuickTime, /* modifyTrackFunction= */
track -> track);
ExtractorOutput extractorOutput = checkNotNull(this.extractorOutput);
int trackCount = trackSampleTables.size();
for (int i = 0; i < trackCount; i++) {
TrackSampleTable trackSampleTable = trackSampleTables.get(i);
if (trackSampleTable.sampleCount == 0) {
continue;
}
Track track = trackSampleTable.track;
long trackDurationUs = track.durationUs != C.TIME_UNSET ? track.durationUs : trackSampleTable.durationUs;
durationUs = max(durationUs, trackDurationUs);
Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, extractorOutput.track(i, track.type));
int maxInputSize;
if (MimeTypes.AUDIO_TRUEHD.equals(track.format.sampleMimeType)) {
// TrueHD groups samples per chunks of TRUEHD_RECHUNK_SAMPLE_COUNT samples.
maxInputSize = trackSampleTable.maximumSize * Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT;
} else {
// Each sample has up to three bytes of overhead for the start code that replaces its
// length. Allow ten source samples per output sample, like the platform extractor.
maxInputSize = trackSampleTable.maximumSize + 3 * 10;
}
Format.Builder formatBuilder = track.format.buildUpon();
formatBuilder.setMaxInputSize(maxInputSize);
if (track.type == C.TRACK_TYPE_VIDEO && trackDurationUs > 0 && trackSampleTable.sampleCount > 1) {
float frameRate = trackSampleTable.sampleCount / (trackDurationUs / 1000000f);
formatBuilder.setFrameRate(frameRate);
}
MetadataUtil.setFormatGaplessInfo(track.type, gaplessInfoHolder, formatBuilder);
MetadataUtil.setFormatMetadata(track.type, udtaMetaMetadata, mdtaMetadata, formatBuilder, smtaMetadata, slowMotionMetadataEntries.isEmpty() ? null : new Metadata(slowMotionMetadataEntries));
mp4Track.trackOutput.format(formatBuilder.build());
if (track.type == C.TRACK_TYPE_VIDEO && firstVideoTrackIndex == C.INDEX_UNSET) {
firstVideoTrackIndex = tracks.size();
}
tracks.add(mp4Track);
}
this.firstVideoTrackIndex = firstVideoTrackIndex;
this.durationUs = durationUs;
this.tracks = tracks.toArray(new Mp4Track[0]);
accumulatedSampleSizes = calculateAccumulatedSampleSizes(this.tracks);
extractorOutput.endTracks();
extractorOutput.seekMap(this);
}
use of com.google.android.exoplayer2.extractor.ExtractorOutput in project ExoPlayer by google.
the class DvbSubtitleReader method createTracks.
@Override
public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) {
for (int i = 0; i < outputs.length; i++) {
DvbSubtitleInfo subtitleInfo = subtitleInfos.get(i);
idGenerator.generateNewId();
TrackOutput output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT);
output.format(new Format.Builder().setId(idGenerator.getFormatId()).setSampleMimeType(MimeTypes.APPLICATION_DVBSUBS).setInitializationData(Collections.singletonList(subtitleInfo.initializationData)).setLanguage(subtitleInfo.language).build());
outputs[i] = output;
}
}
use of com.google.android.exoplayer2.extractor.ExtractorOutput in project ExoPlayer by google.
the class SeiReader method createTracks.
public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) {
for (int i = 0; i < outputs.length; i++) {
idGenerator.generateNewId();
TrackOutput output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT);
Format channelFormat = closedCaptionFormats.get(i);
@Nullable String channelMimeType = channelFormat.sampleMimeType;
Assertions.checkArgument(MimeTypes.APPLICATION_CEA608.equals(channelMimeType) || MimeTypes.APPLICATION_CEA708.equals(channelMimeType), "Invalid closed caption mime type provided: " + channelMimeType);
String formatId = channelFormat.id != null ? channelFormat.id : idGenerator.getFormatId();
output.format(new Format.Builder().setId(formatId).setSampleMimeType(channelMimeType).setSelectionFlags(channelFormat.selectionFlags).setLanguage(channelFormat.language).setAccessibilityChannel(channelFormat.accessibilityChannel).setInitializationData(channelFormat.initializationData).build());
outputs[i] = output;
}
}
use of com.google.android.exoplayer2.extractor.ExtractorOutput in project ExoPlayer by google.
the class StreamReader method readPayload.
@RequiresNonNull({ "trackOutput", "oggSeeker", "extractorOutput" })
private int readPayload(ExtractorInput input, PositionHolder seekPosition) throws IOException {
long position = oggSeeker.read(input);
if (position >= 0) {
seekPosition.position = position;
return Extractor.RESULT_SEEK;
} else if (position < -1) {
onSeekEnd(-(position + 2));
}
if (!seekMapSet) {
SeekMap seekMap = checkStateNotNull(oggSeeker.createSeekMap());
extractorOutput.seekMap(seekMap);
seekMapSet = true;
}
if (lengthOfReadPacket > 0 || oggPacket.populate(input)) {
lengthOfReadPacket = 0;
ParsableByteArray payload = oggPacket.getPayload();
long granulesInPacket = preparePayload(payload);
if (granulesInPacket >= 0 && currentGranule + granulesInPacket >= targetGranule) {
// calculate time and send payload data to codec
long timeUs = convertGranuleToTime(currentGranule);
trackOutput.sampleData(payload, payload.limit());
trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, payload.limit(), 0, null);
targetGranule = -1;
}
currentGranule += granulesInPacket;
} else {
state = STATE_END_OF_INPUT;
return Extractor.RESULT_END_OF_INPUT;
}
return Extractor.RESULT_CONTINUE;
}
Aggregations