예제 #1
0
        private void writeOffsetWeight(SliceHeader sliceHeader, BitWriter writer, int list)
        {
            SeqParameterSet sps       = sliceHeader.sps;
            int             defaultLW = 1 << sliceHeader.pred_weight_table.luma_log2_weight_denom;
            int             defaultCW = 1 << sliceHeader.pred_weight_table.chroma_log2_weight_denom;

            for (int i = 0; i < sliceHeader.pred_weight_table.luma_weight[list].Length; i++)
            {
                bool flagLuma = sliceHeader.pred_weight_table.luma_weight[list][i] != defaultLW ||
                                sliceHeader.pred_weight_table.luma_offset[list][i] != 0;
                CAVLCWriter.writeBool(writer, flagLuma, "SH: luma_weight_l0_flag");
                if (flagLuma)
                {
                    CAVLCWriter.writeSE(writer, sliceHeader.pred_weight_table.luma_weight[list][i], "SH: luma_weight_l" + list);
                    CAVLCWriter.writeSE(writer, sliceHeader.pred_weight_table.luma_offset[list][i], "SH: luma_offset_l" + list);
                }
                if (sps.chroma_format_idc != ColorSpace.MONO)
                {
                    bool flagChroma = sliceHeader.pred_weight_table.chroma_weight[list][0][i] != defaultCW ||
                                      sliceHeader.pred_weight_table.chroma_offset[list][0][i] != 0 ||
                                      sliceHeader.pred_weight_table.chroma_weight[list][1][i] != defaultCW ||
                                      sliceHeader.pred_weight_table.chroma_offset[list][1][i] != 0;
                    CAVLCWriter.writeBool(writer, flagChroma, "SH: chroma_weight_l0_flag");
                    if (flagChroma)
                    {
                        for (int j = 0; j < 2; j++)
                        {
                            CAVLCWriter.writeSE(writer, sliceHeader.pred_weight_table.chroma_weight[list][j][i], "SH: chroma_weight_l" + list);
                            CAVLCWriter.writeSE(writer, sliceHeader.pred_weight_table.chroma_offset[list][j][i], "SH: chroma_offset_l" + list);
                        }
                    }
                }
            }
        }
예제 #2
0
            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));
            }
예제 #3
0
        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");
                }
            }
        }
예제 #4
0
            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));
            }
예제 #5
0
 private void writeRefPicListReordering(SliceHeader sliceHeader, BitWriter writer)
 {
     if (sliceHeader.slice_type.isInter())
     {
         CAVLCWriter.writeBool(writer, sliceHeader.refPicReordering[0] != null, "SH: ref_pic_list_reordering_flag_l0");
         writeReorderingList(sliceHeader.refPicReordering[0], writer);
     }
     if (sliceHeader.slice_type == SliceType.B)
     {
         CAVLCWriter.writeBool(writer, sliceHeader.refPicReordering[1] != null, "SH: ref_pic_list_reordering_flag_l1");
         writeReorderingList(sliceHeader.refPicReordering[1], writer);
     }
 }
