package org.jcodec.codecs.mpeg12.bitstream; import static org.jcodec.codecs.mpeg12.MPEGConst.EXTENSION_START_CODE; import static org.jcodec.codecs.mpeg12.bitstream.CopyrightExtension.Copyright_Extension; import static org.jcodec.codecs.mpeg12.bitstream.PictureCodingExtension.Picture_Coding_Extension; import static org.jcodec.codecs.mpeg12.bitstream.PictureDisplayExtension.Picture_Display_Extension; import static org.jcodec.codecs.mpeg12.bitstream.PictureSpatialScalableExtension.Picture_Spatial_Scalable_Extension; import static org.jcodec.codecs.mpeg12.bitstream.PictureTemporalScalableExtension.Picture_Temporal_Scalable_Extension; import static org.jcodec.codecs.mpeg12.bitstream.QuantMatrixExtension.Quant_Matrix_Extension; 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 PictureHeader implements MPEGHeader { 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 createPictureHeader(int temporal_reference, int picture_coding_type, int vbv_delay, int full_pel_forward_vector, int forward_f_code, int full_pel_backward_vector, int backward_f_code) { PictureHeader p = new PictureHeader(); p.temporal_reference = temporal_reference; p.picture_coding_type = picture_coding_type; p.vbv_delay = vbv_delay; p.full_pel_forward_vector = full_pel_forward_vector; p.forward_f_code = forward_f_code; p.full_pel_backward_vector = full_pel_backward_vector; p.backward_f_code = backward_f_code; return p; } private PictureHeader() { } public static PictureHeader read(ByteBuffer bb) { BitReader _in = BitReader.createBitReader(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 = BitReader.createBitReader(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); } } @Override public void write(ByteBuffer os) { 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); out.flush(); writeExtensions(os); } private void writeExtensions(ByteBuffer out) { if (quantMatrixExtension != null) { out.putInt(EXTENSION_START_CODE); quantMatrixExtension.write(out); } if (copyrightExtension != null) { out.putInt(EXTENSION_START_CODE); copyrightExtension.write(out); } if (pictureCodingExtension != null) { out.putInt(EXTENSION_START_CODE); pictureCodingExtension.write(out); } if (pictureDisplayExtension != null) { out.putInt(EXTENSION_START_CODE); pictureDisplayExtension.write(out); } if (pictureSpatialScalableExtension != null) { out.putInt(EXTENSION_START_CODE); pictureSpatialScalableExtension.write(out); } if (pictureTemporalScalableExtension != null) { out.putInt(EXTENSION_START_CODE); pictureTemporalScalableExtension.write(out); } } public boolean hasExtensions() { return _hasExtensions; } }