package org.jcodec.codecs.mpeg12.bitstream; import static org.jcodec.codecs.mpeg12.MPEGConst.EXTENSION_START_CODE; import java.io.IOException; import java.nio.ByteBuffer; import org.jcodec.common.io.BitReader; import org.jcodec.common.io.BitWriter; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * @author The JCodec project * */ public class PictureHeader { public static final int Quant_Matrix_Extension = 0x3; public static final int Copyright_Extension = 0x4; public static final int Picture_Display_Extension = 0x7; public static final int Picture_Coding_Extension = 0x8; public static final int Picture_Spatial_Scalable_Extension = 0x9; public static final int Picture_Temporal_Scalable_Extension = 0x10; public static final int IntraCoded = 0x1; public static final int PredictiveCoded = 0x2; public static final int BiPredictiveCoded = 0x3; public int temporal_reference; public int picture_coding_type; public int vbv_delay; public int full_pel_forward_vector; public int forward_f_code; public int full_pel_backward_vector; public int backward_f_code; public QuantMatrixExtension quantMatrixExtension; public CopyrightExtension copyrightExtension; public PictureDisplayExtension pictureDisplayExtension; public PictureCodingExtension pictureCodingExtension; public PictureSpatialScalableExtension pictureSpatialScalableExtension; public PictureTemporalScalableExtension pictureTemporalScalableExtension; private boolean hasExtensions; public static PictureHeader read(ByteBuffer bb) { BitReader in = new BitReader(bb); PictureHeader ph = new PictureHeader(); ph.temporal_reference = in.readNBit(10); ph.picture_coding_type = in.readNBit(3); ph.vbv_delay = in.readNBit(16); if (ph.picture_coding_type == 2 || ph.picture_coding_type == 3) { ph.full_pel_forward_vector = in.read1Bit(); ph.forward_f_code = in.readNBit(3); } if (ph.picture_coding_type == 3) { ph.full_pel_backward_vector = in.read1Bit(); ph.backward_f_code = in.readNBit(3); } while (in.read1Bit() == 1) { in.readNBit(8); } return ph; } public static void readExtension(ByteBuffer bb, PictureHeader ph, SequenceHeader sh) { ph.hasExtensions = true; BitReader in = new BitReader(bb); int extType = in.readNBit(4); switch (extType) { case Quant_Matrix_Extension: ph.quantMatrixExtension = QuantMatrixExtension.read(in); break; case Copyright_Extension: ph.copyrightExtension = CopyrightExtension.read(in); break; case Picture_Display_Extension: ph.pictureDisplayExtension = PictureDisplayExtension.read(in, sh.sequenceExtension, ph.pictureCodingExtension); break; case Picture_Coding_Extension: ph.pictureCodingExtension = PictureCodingExtension.read(in); break; case Picture_Spatial_Scalable_Extension: ph.pictureSpatialScalableExtension = PictureSpatialScalableExtension.read(in); break; case Picture_Temporal_Scalable_Extension: ph.pictureTemporalScalableExtension = PictureTemporalScalableExtension.read(in); break; default: throw new RuntimeException("Unsupported extension: " + extType); } } public void write(ByteBuffer os) throws IOException { BitWriter out = new BitWriter(os); out.writeNBit(temporal_reference, 10); out.writeNBit(picture_coding_type, 3); out.writeNBit(vbv_delay, 16); if (picture_coding_type == 2 || picture_coding_type == 3) { out.write1Bit(full_pel_forward_vector); out.write1Bit(forward_f_code); } if (picture_coding_type == 3) { out.write1Bit(full_pel_backward_vector); out.writeNBit(backward_f_code, 3); } out.write1Bit(0); writeExtensions(os); } private void writeExtensions(ByteBuffer out) throws IOException { if (quantMatrixExtension != null) { out.putInt(EXTENSION_START_CODE); BitWriter os = new BitWriter(out); os.writeNBit(Quant_Matrix_Extension, 4); quantMatrixExtension.write(os); } if (copyrightExtension != null) { out.putInt(EXTENSION_START_CODE); BitWriter os = new BitWriter(out); os.writeNBit(Copyright_Extension, 4); copyrightExtension.write(os); } if (pictureCodingExtension != null) { out.putInt(EXTENSION_START_CODE); BitWriter os = new BitWriter(out); os.writeNBit(Picture_Coding_Extension, 4); pictureCodingExtension.write(os); } if (pictureDisplayExtension != null) { out.putInt(EXTENSION_START_CODE); BitWriter os = new BitWriter(out); os.writeNBit(Picture_Display_Extension, 4); pictureDisplayExtension.write(os); } if (pictureSpatialScalableExtension != null) { out.putInt(EXTENSION_START_CODE); BitWriter os = new BitWriter(out); os.writeNBit(Picture_Spatial_Scalable_Extension, 4); pictureSpatialScalableExtension.write(os); } if (pictureTemporalScalableExtension != null) { out.putInt(EXTENSION_START_CODE); BitWriter os = new BitWriter(out); os.writeNBit(Picture_Temporal_Scalable_Extension, 4); pictureTemporalScalableExtension.write(os); } } public boolean hasExtensions() { return hasExtensions; } }