package org.jcodec.codecs.aac;
import org.jcodec.common.io.BitReader;
import org.jcodec.common.io.BitWriter;
import java.nio.ByteBuffer;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* @author The JCodec project
*
*/
public class ADTSParser {
public static class Header {
private int objectType;
private int chanConfig;
private int crcAbsent;
private int numAACFrames;
private int samplingIndex;
private int samples;
private int size;
public Header(int object_type, int chanConfig, int crcAbsent, int numAACFrames, int samplingIndex, int size) {
this.objectType = object_type;
this.chanConfig = chanConfig;
this.crcAbsent = crcAbsent;
this.numAACFrames = numAACFrames;
this.samplingIndex = samplingIndex;
this.size = size;
}
public int getObjectType() {
return objectType;
}
public int getChanConfig() {
return chanConfig;
}
public int getCrcAbsent() {
return crcAbsent;
}
public int getNumAACFrames() {
return numAACFrames;
}
public int getSamplingIndex() {
return samplingIndex;
}
public int getSamples() {
return samples;
}
public int getSize() {
return size;
}
public int getSampleRate() {
return AACConts.AAC_SAMPLE_RATES[samplingIndex];
}
}
public static Header read(ByteBuffer data) {
ByteBuffer dup = data.duplicate();
BitReader br = BitReader.createBitReader(dup);
// int size, rdb, ch, sr;
// int aot, crc_abs;
if (br.readNBit(12) != 0xfff) {
return null;
}
int id = br.read1Bit(); /* id */
int layer = br.readNBit(2); /* layer */
int crc_abs = br.read1Bit(); /* protection_absent */
int aot = br.readNBit(2); /* profile_objecttype */
int sr = br.readNBit(4); /* sample_frequency_index */
int pb = br.read1Bit(); /* private_bit */
int ch = br.readNBit(3); /* channel_configuration */
int origCopy = br.read1Bit(); /* original/copy */
int home = br.read1Bit(); /* home */
/* adts_variable_header */
int copy = br.read1Bit(); /* copyright_identification_bit */
int copyStart = br.read1Bit(); /* copyright_identification_start */
int size = br.readNBit(13); /* aac_frame_length */
if (size < 7)
return null;
int buffer = br.readNBit(11); /* adts_buffer_fullness */
int rdb = br.readNBit(2); /* number_of_raw_data_blocks_in_frame */
br.stop();
data.position(dup.position());
return new Header(aot + 1, ch, crc_abs, rdb + 1, sr, size);
}
public static ByteBuffer write(Header header, ByteBuffer buf) {
ByteBuffer data = buf.duplicate();
BitWriter br = new BitWriter(data);
// int size, rdb, ch, sr;
// int aot, crc_abs;
br.writeNBit(0xfff, 12);
br.write1Bit(1); /* id */
br.writeNBit(0, 2); /* layer */
br.write1Bit(header.getCrcAbsent()); /* protection_absent */
br.writeNBit(header.getObjectType() - 1, 2); /* profile_objecttype */
br.writeNBit(header.getSamplingIndex(), 4); /* sample_frequency_index */
br.write1Bit(0); /* private_bit */
br.writeNBit(header.getChanConfig(), 3); /* channel_configuration */
br.write1Bit(0); /* original/copy */
br.write1Bit(0); /* home */
/* adts_variable_header */
br.write1Bit(0); /* copyright_identification_bit */
br.write1Bit(0); /* copyright_identification_start */
br.writeNBit(header.getSize(), 13); /* aac_frame_length */
br.writeNBit(0, 11); /* adts_buffer_fullness */
br.writeNBit(header.getNumAACFrames() - 1, 2); /* number_of_raw_data_blocks_in_frame */
br.flush();
data.flip();
return data;
}
}