package org.jcodec.codecs.mpeg12.bitstream;
import static org.jcodec.codecs.mpeg12.MPEGConst.EXTENSION_START_CODE;
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 SequenceHeader implements MPEGHeader {
private static boolean _hasExtensions;
public int horizontal_size;
public int vertical_size;
public int aspect_ratio_information;
public int frame_rate_code;
public int bit_rate;
public int vbv_buffer_size_value;
public int constrained_parameters_flag;
public int[] intra_quantiser_matrix;
public int[] non_intra_quantiser_matrix;
public SequenceExtension sequenceExtension;
public SequenceScalableExtension sequenceScalableExtension;
public SequenceDisplayExtension sequenceDisplayExtension;
public static SequenceHeader createSequenceHeader(int horizontal_size, int vertical_size,
int aspect_ratio_information, int frame_rate_code, int bit_rate, int vbv_buffer_size_value,
int constrained_parameters_flag, int[] intra_quantiser_matrix, int[] non_intra_quantiser_matrix) {
SequenceHeader sh = new SequenceHeader();
sh.horizontal_size = horizontal_size;
sh.vertical_size = vertical_size;
sh.aspect_ratio_information = aspect_ratio_information;
sh.frame_rate_code = frame_rate_code;
sh.bit_rate = bit_rate;
sh.vbv_buffer_size_value = vbv_buffer_size_value;
sh.constrained_parameters_flag = constrained_parameters_flag;
sh.intra_quantiser_matrix = intra_quantiser_matrix;
sh.non_intra_quantiser_matrix = non_intra_quantiser_matrix;
return sh;
}
private SequenceHeader() {
}
public static SequenceHeader read(ByteBuffer bb) {
BitReader _in = BitReader.createBitReader(bb);
SequenceHeader sh = new SequenceHeader();
sh.horizontal_size = _in.readNBit(12);
sh.vertical_size = _in.readNBit(12);
sh.aspect_ratio_information = _in.readNBit(4);
sh.frame_rate_code = _in.readNBit(4);
sh.bit_rate = _in.readNBit(18);
_in.read1Bit();
sh.vbv_buffer_size_value = _in.readNBit(10);
sh.constrained_parameters_flag = _in.read1Bit();
if (_in.read1Bit() != 0) {
sh.intra_quantiser_matrix = new int[64];
for (int i = 0; i < 64; i++) {
sh.intra_quantiser_matrix[i] = _in.readNBit(8);
}
}
if (_in.read1Bit() != 0) {
sh.non_intra_quantiser_matrix = new int[64];
for (int i = 0; i < 64; i++) {
sh.non_intra_quantiser_matrix[i] = _in.readNBit(8);
}
}
return sh;
}
public static void readExtension(ByteBuffer bb, SequenceHeader sh) {
_hasExtensions = true;
BitReader _in = BitReader.createBitReader(bb);
int extType = _in.readNBit(4);
switch (extType) {
case SequenceExtension.Sequence_Extension:
sh.sequenceExtension = SequenceExtension.read(_in);
break;
case SequenceScalableExtension.Sequence_Scalable_Extension:
sh.sequenceScalableExtension = SequenceScalableExtension.read(_in);
break;
case SequenceDisplayExtension.Sequence_Display_Extension:
sh.sequenceDisplayExtension = SequenceDisplayExtension.read(_in);
break;
default:
throw new RuntimeException("Unsupported extension: " + extType);
}
}
@Override
public void write(ByteBuffer bb) {
BitWriter bw = new BitWriter(bb);
bw.writeNBit(horizontal_size, 12);
bw.writeNBit(vertical_size, 12);
bw.writeNBit(aspect_ratio_information, 4);
bw.writeNBit(frame_rate_code, 4);
bw.writeNBit(bit_rate, 18);
bw.write1Bit(1);
bw.writeNBit(vbv_buffer_size_value, 10);
bw.write1Bit(constrained_parameters_flag);
bw.write1Bit(intra_quantiser_matrix != null ? 1 : 0);
if (intra_quantiser_matrix != null) {
for (int i = 0; i < 64; i++) {
bw.writeNBit(intra_quantiser_matrix[i], 8);
}
}
bw.write1Bit(non_intra_quantiser_matrix != null ? 1 : 0);
if (non_intra_quantiser_matrix != null) {
for (int i = 0; i < 64; i++) {
bw.writeNBit(non_intra_quantiser_matrix[i], 8);
}
}
bw.flush();
writeExtensions(bb);
}
private void writeExtensions(ByteBuffer out) {
if (sequenceExtension != null) {
out.putInt(EXTENSION_START_CODE);
sequenceExtension.write(out);
}
if (sequenceScalableExtension != null) {
out.putInt(EXTENSION_START_CODE);
sequenceScalableExtension.write(out);
}
if (sequenceDisplayExtension != null) {
out.putInt(EXTENSION_START_CODE);
sequenceDisplayExtension.write(out);
}
}
public boolean hasExtensions() {
return _hasExtensions;
}
public void copyExtensions(SequenceHeader sh) {
sequenceExtension = sh.sequenceExtension;
sequenceScalableExtension = sh.sequenceScalableExtension;
sequenceDisplayExtension = sh.sequenceDisplayExtension;
}
}