/** Skips scaling_list_data(). See H.265/HEVC (2014) 7.3.4. */ private void skipScalingList(ParsableBitArray bitArray) { for (int sizeId = 0; sizeId < 4; sizeId++) { for (int matrixId = 0; matrixId < 6; matrixId += sizeId == 3 ? 3 : 1) { if (!bitArray.readBit()) { // scaling_list_pred_mode_flag[sizeId][matrixId] // scaling_list_pred_matrix_id_delta[sizeId][matrixId] bitArray.readUnsignedExpGolombCodedInt(); } else { int coefNum = Math.min(64, 1 << (4 + sizeId << 1)); if (sizeId > 1) { // scaling_list_dc_coef_minus8[sizeId - 2][matrixId] bitArray.readSignedExpGolombCodedInt(); } for (int i = 0; i < coefNum; i++) { bitArray.readSignedExpGolombCodedInt(); // scaling_list_delta_coef } } } } }
/** * Skips scaling_list_data(). See H.265/HEVC (2014) 7.3.4. */ private static void skipScalingList(ParsableBitArray bitArray) { for (int sizeId = 0; sizeId < 4; sizeId++) { for (int matrixId = 0; matrixId < 6; matrixId += sizeId == 3 ? 3 : 1) { if (!bitArray.readBit()) { // scaling_list_pred_mode_flag[sizeId][matrixId] // scaling_list_pred_matrix_id_delta[sizeId][matrixId] bitArray.readUnsignedExpGolombCodedInt(); } else { int coefNum = Math.min(64, 1 << (4 + (sizeId << 1))); if (sizeId > 1) { // scaling_list_dc_coef_minus8[sizeId - 2][matrixId] bitArray.readSignedExpGolombCodedInt(); } for (int i = 0; i < coefNum; i++) { bitArray.readSignedExpGolombCodedInt(); // scaling_list_delta_coef } } } } }
private void skipScalingList(ParsableBitArray bitArray, int size) { int lastScale = 8; int nextScale = 8; for (int i = 0; i < size; i++) { if (nextScale != 0) { int deltaScale = bitArray.readSignedExpGolombCodedInt(); nextScale = (lastScale + deltaScale + 256) % 256; } lastScale = (nextScale == 0) ? lastScale : nextScale; } }
public TsExtractor(long firstSampleTimestampUs, AudioCapabilities audioCapabilities, boolean idrKeyframesOnly) { this.firstSampleTimestampUs = firstSampleTimestampUs; this.idrKeyframesOnly = idrKeyframesOnly; tsScratch = new ParsableBitArray(new byte[3]); tsPacketBuffer = new ParsableByteArray(TS_PACKET_SIZE); streamTypes = new SparseBooleanArray(); allowedPassthroughStreamTypes = getPassthroughStreamTypes(audioCapabilities); tsPayloadReaders = new SparseArray<>(); tsPayloadReaders.put(TS_PAT_PID, new PatReader()); lastPts = Long.MIN_VALUE; }
/** * Reads the number of short term reference picture sets in a SPS as ue(v), then skips all of * them. See H.265/HEVC (2014) 7.3.7. */ private static void skipShortTermRefPicSets(ParsableBitArray bitArray) { int numShortTermRefPicSets = bitArray.readUnsignedExpGolombCodedInt(); boolean interRefPicSetPredictionFlag = false; int numNegativePics = 0; int numPositivePics = 0; // As this method applies in a SPS, the only element of NumDeltaPocs accessed is the previous // one, so we just keep track of that rather than storing the whole array. // RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1) and delta_idx_minus1 is always zero in SPS. int previousNumDeltaPocs = 0; for (int stRpsIdx = 0; stRpsIdx < numShortTermRefPicSets; stRpsIdx++) { if (stRpsIdx != 0) { interRefPicSetPredictionFlag = bitArray.readBit(); } if (interRefPicSetPredictionFlag) { bitArray.skipBits(1); // delta_rps_sign bitArray.readUnsignedExpGolombCodedInt(); // abs_delta_rps_minus1 for (int j = 0; j <= previousNumDeltaPocs; j++) { if (bitArray.readBit()) { // used_by_curr_pic_flag[j] bitArray.skipBits(1); // use_delta_flag[j] } } } else { numNegativePics = bitArray.readUnsignedExpGolombCodedInt(); numPositivePics = bitArray.readUnsignedExpGolombCodedInt(); previousNumDeltaPocs = numNegativePics + numPositivePics; for (int i = 0; i < numNegativePics; i++) { bitArray.readUnsignedExpGolombCodedInt(); // delta_poc_s0_minus1[i] bitArray.skipBits(1); // used_by_curr_pic_s0_flag[i] } for (int i = 0; i < numPositivePics; i++) { bitArray.readUnsignedExpGolombCodedInt(); // delta_poc_s1_minus1[i] bitArray.skipBits(1); // used_by_curr_pic_s1_flag[i] } } } }
public SampleReader(TrackOutput output, boolean allowNonIdrKeyframes, boolean detectAccessUnits) { this.output = output; this.allowNonIdrKeyframes = allowNonIdrKeyframes; this.detectAccessUnits = detectAccessUnits; sps = new SparseArray<>(); pps = new SparseArray<>(); previousSliceHeader = new SliceHeaderData(); sliceHeader = new SliceHeaderData(); scratch = new ParsableBitArray(); buffer = new byte[DEFAULT_BUFFER_SIZE]; reset(); }
public TsExtractor(PtsTimestampAdjuster ptsTimestampAdjuster, int workaroundFlags) { this.ptsTimestampAdjuster = ptsTimestampAdjuster; this.workaroundFlags = workaroundFlags; tsPacketBuffer = new ParsableByteArray(TS_PACKET_SIZE); tsScratch = new ParsableBitArray(new byte[3]); tsPayloadReaders = new SparseArray<>(); tsPayloadReaders.put(TS_PAT_PID, new PatReader()); streamTypes = new SparseBooleanArray(); }
public PesReader(ElementaryStreamReader pesPayloadReader, PtsTimestampAdjuster ptsTimestampAdjuster) { this.pesPayloadReader = pesPayloadReader; this.ptsTimestampAdjuster = ptsTimestampAdjuster; pesScratch = new ParsableBitArray(new byte[PES_SCRATCH_SIZE]); state = STATE_FINDING_HEADER; }
/** * Constructs a new reader for (E-)AC-3 elementary streams. * * @param output Track output for extracted samples. * @param isEac3 Whether the stream is E-AC-3 (ETSI TS 102 366 Annex E). Specify {@code false} to * parse sample headers as AC-3. */ public Ac3Reader(TrackOutput output, boolean isEac3) { super(output); this.isEac3 = isEac3; headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; }
/** * @param output A {@link TrackOutput} to which AAC samples should be written. * @param id3Output A {@link TrackOutput} to which ID3 samples should be written. */ public AdtsReader(TrackOutput output, TrackOutput id3Output) { super(output); this.id3Output = id3Output; id3Output.format(MediaFormat.createId3Format()); adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]); id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, ID3_HEADER_SIZE)); setFindingSampleState(); }
private static AvcCData parseAvcCFromParent(ParsableByteArray parent, int position) { parent.setPosition(position + Atom.HEADER_SIZE + 4); // Start of the AVCDecoderConfigurationRecord (defined in 14496-15) int nalUnitLengthFieldLength = (parent.readUnsignedByte() & 0x3) + 1; if (nalUnitLengthFieldLength == 3) { throw new IllegalStateException(); } List<byte[]> initializationData = new ArrayList<>(); float pixelWidthAspectRatio = 1; int numSequenceParameterSets = parent.readUnsignedByte() & 0x1F; for (int j = 0; j < numSequenceParameterSets; j++) { initializationData.add(NalUnitUtil.parseChildNalUnit(parent)); } int numPictureParameterSets = parent.readUnsignedByte(); for (int j = 0; j < numPictureParameterSets; j++) { initializationData.add(NalUnitUtil.parseChildNalUnit(parent)); } if (numSequenceParameterSets > 0) { // Parse the first sequence parameter set to obtain pixelWidthAspectRatio. ParsableBitArray spsDataBitArray = new ParsableBitArray(initializationData.get(0)); // Skip the NAL header consisting of the nalUnitLengthField and the type (1 byte). spsDataBitArray.setPosition(8 * (nalUnitLengthFieldLength + 1)); pixelWidthAspectRatio = NalUnitUtil.parseSpsNalUnit(spsDataBitArray).pixelWidthAspectRatio; } return new AvcCData(initializationData, nalUnitLengthFieldLength, pixelWidthAspectRatio); }
/** * Builds initialization data for a {@link MediaFormat} from H.264 (AVC) codec private data. * * @return The AvcSequenceHeader data needed to initialize the video codec. * @throws ParserException If the initialization data could not be built. */ private AvcSequenceHeaderData parseAvcCodecPrivate(ParsableByteArray buffer) throws ParserException { // TODO: Deduplicate with AtomParsers.parseAvcCFromParent. buffer.setPosition(4); int nalUnitLengthFieldLength = (buffer.readUnsignedByte() & 0x03) + 1; Assertions.checkState(nalUnitLengthFieldLength != 3); List<byte[]> initializationData = new ArrayList<>(); int numSequenceParameterSets = buffer.readUnsignedByte() & 0x1F; for (int i = 0; i < numSequenceParameterSets; i++) { initializationData.add(NalUnitUtil.parseChildNalUnit(buffer)); } int numPictureParameterSets = buffer.readUnsignedByte(); for (int j = 0; j < numPictureParameterSets; j++) { initializationData.add(NalUnitUtil.parseChildNalUnit(buffer)); } float pixelWidthAspectRatio = 1; int width = MediaFormat.NO_VALUE; int height = MediaFormat.NO_VALUE; if (numSequenceParameterSets > 0) { // Parse the first sequence parameter set to obtain pixelWidthAspectRatio. ParsableBitArray spsDataBitArray = new ParsableBitArray(initializationData.get(0)); // Skip the NAL header consisting of the nalUnitLengthField and the type (1 byte). spsDataBitArray.setPosition(8 * (nalUnitLengthFieldLength + 1)); NalUnitUtil.SpsData sps = NalUnitUtil.parseSpsNalUnit(spsDataBitArray); width = sps.width; height = sps.height; pixelWidthAspectRatio = sps.pixelWidthAspectRatio; } return new AvcSequenceHeaderData(initializationData, nalUnitLengthFieldLength, width, height, pixelWidthAspectRatio); }
public void testReadBitCompareWithMSb() { byte[] data = {0x0F}; VorbisBitArray lsb = new VorbisBitArray(data); ParsableBitArray msb = new ParsableBitArray(data); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); assertEquals(lsb.readBit(), !msb.readBit()); }
public void testReadBitsCompareWithMSb() { byte[] data = {0x0F}; VorbisBitArray lsb = new VorbisBitArray(data); ParsableBitArray msb = new ParsableBitArray(data); assertEquals(15, lsb.readBits(4)); assertEquals(lsb.readBits(4), msb.readBits(4)); assertEquals(15, msb.readBits(4)); }
public void testReadBitsCompareWithMSbBeyondByteBoundary() { byte[] data = {(byte) 0xF0, 0x0F}; VorbisBitArray lsb = new VorbisBitArray(data); ParsableBitArray msb = new ParsableBitArray(data); assertEquals(0x00, lsb.readBits(4)); assertEquals(0x0F, msb.readBits(4)); assertEquals(0xFF, lsb.readBits(8)); assertEquals(0x00, msb.readBits(8)); assertEquals(0x00, lsb.readBits(4)); assertEquals(0x0F, msb.readBits(4)); }
public TsExtractor(boolean shouldSpliceIn, long firstSampleTimestamp, BufferPool bufferPool) { super(shouldSpliceIn); this.firstSampleTimestamp = firstSampleTimestamp; this.bufferPool = bufferPool; tsScratch = new ParsableBitArray(new byte[3]); tsPacketBuffer = new ParsableByteArray(TS_PACKET_SIZE); sampleQueues = new SparseArray<SampleQueue>(); tsPayloadReaders = new SparseArray<TsPayloadReader>(); tsPayloadReaders.put(TS_PAT_PID, new PatReader()); lastPts = Long.MIN_VALUE; }
public TsExtractor(boolean shouldSpliceIn, long firstSampleTimestamp, BufferPool bufferPool) { this.firstSampleTimestamp = firstSampleTimestamp; this.bufferPool = bufferPool; tsScratch = new ParsableBitArray(new byte[3]); tsPacketBuffer = new ParsableByteArray(TS_PACKET_SIZE); sampleQueues = new SparseArray<SampleQueue>(); tsPayloadReaders = new SparseArray<TsPayloadReader>(); tsPayloadReaders.put(TS_PAT_PID, new PatReader()); lastPts = Long.MIN_VALUE; tsStreamTypes = new SparseArray<Integer>(); }
public IfrParserBuffer() { ifrData = new byte[DEFAULT_BUFFER_SIZE]; scratchSliceType = new ParsableBitArray(ifrData); reset(); }
public PatReader() { patScratch = new ParsableBitArray(new byte[4]); }
public PmtReader() { pmtScratch = new ParsableBitArray(new byte[5]); }
public PesReader(ElementaryStreamReader pesPayloadReader) { this.pesPayloadReader = pesPayloadReader; pesScratch = new ParsableBitArray(new byte[HEADER_SIZE]); state = STATE_FINDING_HEADER; }
public Ac3Reader(TrackOutput output) { super(output); headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; }
public AdtsReader(TrackOutput output) { super(output); adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]); state = STATE_FINDING_SYNC; }
Eia608Parser() { seiBuffer = new ParsableBitArray(); stringBuilder = new StringBuilder(); captions = new ArrayList<>(); }
private static ParsableBitArray unescape(NalUnitTargetBuffer buffer) { int length = NalUnitUtil.unescapeStream(buffer.nalData, buffer.nalLength); ParsableBitArray bitArray = new ParsableBitArray(buffer.nalData, length); bitArray.skipBits(32); // NAL header return bitArray; }
@Override public boolean sniff(ExtractorInput input) throws IOException, InterruptedException { // Skip any ID3 headers. ParsableByteArray scratch = new ParsableByteArray(10); ParsableBitArray scratchBits = new ParsableBitArray(scratch.data); int startPosition = 0; while (true) { input.peekFully(scratch.data, 0, 10); scratch.setPosition(0); if (scratch.readUnsignedInt24() != ID3_TAG) { break; } int length = (scratch.data[6] & 0x7F) << 21 | ((scratch.data[7] & 0x7F) << 14) | ((scratch.data[8] & 0x7F) << 7) | (scratch.data[9] & 0x7F); startPosition += 10 + length; input.advancePeekPosition(length); } input.resetPeekPosition(); input.advancePeekPosition(startPosition); // Try to find four or more consecutive AAC audio frames, exceeding the MPEG TS packet size. int headerPosition = startPosition; int validFramesSize = 0; int validFramesCount = 0; while (true) { input.peekFully(scratch.data, 0, 2); scratch.setPosition(0); int syncBytes = scratch.readUnsignedShort(); if ((syncBytes & 0xFFF6) != 0xFFF0) { validFramesCount = 0; validFramesSize = 0; input.resetPeekPosition(); if (++headerPosition - startPosition >= MAX_SNIFF_BYTES) { return false; } input.advancePeekPosition(headerPosition); } else { if (++validFramesCount >= 4 && validFramesSize > 188) { return true; } // Skip the frame. input.peekFully(scratch.data, 0, 4); scratchBits.setPosition(14); int frameSize = scratchBits.readBits(13); // Either the stream is malformed OR we're not parsing an ADTS stream. if (frameSize <= 6) { return false; } input.advancePeekPosition(frameSize - 6); validFramesSize += frameSize; } } }
public PmtReader() { pmtScratch = new ParsableBitArray(new byte[5]); sectionData = new ParsableByteArray(); }
public PesReader(ElementaryStreamReader pesPayloadReader, PtsTimestampAdjuster ptsTimestampAdjuster) { this.pesPayloadReader = pesPayloadReader; this.ptsTimestampAdjuster = ptsTimestampAdjuster; pesScratch = new ParsableBitArray(new byte[PES_SCRATCH_SIZE]); }