/** * Wipes AVC parameter sets ( SPS/PPS ) from the packet ( inplace operation * ) * * @param in * AVC frame encoded in Annex B NAL unit format * @param spsList * Storage for leading SPS structures ( can be null, then all * leading SPSs are discarded ). * @param ppsList * Storage for leading PPS structures ( can be null, then all * leading PPSs are discarded ). */ public static void wipePS(System.IO.MemoryStream inb, List <System.IO.MemoryStream> spsList, List <System.IO.MemoryStream> ppsList) { System.IO.MemoryStream dup = inb.duplicate(); while (dup.hasRemaining()) { System.IO.MemoryStream buf = nextNALUnit(dup); if (buf == null) { break; } NALUnit nu = NALUnit.read(buf); if (nu.type == NALUnitType.PPS) { if (ppsList != null) { ppsList.Add(buf); } inb.position(dup.Position); } else if (nu.type == NALUnitType.SPS) { if (spsList != null) { spsList.Add(buf); } inb.position(dup.Position); } else if (nu.type == NALUnitType.IDR_SLICE || nu.type == NALUnitType.NON_IDR_SLICE) { break; } } }
/** * Wipes AVC parameter sets ( SPS/PPS ) from the packet * * @param in * AVC frame encoded in Annex B NAL unit format * @param out * Buffer where packet without PS will be put * @param spsList * Storage for leading SPS structures ( can be null, then all * leading SPSs are discarded ). * @param ppsList * Storage for leading PPS structures ( can be null, then all * leading PPSs are discarded ). */ public static void wipePS(System.IO.MemoryStream inb, System.IO.MemoryStream outb, List <System.IO.MemoryStream> spsList, List <System.IO.MemoryStream> ppsList) { System.IO.MemoryStream dup = inb.duplicate(); while (dup.hasRemaining()) { System.IO.MemoryStream buf = nextNALUnit(dup); if (buf == null) { break; } NALUnit nu = NALUnit.read(buf.duplicate()); if (nu.type == NALUnitType.PPS) { if (ppsList != null) { ppsList.Add(buf); } } else if (nu.type == NALUnitType.SPS) { if (spsList != null) { spsList.Add(buf); } } else { outb.putInt(1); outb.put(buf); } } outb.flip(); }
public override int probe(MemoryStream data) { bool avalidSps = false, avalidPps = false, avalidSh = false; foreach (var nalUnit in Utility.splitFrame(data.duplicate())) { NALUnit marker = NALUnit.read(nalUnit); if (marker.type == NALUnitType.IDR_SLICE || marker.type == NALUnitType.NON_IDR_SLICE) { BitReader reader = new BitReader(nalUnit); avalidSh = validSh(new SliceHeaderReader().readPart1(reader)); break; } else if (marker.type == NALUnitType.SPS) { avalidSps = validSps(SeqParameterSet.read(nalUnit)); } else if (marker.type == NALUnitType.PPS) { avalidPps = validPps(PictureParameterSet.read(nalUnit)); } } return((avalidSh ? 60 : 0) + (avalidSps ? 20 : 0) + (avalidPps ? 20 : 0)); }
public void writeUnit(NALUnit nal, MemoryStream data) { MemoryStream empreva = new MemoryStream(data.remaining() + 1024); empreva.Write(_MARKER, 0, 4); nal.write(empreva); emprev(empreva, data); empreva.flip(); empreva.WriteTo(to); }
public static bool idrSlice(IEnumerable <MemoryStream> _data) { foreach (var segment in _data) { if (NALUnit.read(segment.duplicate()).type == NALUnitType.IDR_SLICE) { return(true); } } return(false); }
public static bool idrSlice(System.IO.MemoryStream _data) { System.IO.MemoryStream data = _data.duplicate(); System.IO.MemoryStream segment; while ((segment = nextNALUnit(data)) != null) { if (NALUnit.read(segment).type == NALUnitType.IDR_SLICE) { return(true); } } return(false); }
private bool hasMMCO5(SliceHeader firstSliceHeader, NALUnit firstNu) { if (firstNu.type != NALUnitType.IDR_SLICE && firstSliceHeader.refPicMarkingNonIDR != null) { nVideo.Codecs.H264.RefPicMarking.Instruction[] instructions = firstSliceHeader.refPicMarkingNonIDR.getInstructions(); foreach (var instruction in instructions) { if (instruction.getType() == nVideo.Codecs.H264.RefPicMarking.InstrType.CLEAR) { return(true); } } } return(false); }
public int calcPOC(SliceHeader firstSliceHeader, NALUnit firstNu) { switch (firstSliceHeader.sps.pic_order_cnt_type) { case 0: return(calcPOC0(firstSliceHeader, firstNu)); case 1: return(calcPOC1(firstSliceHeader, firstNu)); case 2: return(calcPOC2(firstSliceHeader, firstNu)); default: throw new Exception("POC no!!!"); } }
private int calcPOC0(SliceHeader firstSliceHeader, NALUnit firstNu) { if (firstNu.type == NALUnitType.IDR_SLICE) { prevPOCMsb = prevPOCLsb = 0; } int maxPOCLsbDiv2 = 1 << (firstSliceHeader.sps.log2_max_pic_order_cnt_lsb_minus4 + 3), maxPOCLsb = maxPOCLsbDiv2 << 1; int POCLsb = firstSliceHeader.pic_order_cnt_lsb; int POCMsb, POC; if ((POCLsb < prevPOCLsb) && ((prevPOCLsb - POCLsb) >= maxPOCLsbDiv2)) { POCMsb = prevPOCMsb + maxPOCLsb; } else if ((POCLsb > prevPOCLsb) && ((POCLsb - prevPOCLsb) > maxPOCLsbDiv2)) { POCMsb = prevPOCMsb - maxPOCLsb; } else { POCMsb = prevPOCMsb; } POC = POCMsb + POCLsb; if (firstNu.nal_ref_idc > 0) { if (hasMMCO5(firstSliceHeader, firstNu)) { prevPOCMsb = 0; prevPOCLsb = POC; } else { prevPOCMsb = POCMsb; prevPOCLsb = POCLsb; } } return(POC); }
public Frame decodeFrame(List <MemoryStream> nalUnits, int[][] buffer) { Frame result = null; foreach (var nalUnit in nalUnits) { NALUnit marker = NALUnit.read(nalUnit); Utility.unescapeNAL(nalUnit); switch (marker.type.getValue()) { case 1: case 5: if (result == null) { result = init(buffer, nalUnit, marker); } decoder.decode(nalUnit, marker); break; case 8: SeqParameterSet _sps = SeqParameterSet.read(nalUnit); vdecoder.sps.Add(_sps.seq_parameter_set_id, _sps); break; case 7: PictureParameterSet _pps = PictureParameterSet.read(nalUnit); vdecoder.pps.Add(_pps.pic_parameter_set_id, _pps); break; default: break; } } filter.deblockFrame(result); updateReferences(result); return(result); }
private Frame init(int[][] buffer, MemoryStream segment, NALUnit marker) { firstNu = marker; shr = new SliceHeaderReader(); BitReader br = new BitReader(segment.duplicate()); firstSliceHeader = shr.readPart1(br); activePps = vdecoder.pps[firstSliceHeader.pic_parameter_set_id]; activeSps = vdecoder.sps[activePps.seq_parameter_set_id]; shr.readPart2(firstSliceHeader, marker, activeSps, activePps, br); int picWidthInMbs = activeSps.pic_width_in_mbs_minus1 + 1; int picHeightInMbs = Utility.getPicHeightInMbs(activeSps); int[][] nCoeff = (int[][])Array.CreateInstance(typeof(int), new int[] { picHeightInMbs << 2, picWidthInMbs << 2 }); //new int[picHeightInMbs << 2][picWidthInMbs << 2]; mvs = (int[][][][])Array.CreateInstance(typeof(int), new int[] { 2, picHeightInMbs << 2, picWidthInMbs << 2, 3 }); //new int[2][picHeightInMbs << 2][picWidthInMbs << 2][3]; MBType[] mbTypes = new MBType[picHeightInMbs * picWidthInMbs]; bool[] tr8x8Used = new bool[picHeightInMbs * picWidthInMbs]; int[][] mbQps = (int[][])Array.CreateInstance(typeof(int), new int[] { 3, picHeightInMbs * picWidthInMbs });//new int[3][picHeightInMbs * picWidthInMbs]; SliceHeader[] shs = new SliceHeader[picHeightInMbs * picWidthInMbs]; Frame[][][] refsUsed = new Frame[picHeightInMbs * picWidthInMbs][][]; if (vdecoder.sRefs == null) { vdecoder.sRefs = new Frame[1 << (firstSliceHeader.sps.log2_max_frame_num_minus4 + 4)]; vdecoder.lRefs = new Dictionary <int, Frame>(); } Frame result = createFrame(activeSps, buffer, firstSliceHeader.frame_num, mvs, refsUsed, vdecoder.poc.calcPOC(firstSliceHeader, firstNu)); decoder = new SliceDecoder(activeSps, activePps, nCoeff, mvs, mbTypes, mbQps, shs, tr8x8Used, refsUsed, result, vdecoder.sRefs, vdecoder.lRefs); decoder.setDebug(vdecoder.debug); filter = new DeblockingFilter(picWidthInMbs, activeSps.bit_depth_chroma_minus8 + 8, nCoeff, mvs, mbTypes, mbQps, shs, tr8x8Used, refsUsed); return(result); }
private int calcPOC1(SliceHeader firstSliceHeader, NALUnit firstNu) { return(firstSliceHeader.frame_num << 1); }
public SliceHeader readPart2(SliceHeader sh, NALUnit nalUnit, SeqParameterSet sps, PictureParameterSet pps, BitReader inb) { sh.pps = pps; sh.sps = sps; sh.frame_num = CAVLCReader.readU(inb, sps.log2_max_frame_num_minus4 + 4, "SH: frame_num"); if (!sps.frame_mbs_only_flag) { sh.field_pic_flag = CAVLCReader.readBool(inb, "SH: field_pic_flag"); if (sh.field_pic_flag) { sh.bottom_field_flag = CAVLCReader.readBool(inb, "SH: bottom_field_flag"); } } if (nalUnit.type == NALUnitType.IDR_SLICE) { sh.idr_pic_id = CAVLCReader.readUE(inb, "SH: idr_pic_id"); } if (sps.pic_order_cnt_type == 0) { sh.pic_order_cnt_lsb = CAVLCReader.readU(inb, sps.log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb"); if (pps.pic_order_present_flag && !sps.field_pic_flag) { sh.delta_pic_order_cnt_bottom = CAVLCReader.readSE(inb, "SH: delta_pic_order_cnt_bottom"); } } sh.delta_pic_order_cnt = new int[2]; if (sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag) { sh.delta_pic_order_cnt[0] = CAVLCReader.readSE(inb, "SH: delta_pic_order_cnt[0]"); if (pps.pic_order_present_flag && !sps.field_pic_flag) { sh.delta_pic_order_cnt[1] = CAVLCReader.readSE(inb, "SH: delta_pic_order_cnt[1]"); } } if (pps.redundant_pic_cnt_present_flag) { sh.redundant_pic_cnt = CAVLCReader.readUE(inb, "SH: redundant_pic_cnt"); } if (sh.slice_type == SliceType.B) { sh.direct_spatial_mv_pred_flag = CAVLCReader.readBool(inb, "SH: direct_spatial_mv_pred_flag"); } if (sh.slice_type == SliceType.P || sh.slice_type == SliceType.SP || sh.slice_type == SliceType.B) { sh.num_ref_idx_active_override_flag = CAVLCReader.readBool(inb, "SH: num_ref_idx_active_override_flag"); if (sh.num_ref_idx_active_override_flag) { sh.num_ref_idx_active_minus1[0] = CAVLCReader.readUE(inb, "SH: num_ref_idx_l0_active_minus1"); if (sh.slice_type == SliceType.B) { sh.num_ref_idx_active_minus1[1] = CAVLCReader.readUE(inb, "SH: num_ref_idx_l1_active_minus1"); } } } readRefPicListReorderinbg(sh, inb); if ((pps.weighted_pred_flag && (sh.slice_type == SliceType.P || sh.slice_type == SliceType.SP)) || (pps.weighted_bipred_idc == 1 && sh.slice_type == SliceType.B)) { readPredWeightTable(sps, pps, sh, inb); } if (nalUnit.nal_ref_idc != 0) { readDecoderPicMarkinbg(nalUnit, sh, inb); } if (pps.entropy_coding_mode_flag && sh.slice_type.isInter()) { sh.cabac_init_idc = CAVLCReader.readUE(inb, "SH: cabac_inbit_idc"); } sh.slice_qp_delta = CAVLCReader.readSE(inb, "SH: slice_qp_delta"); if (sh.slice_type == SliceType.SP || sh.slice_type == SliceType.SI) { if (sh.slice_type == SliceType.SP) { sh.sp_for_switch_flag = CAVLCReader.readBool(inb, "SH: sp_for_switch_flag"); } sh.slice_qs_delta = CAVLCReader.readSE(inb, "SH: slice_qs_delta"); } if (pps.deblocking_filter_control_present_flag) { sh.disable_deblocking_filter_idc = CAVLCReader.readUE(inb, "SH: disable_deblockinbg_filter_idc"); if (sh.disable_deblocking_filter_idc != 1) { sh.slice_alpha_c0_offset_div2 = CAVLCReader.readSE(inb, "SH: slice_alpha_c0_offset_div2"); sh.slice_beta_offset_div2 = CAVLCReader.readSE(inb, "SH: slice_beta_offset_div2"); } } if (pps.num_slice_groups_minus1 > 0 && pps.slice_group_map_type >= 3 && pps.slice_group_map_type <= 5) { int len = Utility.getPicHeightInMbs(sps) * (sps.pic_width_in_mbs_minus1 + 1) / (pps.slice_group_change_rate_minus1 + 1); if ((Utility.getPicHeightInMbs(sps) * (sps.pic_width_in_mbs_minus1 + 1)) % (pps.slice_group_change_rate_minus1 + 1) > 0) { len += 1; } len = CeilLog2(len + 1); sh.slice_group_change_cycle = CAVLCReader.readU(inb, len, "SH: slice_group_change_cycle"); } return(sh); }
public SliceHeader run(System.IO.MemoryStream iss, System.IO.MemoryStream os, NALUnit nu, SeqParameterSet sps, PictureParameterSet pps) { System.IO.MemoryStream nal = os.duplicate(); Utility.unescapeNAL(iss); BitReader reader = new BitReader(iss); SliceHeader sh = shr.readPart1(reader); return(part2(iss, os, nu, sps, pps, nal, reader, sh)); }
public SliceHeader run(System.IO.MemoryStream iss, System.IO.MemoryStream os, NALUnit nu) { System.IO.MemoryStream nal = os.duplicate(); Utility.unescapeNAL(iss); BitReader reader = new BitReader(iss); SliceHeader sh = shr.readPart1(reader); PictureParameterSet pp = findPPS(pps, sh.pic_parameter_set_id); return(part2(iss, os, nu, findSPS(sps, pp.pic_parameter_set_id), pp, nal, reader, sh)); }
private SliceHeader part2(System.IO.MemoryStream iss, System.IO.MemoryStream os, NALUnit nu, SeqParameterSet sps, PictureParameterSet pps, System.IO.MemoryStream nal, BitReader reader, SliceHeader sh) { BitWriter writer = new BitWriter(os); shr.readPart2(sh, nu, sps, pps, reader); tweak(sh); shw.write(sh, nu.type == NALUnitType.IDR_SLICE, nu.nal_ref_idc, writer); if (pps.entropy_coding_mode_flag) { copyDataCABAC(iss, os, reader, writer); } else { copyDataCAVLC(iss, os, reader, writer); } nal.limit(os.Position); Utility.escapeNAL(nal); os.position(nal.limit()); return(sh); }
// static int i = 0; private static void readDecoderPicMarkinbg(NALUnit nalUnit, SliceHeader sh, BitReader inb) { if (nalUnit.type == NALUnitType.IDR_SLICE) { bool no_output_of_prior_pics_flag = CAVLCReader.readBool(inb, "SH: no_output_of_prior_pics_flag"); bool long_term_reference_flag = CAVLCReader.readBool(inb, "SH: long_term_reference_flag"); sh.refPicMarkingIDR = new nVideo.Codecs.H264.RefPicMarkingIDR(no_output_of_prior_pics_flag, long_term_reference_flag); } else { bool adaptive_ref_pic_markinbg_mode_flag = CAVLCReader.readBool(inb, "SH: adaptive_ref_pic_markinbg_mode_flag"); if (adaptive_ref_pic_markinbg_mode_flag) { List <nVideo.Codecs.H264.RefPicMarking.Instruction> mmops = new List <nVideo.Codecs.H264.RefPicMarking.Instruction>(); int memory_management_control_operation; do { memory_management_control_operation = CAVLCReader.readUE(inb, "SH: memory_management_control_operation"); nVideo.Codecs.H264.RefPicMarking.Instruction inbstr = null; switch (memory_management_control_operation) { case 1: inbstr = new nVideo.Codecs.H264.RefPicMarking.Instruction(nVideo.Codecs.H264.RefPicMarking.InstrType.REMOVE_SHORT, CAVLCReader.readUE(inb, "SH: difference_of_pic_nums_minus1") + 1, 0); break; case 2: inbstr = new nVideo.Codecs.H264.RefPicMarking.Instruction(nVideo.Codecs.H264.RefPicMarking.InstrType.REMOVE_LONG, CAVLCReader.readUE(inb, "SH: long_term_pic_num"), 0); break; case 3: inbstr = new nVideo.Codecs.H264.RefPicMarking.Instruction(nVideo.Codecs.H264.RefPicMarking.InstrType.CONVERT_INTO_LONG, CAVLCReader.readUE(inb, "SH: difference_of_pic_nums_minus1") + 1, CAVLCReader.readUE(inb, "SH: long_term_frame_idx")); break; case 4: inbstr = new nVideo.Codecs.H264.RefPicMarking.Instruction(nVideo.Codecs.H264.RefPicMarking.InstrType.TRUNK_LONG, CAVLCReader.readUE(inb, "SH: max_long_term_frame_idx_plus1") - 1, 0); break; case 5: inbstr = new nVideo.Codecs.H264.RefPicMarking.Instruction(nVideo.Codecs.H264.RefPicMarking.InstrType.CLEAR, 0, 0); break; case 6: inbstr = new nVideo.Codecs.H264.RefPicMarking.Instruction(nVideo.Codecs.H264.RefPicMarking.InstrType.MARK_LONG, CAVLCReader.readUE(inb, "SH: long_term_frame_idx"), 0); break; } if (inbstr != null) { mmops.Add(inbstr); } } while (memory_management_control_operation != 0); sh.refPicMarkingNonIDR = new RefPicMarking(mmops.ToArray()); } } }