예제 #6
0
        private void fillHorizontalEdge(Picture pic, int comp, int mbAddr, int[][] bs)
        {
            SliceHeader sh      = shs[mbAddr];
            int         mbWidth = sh.sps.pic_width_in_mbs_minus1 + 1;

            int alpha = sh.slice_alpha_c0_offset_div2 << 1;
            int beta  = sh.slice_beta_offset_div2 << 1;

            int mbX = mbAddr % mbWidth;
            int mbY = mbAddr / mbWidth;

            bool topAvailable = mbY > 0 && (sh.disable_deblocking_filter_idc != 2 || shs[mbAddr - mbWidth] == sh);
            int  curQp        = mbQps[comp][mbAddr];

            int cW = 2 - pic.getColor().compWidth[comp];
            int cH = 2 - pic.getColor().compHeight[comp];

            if (topAvailable)
            {
                int topQp = mbQps[comp][mbAddr - mbWidth];
                int avgQp = (topQp + curQp + 1) >> 1;
                for (int blkX = 0; blkX < 4; blkX++)
                {
                    int thisBlkX = (mbX << 2) + blkX;
                    int thisBlkY = (mbY << 2);

                    filterBlockEdgeHoris(pic, comp, thisBlkX << cW, thisBlkY << cH, getIdxAlpha(alpha, avgQp),
                                         getIdxBeta(beta, avgQp), bs[0][blkX], 1 << cW);
                }
            }

            bool skip4x4 = comp == 0 && tr8x8Used[mbAddr] || cH == 1;

            for (int blkY = 1; blkY < 4; blkY++)
            {
                if (skip4x4 && (blkY & 1) == 1)
                {
                    continue;
                }

                for (int blkX = 0; blkX < 4; blkX++)
                {
                    int thisBlkX = (mbX << 2) + blkX;
                    int thisBlkY = (mbY << 2) + blkY;

                    filterBlockEdgeHoris(pic, comp, thisBlkX << cW, thisBlkY << cH, getIdxAlpha(alpha, curQp),
                                         getIdxBeta(beta, curQp), bs[blkY][blkX], 1 << cW);
                }
            }
        }
예제 #7
0
        public SliceHeader readPart1(BitReader inb)
        {
            SliceHeader sh = new SliceHeader();

            sh.first_mb_in_slice = CAVLCReader.readUE(inb, "SH: first_mb_inb_slice");
            int sh_type = CAVLCReader.readUE(inb, "SH: slice_type");

            sh.slice_type       = (SliceType)(sh_type % 5);
            sh.slice_type_restr = (sh_type / 5) > 0;

            sh.pic_parameter_set_id = CAVLCReader.readUE(inb, "SH: pic_parameter_set_id");

            return(sh);
        }
예제 #8
0
 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);
 }
예제 #9
0
        private void writePredWeightTable(SliceHeader sliceHeader, BitWriter writer)
        {
            SeqParameterSet sps = sliceHeader.sps;

            CAVLCWriter.writeUE(writer, sliceHeader.pred_weight_table.luma_log2_weight_denom, "SH: luma_log2_weight_denom");
            if (sps.chroma_format_idc != ColorSpace.MONO)
            {
                CAVLCWriter.writeUE(writer, sliceHeader.pred_weight_table.chroma_log2_weight_denom, "SH: chroma_log2_weight_denom");
            }

            writeOffsetWeight(sliceHeader, writer, 0);
            if (sliceHeader.slice_type == SliceType.B)
            {
                writeOffsetWeight(sliceHeader, writer, 1);
            }
        }
예제 #10
0
        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!!!");
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
            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);
            }
예제 #13
0
 private static void readRefPicListReorderinbg(SliceHeader sh, BitReader inb)
 {
     sh.refPicReordering = new int[2][][];
     // System.out.println(i++);
     if (sh.slice_type.isInter())
     {
         bool ref_pic_list_reorderinbg_flag_l0 = CAVLCReader.readBool(inb, "SH: ref_pic_list_reorderinbg_flag_l0");
         if (ref_pic_list_reorderinbg_flag_l0)
         {
             sh.refPicReordering[0] = readReorderinbgEntries(inb);
         }
     }
     if (sh.slice_type == SliceType.B)
     {
         bool ref_pic_list_reorderinbg_flag_l1 = CAVLCReader.readBool(inb, "SH: ref_pic_list_reorderinbg_flag_l1");
         if (ref_pic_list_reorderinbg_flag_l1)
         {
             sh.refPicReordering[1] = readReorderinbgEntries(inb);
         }
     }
 }
