@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { int currentFileSize = (int) input.getLength(); // Increase the size of sampleData if necessary. if (sampleSize == sampleData.length) { sampleData = Arrays.copyOf(sampleData, (currentFileSize != C.LENGTH_UNSET ? currentFileSize : sampleData.length) * 3 / 2); } // Consume to the input. int bytesRead = input.read(sampleData, sampleSize, sampleData.length - sampleSize); if (bytesRead != C.RESULT_END_OF_INPUT) { sampleSize += bytesRead; if (currentFileSize == C.LENGTH_UNSET || sampleSize != currentFileSize) { return Extractor.RESULT_CONTINUE; } } // We've reached the end of the input, which corresponds to the end of the current file. processSample(); return Extractor.RESULT_END_OF_INPUT; }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { int bytesRead = input.read(packetBuffer.data, 0, MAX_PACKET_SIZE); if (bytesRead == C.RESULT_END_OF_INPUT) { return RESULT_END_OF_INPUT; } // Feed whatever data we have to the reader, regardless of whether the read finished or not. packetBuffer.setPosition(0); packetBuffer.setLimit(bytesRead); if (!startedPacket) { // Pass data to the reader as though it's contained within a single infinitely long packet. reader.packetStarted(firstSampleTimestampUs, true); startedPacket = true; } // TODO: Make it possible for reader to consume the dataSource directly, so that it becomes // unnecessary to copy the data through packetBuffer. reader.consume(packetBuffer); return RESULT_CONTINUE; }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { int bytesRead = input.read(sampleData.data, 0, MAX_SYNC_FRAME_SIZE); if (bytesRead == C.RESULT_END_OF_INPUT) { return RESULT_END_OF_INPUT; } // Feed whatever data we have to the reader, regardless of whether the read finished or not. sampleData.setPosition(0); sampleData.setLimit(bytesRead); if (!startedPacket) { // Pass data to the reader as though it's contained within a single infinitely long packet. reader.packetStarted(firstSampleTimestampUs, true); startedPacket = true; } // TODO: Make it possible for the reader to consume the dataSource directly, so that it becomes // unnecessary to copy the data through packetBuffer. reader.consume(sampleData); return RESULT_CONTINUE; }
/** * @see Extractor#read(ExtractorInput, PositionHolder) */ final int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { switch (state) { case STATE_READ_HEADERS: return readHeaders(input); case STATE_SKIP_HEADERS: input.skipFully((int) payloadStartPosition); state = STATE_READ_PAYLOAD; return Extractor.RESULT_CONTINUE; case STATE_READ_PAYLOAD: return readPayload(input, seekPosition); default: // Never happens. throw new IllegalStateException(); } }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { while (true) { switch (parserState) { case STATE_READING_ATOM_HEADER: if (!readAtomHeader(input)) { return RESULT_END_OF_INPUT; } break; case STATE_READING_ATOM_PAYLOAD: if (readAtomPayload(input, seekPosition)) { return RESULT_SEEK; } break; case STATE_READING_SAMPLE: return readSample(input, seekPosition); default: throw new IllegalStateException(); } } }
/** * Processes the atom payload. If {@link #atomData} is null and the size is at or above the * threshold {@link #RELOAD_MINIMUM_SEEK_DISTANCE}, {@code true} is returned and the caller should * restart loading at the position in {@code positionHolder}. Otherwise, the atom is read/skipped. */ private boolean readAtomPayload(ExtractorInput input, PositionHolder positionHolder) throws IOException, InterruptedException { long atomPayloadSize = atomSize - atomHeaderBytesRead; long atomEndPosition = input.getPosition() + atomPayloadSize; boolean seekRequired = false; if (atomData != null) { input.readFully(atomData.data, atomHeaderBytesRead, (int) atomPayloadSize); if (atomType == Atom.TYPE_ftyp) { isQuickTime = processFtypAtom(atomData); } else if (!containerAtoms.isEmpty()) { containerAtoms.peek().add(new Atom.LeafAtom(atomType, atomData)); } } else { // We don't need the data. Skip or seek, depending on how large the atom is. if (atomPayloadSize < RELOAD_MINIMUM_SEEK_DISTANCE) { input.skipFully((int) atomPayloadSize); } else { positionHolder.position = input.getPosition() + atomPayloadSize; seekRequired = true; } } processAtomEnded(atomEndPosition); return seekRequired && parserState != STATE_READING_SAMPLE; }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { while (true) { switch (parserState) { case STATE_READING_ATOM_HEADER: if (!readAtomHeader(input)) { return Extractor.RESULT_END_OF_INPUT; } break; case STATE_READING_ATOM_PAYLOAD: readAtomPayload(input); break; case STATE_READING_ENCRYPTION_DATA: readEncryptionData(input); break; default: if (readSample(input)) { return RESULT_CONTINUE; } } } }
/** * Updates the position of the holder to Cues element's position if the extractor configuration * permits use of master seek entry. After building Cues sets the holder's position back to where * it was before. * * @param seekPosition The holder whose position will be updated. * @param currentPosition Current position of the input. * @return Whether the seek position was updated. */ private boolean maybeSeekForCues(PositionHolder seekPosition, long currentPosition) { if (seekForCues) { seekPositionAfterBuildingCues = currentPosition; seekPosition.position = cuesContentPosition; seekForCues = false; return true; } // After parsing Cues, seek back to original position if available. We will not do this unless // we seeked to get to the Cues in the first place. if (sentSeekMap && seekPositionAfterBuildingCues != C.POSITION_UNSET) { seekPosition.position = seekPositionAfterBuildingCues; seekPositionAfterBuildingCues = C.POSITION_UNSET; return true; } return false; }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { while (true) { switch (parserState) { case STATE_READING_FLV_HEADER: if (!readFlvHeader(input)) { return RESULT_END_OF_INPUT; } break; case STATE_SKIPPING_TO_TAG_HEADER: skipToTagHeader(input); break; case STATE_READING_TAG_HEADER: if (!readTagHeader(input)) { return RESULT_END_OF_INPUT; } break; case STATE_READING_TAG_DATA: if (readTagData(input)) { return RESULT_CONTINUE; } break; } } }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { if (synchronizedHeaderData == 0) { try { synchronize(input, false); } catch (EOFException e) { return RESULT_END_OF_INPUT; } } if (seeker == null) { seeker = setupSeeker(input); extractorOutput.seekMap(seeker); trackOutput.format(Format.createAudioSampleFormat(null, synchronizedHeader.mimeType, null, Format.NO_VALUE, MpegAudioHeader.MAX_FRAME_SIZE_BYTES, synchronizedHeader.channels, synchronizedHeader.sampleRate, Format.NO_VALUE, gaplessInfoHolder.encoderDelay, gaplessInfoHolder.encoderPadding, null, null, 0, null, (flags & FLAG_DISABLE_ID3_METADATA) != 0 ? null : metadata)); } return readSample(input); }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { while (true) { switch (parserState) { case STATE_READING_HEADER: parseHeader(input); parserState = STATE_READING_TIMESTAMP_AND_COUNT; break; case STATE_READING_TIMESTAMP_AND_COUNT: if (parseTimestampAndSampleCount(input)) { parserState = STATE_READING_SAMPLES; } else { parserState = STATE_READING_HEADER; return RESULT_END_OF_INPUT; } break; case STATE_READING_SAMPLES: parseSamples(input); parserState = STATE_READING_TIMESTAMP_AND_COUNT; return RESULT_CONTINUE; default: throw new IllegalStateException(); } } }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { if (synchronizedHeaderData == 0) { try { synchronize(input, false); } catch (EOFException e) { return RESULT_END_OF_INPUT; } } if (seeker == null) { seeker = setupSeeker(input); extractorOutput.seekMap(seeker); trackOutput.format(Format.createAudioSampleFormat(null, synchronizedHeader.mimeType, null, Format.NO_VALUE, MpegAudioHeader.MAX_FRAME_SIZE_BYTES, synchronizedHeader.channels, synchronizedHeader.sampleRate, Format.NO_VALUE, gaplessInfoHolder.encoderDelay, gaplessInfoHolder.encoderPadding, null, null, 0, null)); } return readSample(input); }
public void testCustomPesReader() throws Exception { CustomEsReaderFactory factory = new CustomEsReaderFactory(); TsExtractor tsExtractor = new TsExtractor(new TimestampAdjuster(0), factory, false); FakeExtractorInput input = new FakeExtractorInput.Builder() .setData(TestUtil.getByteArray(getInstrumentation(), "ts/sample.ts")) .setSimulateIOErrors(false) .setSimulateUnknownLength(false) .setSimulatePartialReads(false).build(); FakeExtractorOutput output = new FakeExtractorOutput(); tsExtractor.init(output); tsExtractor.seek(input.getPosition()); PositionHolder seekPositionHolder = new PositionHolder(); int readResult = Extractor.RESULT_CONTINUE; while (readResult != Extractor.RESULT_END_OF_INPUT) { readResult = tsExtractor.read(input, seekPositionHolder); } CustomEsReader reader = factory.reader; assertEquals(2, reader.packetsRead); TrackOutput trackOutput = reader.getTrackOutput(); assertTrue(trackOutput == output.trackOutputs.get(257 /* PID of audio track. */)); assertEquals( Format.createTextSampleFormat("Overriding format", "mime", null, 0, 0, "und", null, 0), ((FakeTrackOutput) trackOutput).format); }
@Override public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException { if (streamReader == null) { if (!sniffInternal(input)) { throw new ParserException("Failed to determine bitstream type"); } input.resetPeekPosition(); } if (!streamReaderInitialized) { TrackOutput trackOutput = output.track(0, C.TRACK_TYPE_AUDIO); output.endTracks(); streamReader.init(output, trackOutput); streamReaderInitialized = true; } return streamReader.read(input, seekPosition); }