/** * Parses the sample header. */ @SuppressWarnings("ReferenceEquality") private void parseHeader() { headerScratchBits.setPosition(0); Ac3Util.Ac3SyncFrameInfo frameInfo = Ac3Util.parseAc3SyncframeInfo(headerScratchBits); if (format == null || frameInfo.channelCount != format.channelCount || frameInfo.sampleRate != format.sampleRate || frameInfo.mimeType != format.sampleMimeType) { format = Format.createAudioSampleFormat(trackFormatId, frameInfo.mimeType, null, Format.NO_VALUE, Format.NO_VALUE, frameInfo.channelCount, frameInfo.sampleRate, null, null, 0, language); output.format(format); } sampleSize = frameInfo.frameSize; // In this class a sample is an access unit (syncframe in AC-3), but the MediaFormat sample rate // specifies the number of PCM audio samples per second. sampleDurationUs = C.MICROS_PER_SECOND * frameInfo.sampleCount / format.sampleRate; }
/** * Parses the sample header. */ private void parseHeader() { if (format == null) { // We read ahead to distinguish between AC-3 and E-AC-3. headerScratchBits.skipBits(40); isEac3 = headerScratchBits.readBits(5) == 16; headerScratchBits.setPosition(headerScratchBits.getPosition() - 45); format = isEac3 ? Ac3Util.parseEac3SyncframeFormat(headerScratchBits, trackFormatId, language , null) : Ac3Util.parseAc3SyncframeFormat(headerScratchBits, trackFormatId, language, null); output.format(format); } sampleSize = isEac3 ? Ac3Util.parseEAc3SyncframeSize(headerScratchBits.data) : Ac3Util.parseAc3SyncframeSize(headerScratchBits.data); int audioSamplesPerSyncframe = isEac3 ? Ac3Util.parseEAc3SyncframeAudioSampleCount(headerScratchBits.data) : Ac3Util.getAc3SyncframeAudioSampleCount(); // In this class a sample is an access unit (syncframe in AC-3), but the MediaFormat sample rate // specifies the number of PCM audio samples per second. sampleDurationUs = (int) (C.MICROS_PER_SECOND * audioSamplesPerSyncframe / format.sampleRate); }
/** * Parses the sample header. */ private void parseHeader() { if (format == null) { // We read ahead to distinguish between AC-3 and E-AC-3. headerScratchBits.skipBits(40); isEac3 = headerScratchBits.readBits(5) == 16; headerScratchBits.setPosition(headerScratchBits.getPosition() - 45); format = isEac3 ? Ac3Util.parseEac3SyncframeFormat(headerScratchBits, null, language , null) : Ac3Util.parseAc3SyncframeFormat(headerScratchBits, null, language, null); output.format(format); } sampleSize = isEac3 ? Ac3Util.parseEAc3SyncframeSize(headerScratchBits.data) : Ac3Util.parseAc3SyncframeSize(headerScratchBits.data); int audioSamplesPerSyncframe = isEac3 ? Ac3Util.parseEAc3SyncframeAudioSampleCount(headerScratchBits.data) : Ac3Util.getAc3SyncframeAudioSampleCount(); // In this class a sample is an access unit (syncframe in AC-3), but the MediaFormat sample rate // specifies the number of PCM audio samples per second. sampleDurationUs = (int) (C.MICROS_PER_SECOND * audioSamplesPerSyncframe / format.sampleRate); }
@Override public boolean sniff(ExtractorInput input) throws IOException, InterruptedException { // Skip any ID3 headers. ParsableByteArray scratch = new ParsableByteArray(10); int startPosition = 0; while (true) { input.peekFully(scratch.data, 0, 10); scratch.setPosition(0); if (scratch.readUnsignedInt24() != ID3_TAG) { break; } scratch.skipBytes(3); int length = scratch.readSynchSafeInt(); startPosition += 10 + length; input.advancePeekPosition(length); } input.resetPeekPosition(); input.advancePeekPosition(startPosition); int headerPosition = startPosition; int validFramesCount = 0; while (true) { input.peekFully(scratch.data, 0, 5); scratch.setPosition(0); int syncBytes = scratch.readUnsignedShort(); if (syncBytes != AC3_SYNC_WORD) { validFramesCount = 0; input.resetPeekPosition(); if (++headerPosition - startPosition >= MAX_SNIFF_BYTES) { return false; } input.advancePeekPosition(headerPosition); } else { if (++validFramesCount >= 4) { return true; } int frameSize = Ac3Util.parseAc3SyncframeSize(scratch.data); if (frameSize == C.LENGTH_UNSET) { return false; } input.advancePeekPosition(frameSize - 5); } } }