예제 #14
0
        private void calcBsH(Picture pic, int mbAddr, int[][] bs)
        {
            SliceHeader sh      = shs[mbAddr];
            int         mbWidth = sh.sps.pic_width_in_mbs_minus1 + 1;

            int mbX = mbAddr % mbWidth;
            int mbY = mbAddr / mbWidth;

            bool topAvailable = mbY > 0 && (sh.disable_deblocking_filter_idc != 2 || shs[mbAddr - mbWidth] == sh);
            bool thisIntra    = mbTypes[mbAddr] != null && mbTypes[mbAddr].isIntra();

            if (topAvailable)
            {
                bool topIntra = mbTypes[mbAddr - mbWidth] != null && mbTypes[mbAddr - mbWidth].isIntra();
                for (int blkX = 0; blkX < 4; blkX++)
                {
                    int thisBlkX = (mbX << 2) + blkX;
                    int thisBlkY = (mbY << 2);

                    bs[0][blkX] = calcBoundaryStrenth(true, topIntra, thisIntra, nCoeff[thisBlkY][thisBlkX],
                                                      nCoeff[thisBlkY - 1][thisBlkX], mvs[0][thisBlkY][thisBlkX], mvs[0][thisBlkY - 1][thisBlkX],
                                                      mvs[1][thisBlkY][thisBlkX], mvs[1][thisBlkY - 1][thisBlkX], mbAddr, mbAddr - mbWidth);
                }
            }

            for (int blkY = 1; blkY < 4; blkY++)
            {
                for (int blkX = 0; blkX < 4; blkX++)
                {
                    int thisBlkX = (mbX << 2) + blkX;
                    int thisBlkY = (mbY << 2) + blkY;

                    bs[blkY][blkX] = calcBoundaryStrenth(false, thisIntra, thisIntra, nCoeff[thisBlkY][thisBlkX],
                                                         nCoeff[thisBlkY - 1][thisBlkX], mvs[0][thisBlkY][thisBlkX], mvs[0][thisBlkY - 1][thisBlkX],
                                                         mvs[1][thisBlkY][thisBlkX], mvs[1][thisBlkY - 1][thisBlkX], mbAddr, mbAddr);
                }
            }
        }
예제 #15
0
 private bool validSh(SliceHeader sh)
 {
     return(sh.first_mb_in_slice == 0 && sh.pic_parameter_set_id < 2);
 }
예제 #16
0
 public Prediction(SliceHeader sh)
 {
     this.sh = sh;
 }
예제 #17
0
        private static void readPredWeightTable(SeqParameterSet sps, PictureParameterSet pps, SliceHeader sh, BitReader inb)
        {
            sh.pred_weight_table = new PredictionWeightTable();
            int[] numRefsminus1 = sh.num_ref_idx_active_override_flag ? sh.num_ref_idx_active_minus1
                    : pps.num_ref_idx_active_minus1;
            int[] nr = new int[] { numRefsminus1[0] + 1, numRefsminus1[1] + 1 };

            sh.pred_weight_table.luma_log2_weight_denom = CAVLCReader.readUE(inb, "SH: luma_log2_weight_denom");
            if (sps.chroma_format_idc != ColorSpace.MONO)
            {
                sh.pred_weight_table.chroma_log2_weight_denom = CAVLCReader.readUE(inb, "SH: chroma_log2_weight_denom");
            }
            int defaultLW = 1 << sh.pred_weight_table.luma_log2_weight_denom;
            int defaultCW = 1 << sh.pred_weight_table.chroma_log2_weight_denom;

            for (int list = 0; list < 2; list++)
            {
                sh.pred_weight_table.luma_weight[list]   = new int[nr[list]];
                sh.pred_weight_table.luma_offset[list]   = new int[nr[list]];
                sh.pred_weight_table.chroma_weight[list] = (int[][])System.Array.CreateInstance(typeof(int), new int[] { 2, nr[list] });
                sh.pred_weight_table.chroma_offset[list] = (int[][])System.Array.CreateInstance(typeof(int), new int[] { 2, nr[list] });
                for (int i = 0; i < nr[list]; i++)
                {
                    sh.pred_weight_table.luma_weight[list][i]      = defaultLW;
                    sh.pred_weight_table.luma_offset[list][i]      = 0;
                    sh.pred_weight_table.chroma_weight[list][0][i] = defaultCW;
                    sh.pred_weight_table.chroma_offset[list][0][i] = 0;
                    sh.pred_weight_table.chroma_weight[list][1][i] = defaultCW;
                    sh.pred_weight_table.chroma_offset[list][1][i] = 0;
                }
            }

            readWeightOffset(sps, pps, sh, inb, nr, 0);
            if (sh.slice_type == SliceType.B)
            {
                readWeightOffset(sps, pps, sh, inb, nr, 1);
            }
        }
