/** * Continues a read from the provided {@code source} into a given {@code target}. It's assumed * that the data should be written into {@code target} starting from an offset of zero. * * @param source The source from which to read. * @param target The target into which data is to be read, or {@code null} to skip. * @param targetLength The target length of the read. * @return Whether the target length has been reached. */ private boolean continueRead(ParsableByteArray source, byte[] target, int targetLength) { int bytesToRead = Math.min(source.bytesLeft(), targetLength - bytesRead); if (bytesToRead <= 0) { return true; } else if (target == null) { source.skip(bytesToRead); } else { source.readBytes(target, bytesRead, bytesToRead); } bytesRead += bytesToRead; return bytesRead == targetLength; }
private static void parseSenc(ParsableByteArray senc, int offset, TrackFragment out) throws ParserException { senc.setPosition(Atom.HEADER_SIZE + offset); int fullAtom = senc.readInt(); int flags = Atom.parseFullAtomFlags(fullAtom); if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) { // TODO: Implement this. throw new ParserException("Overriding TrackEncryptionBox parameters is unsupported."); } boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0; int sampleCount = senc.readUnsignedIntToInt(); if (sampleCount != out.length) { throw new ParserException("Length mismatch: " + sampleCount + ", " + out.length); } Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption); out.initEncryptionData(senc.bytesLeft()); out.fillEncryptionData(senc); }
@Override public void consume(ParsableByteArray data) { if (!writingSample) { return; } int bytesAvailable = data.bytesLeft(); if (sampleBytesRead < ID3_HEADER_SIZE) { // We're still reading the ID3 header. int headerBytesAvailable = Math.min(bytesAvailable, ID3_HEADER_SIZE - sampleBytesRead); System.arraycopy( data.data, data.getPosition(), id3Header.data, sampleBytesRead, headerBytesAvailable); if (sampleBytesRead + headerBytesAvailable == ID3_HEADER_SIZE) { // We've finished reading the ID3 header. Extract the sample size. id3Header.setPosition(6); // 'ID3' (3) + version (2) + flags (1) sampleSize = ID3_HEADER_SIZE + id3Header.readSynchSafeInt(); } } // Write data to the output. output.sampleData(data, bytesAvailable); sampleBytesRead += bytesAvailable; }
@Override public void consume(ParsableByteArray data, boolean payloadUnitStartIndicator) { if (payloadUnitStartIndicator) { switch (state) { case STATE_FINDING_HEADER: case STATE_READING_HEADER: // Expected. break; case STATE_READING_HEADER_EXTENSION: Log.w(TAG, "Unexpected start indicator reading extended header"); break; case STATE_READING_BODY: // If payloadSize == -1 then the length of the previous packet was unspecified, and so // we only know that it's finished now that we've seen the start of the next one. This // is expected. If payloadSize != -1, then the length of the previous packet was known, // but we didn't receive that amount of data. This is not expected. if (payloadSize != -1) { Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes"); } // Either way, if the body was started, notify the reader that it has now finished. if (bodyStarted) { pesPayloadReader.packetFinished(); } break; } setState(STATE_READING_HEADER); } while (data.bytesLeft() > 0) { switch (state) { case STATE_FINDING_HEADER: data.skip(data.bytesLeft()); break; case STATE_READING_HEADER: if (continueRead(data, pesScratch.getData(), HEADER_SIZE)) { setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER); } break; case STATE_READING_HEADER_EXTENSION: int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength); // Read as much of the extended header as we're interested in, and skip the rest. if (continueRead(data, pesScratch.getData(), readLength) && continueRead(data, null, extendedHeaderLength)) { parseHeaderExtension(); bodyStarted = false; setState(STATE_READING_BODY); } break; case STATE_READING_BODY: readLength = data.bytesLeft(); int padding = payloadSize == -1 ? 0 : readLength - payloadSize; if (padding > 0) { readLength -= padding; data.setLimit(data.getPosition() + readLength); } pesPayloadReader.consume(data, timeUs, !bodyStarted); bodyStarted = true; if (payloadSize != -1) { payloadSize -= readLength; if (payloadSize == 0) { pesPayloadReader.packetFinished(); setState(STATE_READING_HEADER); } } break; } } }