package org.jcodec.codecs.aac.blocks; import org.jcodec.codecs.aac.ChannelPosition; import org.jcodec.common.io.BitReader; import java.io.IOException; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * Decode program configuration element; reference: table 4.2. * * @author The JCodec project * */ public class BlockPCE extends Block { private static final int MAX_ELEM_ID = 16; public static class ChannelMapping { RawDataBlockType syn_ele; int someInt; ChannelPosition position; } public void parse(BitReader _in) { _in.readNBit(2); // object_type int samplingIndex = (int) _in.readNBit(4); int num_front = (int) _in.readNBit(4); int num_side = (int) _in.readNBit(4); int num_back = (int) _in.readNBit(4); int num_lfe = (int) _in.readNBit(2); int num_assoc_data = (int) _in.readNBit(3); int num_cc = (int) _in.readNBit(4); if (_in.read1Bit() != 0) _in.readNBit(4); // mono_mixdown_tag if (_in.read1Bit() != 0) _in.readNBit(4); // stereo_mixdown_tag if (_in.read1Bit() != 0) _in.readNBit(3); // mixdown_coeff_index and pseudo_surround // if (!_in.moreData(4 * (num_front + num_side + num_back + num_lfe + // num_assoc_data + num_cc))) { // throw new RuntimeException("Overread"); // } ChannelMapping[] layout_map = new ChannelMapping[MAX_ELEM_ID * 4]; int tags = 0; decodeChannelMap(layout_map, tags, ChannelPosition.AAC_CHANNEL_FRONT, _in, num_front); tags = num_front; decodeChannelMap(layout_map, tags, ChannelPosition.AAC_CHANNEL_SIDE, _in, num_side); tags += num_side; decodeChannelMap(layout_map, tags, ChannelPosition.AAC_CHANNEL_BACK, _in, num_back); tags += num_back; decodeChannelMap(layout_map, tags, ChannelPosition.AAC_CHANNEL_LFE, _in, num_lfe); tags += num_lfe; _in.skip(4 * num_assoc_data); decodeChannelMap(layout_map, tags, ChannelPosition.AAC_CHANNEL_CC, _in, num_cc); tags += num_cc; _in.align(); /* comment field, first byte is length */ int comment_len = (int) _in.readNBit(8) * 8; // if (!_in.moreData(comment_len)) { // throw new RuntimeException("Overread"); // } _in.skip(comment_len); } /** * Decode an array of 4 bit element IDs, optionally interleaved with a * stereo/mono switching bit. * * @throws IOException */ private void decodeChannelMap(ChannelMapping layout_map[], int offset, ChannelPosition type, BitReader _in, int n) { while (n-- > 0) { RawDataBlockType syn_ele = null; switch (type) { case AAC_CHANNEL_FRONT: case AAC_CHANNEL_BACK: case AAC_CHANNEL_SIDE: syn_ele = RawDataBlockType.values()[_in.read1Bit()]; break; case AAC_CHANNEL_CC: _in.read1Bit(); syn_ele = RawDataBlockType.TYPE_CCE; break; case AAC_CHANNEL_LFE: syn_ele = RawDataBlockType.TYPE_LFE; break; } layout_map[offset].syn_ele = syn_ele; layout_map[offset].someInt = (int) _in.readNBit(4); layout_map[offset].position = type; offset++; } } }