예제 #18
0
 private int calcPOC1(SliceHeader firstSliceHeader, NALUnit firstNu)
 {
     return(firstSliceHeader.frame_num << 1);
 }
예제 #19
0
 private static void readWeightOffset(SeqParameterSet sps, PictureParameterSet pps, SliceHeader sh, BitReader inb,
                                      int[] numRefs, int list)
 {
     for (int i = 0; i < numRefs[list]; i++)
     {
         bool luma_weight_l0_flag = CAVLCReader.readBool(inb, "SH: luma_weight_l0_flag");
         if (luma_weight_l0_flag)
         {
             sh.pred_weight_table.luma_weight[list][i] = CAVLCReader.readSE(inb, "SH: weight");
             sh.pred_weight_table.luma_offset[list][i] = CAVLCReader.readSE(inb, "SH: offset");
         }
         if (sps.chroma_format_idc != ColorSpace.MONO)
         {
             bool chroma_weight_l0_flag = CAVLCReader.readBool(inb, "SH: chroma_weight_l0_flag");
             if (chroma_weight_l0_flag)
             {
                 sh.pred_weight_table.chroma_weight[list][0][i] = CAVLCReader.readSE(inb, "SH: weight");
                 sh.pred_weight_table.chroma_offset[list][0][i] = CAVLCReader.readSE(inb, "SH: offset");
                 sh.pred_weight_table.chroma_weight[list][1][i] = CAVLCReader.readSE(inb, "SH: weight");
                 sh.pred_weight_table.chroma_offset[list][1][i] = CAVLCReader.readSE(inb, "SH: offset");
             }
         }
     }
 }
예제 #20
0
        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);
        }
예제 #21
0
        // 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());
                }
            }
        }
예제 #22
0
 protected abstract void tweak(SliceHeader sh);
