public Picture decodePicture(Context context, PictureHeader ph, MemoryStream buffer, int[][] buf, int vertOff, int vertStep) { int planeSize = context.codedWidth * context.codedHeight; if (buf.Length < 3 || buf[0].Length < planeSize || buf[1].Length < planeSize || buf[2].Length < planeSize) { throw new Exception("ByteBuffer too small to hold output picture [" + context.codedWidth + "x" + context.codedHeight + "]"); } try { MemoryStream segment; while ((segment = MPEGUtil.nextSegment(buffer)) != null) { if (segment.get(3) >= MPEGConst.SLICE_START_CODE_FIRST && segment.get(3) <= MPEGConst.SLICE_START_CODE_LAST) { segment.position(4); try { decodeSlice(ph, segment.get(3) & 0xff, context, buf, new BitReader(segment), vertOff, vertStep); } catch (Exception e) { //e.printStackTrace(); } } else if (segment.get(3) >= 0xB3 && segment.get(3) != 0xB6 && segment.get(3) != 0xB7) { throw new Exception("Unexpected start code " + segment.get(3)); } else if (segment.get(3) == 0x0) { //buffer.reset(); break; } } Picture pic = new Picture(context.codedWidth, context.codedHeight, buf, context.color); if ((ph.picture_coding_type == PictureHeader.IntraCoded || ph.picture_coding_type == PictureHeader.PredictiveCoded) && ph.pictureCodingExtension != null && ph.pictureCodingExtension.picture_structure != PictureCodingExtension.Frame) { refFields[ph.pictureCodingExtension.picture_structure - 1] = copyAndCreateIfNeeded(pic, refFields[ph.pictureCodingExtension.picture_structure - 1]); } return(pic); } catch (IOException e) { throw e; } }
private PictureHeader readHeader(MemoryStream buffer) { PictureHeader ph = null; MemoryStream segment; MemoryStream fork = buffer.duplicate(); while ((segment = MPEGUtil.nextSegment(fork)) != null) { int code = segment.getInt() & 0xff; if (code == MPEGConst.SEQUENCE_HEADER_CODE) { SequenceHeader newSh = SequenceHeader.read(segment); if (sh != null) { newSh.copyExtensions(sh); } sh = newSh; } else if (code == MPEGConst.GROUP_START_CODE) { gh = GOPHeader.read(segment); } else if (code == MPEGConst.PICTURE_START_CODE) { ph = PictureHeader.read(segment); } else if (code == MPEGConst.EXTENSION_START_CODE) { int extType = segment.get(4) >> 4; if (extType == SequenceHeader.Sequence_Extension || extType == SequenceHeader.Sequence_Scalable_Extension || extType == SequenceHeader.Sequence_Display_Extension) { SequenceHeader.readExtension(segment, sh); } else { PictureHeader.readExtension(segment, ph, sh); } } else if (code == MPEGConst.USER_DATA_START_CODE) { // do nothing } else { break; } buffer.position(fork.position()); } return(ph); }
private static SequenceHeader getSequenceHeader(MemoryStream data) { MemoryStream segment = MPEGUtil.nextSegment(data); while (segment != null) { int marker = segment.getInt(); if (marker == (0x100 | MPEGConst.SEQUENCE_HEADER_CODE)) { return(SequenceHeader.read(segment)); } segment = MPEGUtil.nextSegment(data); } return(null); }