private void writeDecRefPicMarking(SliceHeader sliceHeader, bool idrSlice, BitWriter writer) { if (idrSlice) { RefPicMarkingIDR drpmidr = sliceHeader.refPicMarkingIDR; CAVLCWriter.writeBool(writer, drpmidr.isDiscardDecodedPics(), "SH: no_output_of_prior_pics_flag"); CAVLCWriter.writeBool(writer, drpmidr.isUseForlongTerm(), "SH: long_term_reference_flag"); } else { CAVLCWriter.writeBool(writer, sliceHeader.refPicMarkingNonIDR != null, "SH: adaptive_ref_pic_marking_mode_flag"); if (sliceHeader.refPicMarkingNonIDR != null) { RefPicMarking drpmidr = sliceHeader.refPicMarkingNonIDR; foreach (var mmop in drpmidr.getInstructions()) { switch (mmop.getType()) { case RefPicMarking.InstrType.REMOVE_SHORT: CAVLCWriter.writeUE(writer, 1, "SH: memory_management_control_operation"); CAVLCWriter.writeUE(writer, mmop.getArg1() - 1, "SH: difference_of_pic_nums_minus1"); break; case RefPicMarking.InstrType.REMOVE_LONG: CAVLCWriter.writeUE(writer, 2, "SH: memory_management_control_operation"); CAVLCWriter.writeUE(writer, mmop.getArg1(), "SH: long_term_pic_num"); break; case RefPicMarking.InstrType.CONVERT_INTO_LONG: CAVLCWriter.writeUE(writer, 3, "SH: memory_management_control_operation"); CAVLCWriter.writeUE(writer, mmop.getArg1() - 1, "SH: difference_of_pic_nums_minus1"); CAVLCWriter.writeUE(writer, mmop.getArg2(), "SH: long_term_frame_idx"); break; case RefPicMarking.InstrType.TRUNK_LONG: CAVLCWriter.writeUE(writer, 4, "SH: memory_management_control_operation"); CAVLCWriter.writeUE(writer, mmop.getArg1() + 1, "SH: max_long_term_frame_idx_plus1"); break; case RefPicMarking.InstrType.CLEAR: CAVLCWriter.writeUE(writer, 5, "SH: memory_management_control_operation"); break; case RefPicMarking.InstrType.MARK_LONG: CAVLCWriter.writeUE(writer, 6, "SH: memory_management_control_operation"); CAVLCWriter.writeUE(writer, mmop.getArg1(), "SH: long_term_frame_idx"); break; } } CAVLCWriter.writeUE(writer, 0, "SH: memory_management_control_operation"); } } }
public void performMarking(RefPicMarking refPicMarking, Frame picture) { Frame saved = saveRef(picture); if (refPicMarking != null) { foreach (var instr in refPicMarking.getInstructions()) { switch (instr.getType()) { case RefPicMarking.InstrType.REMOVE_SHORT: unrefShortTerm(instr.getArg1()); break; case RefPicMarking.InstrType.REMOVE_LONG: unrefLongTerm(instr.getArg1()); break; case RefPicMarking.InstrType.CONVERT_INTO_LONG: convert(instr.getArg1(), instr.getArg2()); break; case RefPicMarking.InstrType.TRUNK_LONG: truncateLongTerm(instr.getArg1() - 1); break; case RefPicMarking.InstrType.CLEAR: clearAll(); break; case RefPicMarking.InstrType.MARK_LONG: saveLong(saved, instr.getArg1()); saved = null; break; } } } if (saved != null) { saveShort(saved); } int maxFrames = 1 << (activeSps.log2_max_frame_num_minus4 + 4); if (refPicMarking == null) { int maxShort = Math.Max(1, activeSps.num_ref_frames - vdecoder.lRefs.Count()); int min = int.MaxValue, num = 0, minFn = 0; for (int i = 0; i < vdecoder.sRefs.Length; i++) { if (vdecoder.sRefs[i] != null) { int fnWrap = unwrap(firstSliceHeader.frame_num, vdecoder.sRefs[i].getFrameNo(), maxFrames); if (fnWrap < min) { min = fnWrap; minFn = vdecoder.sRefs[i].getFrameNo(); } num++; } } if (num > maxShort) { // System.out.println("Removing: " + minFn + ", POC: " + // sRefs[minFn].getPOC()); releaseRef(vdecoder.sRefs[minFn]); vdecoder.sRefs[minFn] = null; } } }