예제 #23
0
        public void write(SliceHeader sliceHeader, bool idrSlice, int nalRefIdc, BitWriter writer)
        {
            SeqParameterSet     sps = sliceHeader.sps;
            PictureParameterSet pps = sliceHeader.pps;

            CAVLCWriter.writeUE(writer, sliceHeader.first_mb_in_slice, "SH: first_mb_in_slice");
            CAVLCWriter.writeUE(writer, (int)sliceHeader.slice_type + (sliceHeader.slice_type_restr ? 5 : 0), "SH: slice_type");
            CAVLCWriter.writeUE(writer, sliceHeader.pic_parameter_set_id, "SH: pic_parameter_set_id");
            CAVLCWriter.writeU(writer, sliceHeader.frame_num, sps.log2_max_frame_num_minus4 + 4, "SH: frame_num");
            if (!sps.frame_mbs_only_flag)
            {
                CAVLCWriter.writeBool(writer, sliceHeader.field_pic_flag, "SH: field_pic_flag");
                if (sliceHeader.field_pic_flag)
                {
                    CAVLCWriter.writeBool(writer, sliceHeader.bottom_field_flag, "SH: bottom_field_flag");
                }
            }
            if (idrSlice)
            {
                CAVLCWriter.writeUE(writer, sliceHeader.idr_pic_id, "SH: idr_pic_id");
            }
            if (sps.pic_order_cnt_type == 0)
            {
                CAVLCWriter.writeU(writer, sliceHeader.pic_order_cnt_lsb, sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
                if (pps.pic_order_present_flag && !sps.field_pic_flag)
                {
                    CAVLCWriter.writeSE(writer, sliceHeader.delta_pic_order_cnt_bottom, "SH: delta_pic_order_cnt_bottom");
                }
            }
            if (sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag)
            {
                CAVLCWriter.writeSE(writer, sliceHeader.delta_pic_order_cnt[0], "SH: delta_pic_order_cnt");
                if (pps.pic_order_present_flag && !sps.field_pic_flag)
                {
                    CAVLCWriter.writeSE(writer, sliceHeader.delta_pic_order_cnt[1], "SH: delta_pic_order_cnt");
                }
            }
            if (pps.redundant_pic_cnt_present_flag)
            {
                CAVLCWriter.writeUE(writer, sliceHeader.redundant_pic_cnt, "SH: redundant_pic_cnt");
            }
            if (sliceHeader.slice_type == SliceType.B)
            {
                CAVLCWriter.writeBool(writer, sliceHeader.direct_spatial_mv_pred_flag, "SH: direct_spatial_mv_pred_flag");
            }
            if (sliceHeader.slice_type == SliceType.P || sliceHeader.slice_type == SliceType.SP ||
                sliceHeader.slice_type == SliceType.B)
            {
                CAVLCWriter.writeBool(writer, sliceHeader.num_ref_idx_active_override_flag, "SH: num_ref_idx_active_override_flag");
                if (sliceHeader.num_ref_idx_active_override_flag)
                {
                    CAVLCWriter.writeUE(writer, sliceHeader.num_ref_idx_active_minus1[0], "SH: num_ref_idx_l0_active_minus1");
                    if (sliceHeader.slice_type == SliceType.B)
                    {
                        CAVLCWriter.writeUE(writer, sliceHeader.num_ref_idx_active_minus1[1], "SH: num_ref_idx_l1_active_minus1");
                    }
                }
            }
            writeRefPicListReordering(sliceHeader, writer);
            if ((pps.weighted_pred_flag && (sliceHeader.slice_type == SliceType.P || sliceHeader.slice_type == SliceType.SP)) ||
                (pps.weighted_bipred_idc == 1 && sliceHeader.slice_type == SliceType.B))
            {
                writePredWeightTable(sliceHeader, writer);
            }
            if (nalRefIdc != 0)
            {
                writeDecRefPicMarking(sliceHeader, idrSlice, writer);
            }
            if (pps.entropy_coding_mode_flag && sliceHeader.slice_type.isInter())
            {
                CAVLCWriter.writeUE(writer, sliceHeader.cabac_init_idc, "SH: cabac_init_idc");
            }
            CAVLCWriter.writeSE(writer, sliceHeader.slice_qp_delta, "SH: slice_qp_delta");
            if (sliceHeader.slice_type == SliceType.SP || sliceHeader.slice_type == SliceType.SI)
            {
                if (sliceHeader.slice_type == SliceType.SP)
                {
                    CAVLCWriter.writeBool(writer, sliceHeader.sp_for_switch_flag, "SH: sp_for_switch_flag");
                }
                CAVLCWriter.writeSE(writer, sliceHeader.slice_qs_delta, "SH: slice_qs_delta");
            }
            if (pps.deblocking_filter_control_present_flag)
            {
                CAVLCWriter.writeUE(writer, sliceHeader.disable_deblocking_filter_idc, "SH: disable_deblocking_filter_idc");
                if (sliceHeader.disable_deblocking_filter_idc != 1)
                {
                    CAVLCWriter.writeSE(writer, sliceHeader.slice_alpha_c0_offset_div2, "SH: slice_alpha_c0_offset_div2");
                    CAVLCWriter.writeSE(writer, sliceHeader.slice_beta_offset_div2, "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 = (sps.pic_height_in_map_units_minus1 + 1) * (sps.pic_width_in_mbs_minus1 + 1)
                          / (pps.slice_group_change_rate_minus1 + 1);
                if (((sps.pic_height_in_map_units_minus1 + 1) * (sps.pic_width_in_mbs_minus1 + 1))
                    % (pps.slice_group_change_rate_minus1 + 1) > 0)
                {
                    len += 1;
                }

                len = CeilLog2(len + 1);
                CAVLCWriter.writeU(writer, sliceHeader.slice_group_change_cycle, len);
            }
        }
예제 #24
0
            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);
            }