/** * Parses the sample header. */ private void parseHeader() { if (mediaFormat == null) { mediaFormat = isEac3 ? Ac3Util.parseEac3SyncframeFormat(headerScratchBits, null, C.UNKNOWN_TIME_US, null) : Ac3Util.parseAc3SyncframeFormat(headerScratchBits, null, C.UNKNOWN_TIME_US, null); output.format(mediaFormat); } 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 / mediaFormat.sampleRate); }
/** * Parses the sample header. */ private void parseHeader() { headerScratchBits.setPosition(0); sampleSize = Ac3Util.parseFrameSize(headerScratchBits); if (mediaFormat == null) { headerScratchBits.setPosition(0); mediaFormat = Ac3Util.parseFrameAc3Format(headerScratchBits); output.format(mediaFormat); bitrate = Ac3Util.getBitrate(sampleSize, mediaFormat.sampleRate); } frameDurationUs = (int) (1000L * 8 * sampleSize / bitrate); }
private static int getFramesPerEncodedSample(int encoding, ByteBuffer buffer) { if (encoding == C.ENCODING_DTS || encoding == C.ENCODING_DTS_HD) { return DtsUtil.parseDtsAudioSampleCount(buffer); } else if (encoding == C.ENCODING_AC3) { return Ac3Util.getAc3SyncframeAudioSampleCount(); } else if (encoding == C.ENCODING_E_AC3) { return Ac3Util.parseEAc3SyncframeAudioSampleCount(buffer); } else { throw new IllegalStateException("Unexpected audio encoding: " + encoding); } }
private static void parseAudioSampleEntry(ParsableByteArray parent, int atomType, int position, int size, long durationUs, StsdDataHolder out, int entryIndex) { parent.setPosition(position + Atom.HEADER_SIZE); parent.skipBytes(16); int channelCount = parent.readUnsignedShort(); int sampleSize = parent.readUnsignedShort(); parent.skipBytes(4); int sampleRate = parent.readUnsignedFixedPoint1616(); // If the atom type determines a MIME type, set it immediately. String mimeType = null; if (atomType == Atom.TYPE_ac_3) { mimeType = MimeTypes.AUDIO_AC3; } else if (atomType == Atom.TYPE_ec_3) { mimeType = MimeTypes.AUDIO_EC3; } byte[] initializationData = null; int childPosition = parent.getPosition(); while (childPosition - position < size) { parent.setPosition(childPosition); int childStartPosition = parent.getPosition(); int childAtomSize = parent.readInt(); Assertions.checkArgument(childAtomSize > 0, "childAtomSize should be positive"); int childAtomType = parent.readInt(); if (atomType == Atom.TYPE_mp4a || atomType == Atom.TYPE_enca) { if (childAtomType == Atom.TYPE_esds) { Pair<String, byte[]> mimeTypeAndInitializationData = parseEsdsFromParent(parent, childStartPosition); mimeType = mimeTypeAndInitializationData.first; initializationData = mimeTypeAndInitializationData.second; if (MimeTypes.AUDIO_AAC.equals(mimeType)) { // TODO: Do we really need to do this? See [Internal: b/10903778] // Update sampleRate and channelCount from the AudioSpecificConfig initialization data. Pair<Integer, Integer> audioSpecificConfig = CodecSpecificDataUtil.parseAacAudioSpecificConfig(initializationData); sampleRate = audioSpecificConfig.first; channelCount = audioSpecificConfig.second; } } else if (childAtomType == Atom.TYPE_sinf) { out.trackEncryptionBoxes[entryIndex] = parseSinfFromParent(parent, childStartPosition, childAtomSize); } } else if (atomType == Atom.TYPE_ac_3 && childAtomType == Atom.TYPE_dac3) { // TODO: Choose the right AC-3 track based on the contents of dac3/dec3. // TODO: Add support for encryption (by setting out.trackEncryptionBoxes). parent.setPosition(Atom.HEADER_SIZE + childStartPosition); out.mediaFormat = Ac3Util.parseAnnexFAc3Format(parent); return; } else if (atomType == Atom.TYPE_ec_3 && childAtomType == Atom.TYPE_dec3) { parent.setPosition(Atom.HEADER_SIZE + childStartPosition); out.mediaFormat = Ac3Util.parseAnnexFEAc3Format(parent); return; } childPosition += childAtomSize; } // If the media type was not recognized, ignore the track. if (mimeType == null) { return; } out.mediaFormat = MediaFormat.createAudioFormat(mimeType, sampleSize, durationUs, channelCount, sampleRate, initializationData == null ? null : Collections.singletonList(initializationData)); }