Пример #1
0
 private void mvZero(Context context, PictureHeader ph, MPEGPred pred, int mbX, int mbY, int[][] mbPix)
 {
     if (ph.picture_coding_type == PictureHeader.PredictiveCoded)
     {
         pred.predict16x16NoMV(refFrames[0], mbX << 4, mbY << 4, ph.pictureCodingExtension == null ? PictureCodingExtension.Frame
                 : ph.pictureCodingExtension.picture_structure, 0, mbPix);
     }
     else
     {
         int[][] pp = mbPix;
         if (context.lastPredB.macroblock_motion_backward == 1)
         {
             pred.predict16x16NoMV(refFrames[0], mbX << 4, mbY << 4, ph.pictureCodingExtension == null ? PictureCodingExtension.Frame
                     : ph.pictureCodingExtension.picture_structure, 1, pp);
             pp = new int[][] { new int[mbPix[0].Length], new int[mbPix[1].Length], new int[mbPix[2].Length] };
         }
         if (context.lastPredB.macroblock_motion_forward == 1)
         {
             pred.predict16x16NoMV(refFrames[1], mbX << 4, mbY << 4, ph.pictureCodingExtension == null ? PictureCodingExtension.Frame
                     : ph.pictureCodingExtension.picture_structure, 0, pp);
             if (mbPix != pp)
             {
                 avgPred(mbPix, pp);
             }
         }
     }
 }
Пример #2
0
        public void decodeSlice(PictureHeader ph, int verticalPos, Context context, int[][] buf, BitReader ing, int vertOff,
                                int vertStep)
        {
            int stride = context.codedWidth;

            resetDCPredictors(context, ph);

            int mbRow = verticalPos - 1;

            if (sh.vertical_size > 2800)
            {
                mbRow += (ing.readNBit(3) << 7);
            }
            if (sh.sequenceScalableExtension != null &&
                sh.sequenceScalableExtension.scalable_mode == SequenceScalableExtension.DATA_PARTITIONING)
            {
                int priorityBreakpoint = ing.readNBit(7);
            }
            int qScaleCode = ing.readNBit(5);

            if (ing.read1Bit() == 1)
            {
                int intraSlice = ing.read1Bit();
                ing.skip(7);
                while (ing.read1Bit() == 1)
                {
                    ing.readNBit(8);
                }
            }

            MPEGPred pred = new MPEGPred(ph.pictureCodingExtension != null ? ph.pictureCodingExtension.f_code
                    : new int[][] { new int[] { ph.forward_f_code, ph.forward_f_code },
                                    new int[] { ph.backward_f_code, ph.backward_f_code } },
                                         sh.sequenceExtension != null ? sh.sequenceExtension.chroma_format : SequenceExtension.Chroma420,
                                         ph.pictureCodingExtension != null && ph.pictureCodingExtension.top_field_first == 0 ? false : true);

            int[] ctx = new int[] { qScaleCode };

            for (int prevAddr = mbRow * context.mbWidth - 1; ing.checkNBit(23) != 0;)
            {
                // TODO: decode skipped!!!
                prevAddr = decodeMacroblock(ph, context, prevAddr, ctx, buf, stride, ing, vertOff, vertStep, pred);
                context.mbNo++;
            }
        }
Пример #3
0
        public int decodeMacroblock(PictureHeader ph, Context context, int prevAddr, int[] qScaleCode, int[][] buf,
                                    int stride, BitReader bits, int vertOff, int vertStep, MPEGPred pred)
        {
            int mbAddr = prevAddr;

            while (bits.checkNBit(11) == 0x8)
            {
                bits.skip(11);
                mbAddr += 33;
            }
            mbAddr += MPEGConst.vlcAddressIncrement.readVLC(bits) + 1;

            int chromaFormat = SequenceExtension.Chroma420;

            if (sh.sequenceExtension != null)
            {
                chromaFormat = sh.sequenceExtension.chroma_format;
            }

            for (int i = prevAddr + 1; i < mbAddr; i++)
            {
                int[][] predFwda = new int[][] { new int[256], new int[1 << (chromaFormat + 5)],
                                                 new int[1 << (chromaFormat + 5)] };
                int mbXa = i % context.mbWidth;
                int mbYa = i / context.mbWidth;
                if (ph.picture_coding_type == PictureHeader.PredictiveCoded)
                {
                    pred.reset();
                }
                mvZero(context, ph, pred, mbXa, mbYa, predFwda);
                put(predFwda, buf, stride, chromaFormat, mbXa, mbYa, context.codedWidth, context.codedHeight >> vertStep,
                    vertOff, vertStep);
            }

            VLC vlcMBTypea = MPEGConst.vlcMBType(ph.picture_coding_type, sh.sequenceScalableExtension);

            nVideo.Codecs.MPEG12.MPEGConst.MBType[] mbTypeVal = MPEGConst.mbTypeVal(ph.picture_coding_type, sh.sequenceScalableExtension);

            nVideo.Codecs.MPEG12.MPEGConst.MBType mbType = mbTypeVal[vlcMBTypea.readVLC(bits)];

            if (mbType.macroblock_intra != 1 || (mbAddr - prevAddr) > 1)
            {
                resetDCPredictors(context, ph);
            }

            int spatial_temporal_weight_code = 0;

            if (mbType.spatial_temporal_weight_code_flag == 1 && ph.pictureSpatialScalableExtension != null &&
                ph.pictureSpatialScalableExtension.spatial_temporal_weight_code_table_index != 0)
            {
                spatial_temporal_weight_code = bits.readNBit(2);
            }

            int motion_type = -1;

            if (mbType.macroblock_motion_forward != 0 || mbType.macroblock_motion_backward != 0)
            {
                if (ph.pictureCodingExtension == null || ph.pictureCodingExtension.picture_structure == PictureCodingExtension.Frame &&
                    ph.pictureCodingExtension.frame_pred_frame_dct == 1)
                {
                    motion_type = 2;
                }
                else
                {
                    motion_type = bits.readNBit(2);
                }
            }

            int dctType = 0;

            if (ph.pictureCodingExtension != null && ph.pictureCodingExtension.picture_structure == PictureCodingExtension.Frame &&
                ph.pictureCodingExtension.frame_pred_frame_dct == 0 &&
                (mbType.macroblock_intra != 0 || mbType.macroblock_pattern != 0))
            {
                dctType = bits.read1Bit();
            }
            // buf[3][mbAddr] = dctType;

            if (mbType.macroblock_quant != 0)
            {
                qScaleCode[0] = bits.readNBit(5);
            }
            bool concealmentMv = ph.pictureCodingExtension != null &&
                                 ph.pictureCodingExtension.concealment_motion_vectors != 0;

            int[][] predFwd = null;
            int     mbX     = mbAddr % context.mbWidth;
            int     mbY     = mbAddr / context.mbWidth;

            if (mbType.macroblock_intra == 1)
            {
                if (concealmentMv)
                {
                    // TODO read consealment vectors
                }
                else
                {
                    pred.reset();
                }
            }
            else if (mbType.macroblock_motion_forward != 0)
            {
                int refIdx = ph.picture_coding_type == PictureHeader.PredictiveCoded ? 0 : 1;
                predFwd = new int[][] { new int[256], new int[1 << (chromaFormat + 5)], new int[1 << (chromaFormat + 5)] };
                if (ph.pictureCodingExtension == null || ph.pictureCodingExtension.picture_structure == PictureCodingExtension.Frame)
                {
                    pred.predictInFrame(refFrames[refIdx], mbX << 4, mbY << 4, predFwd, bits, motion_type, 0,
                                        spatial_temporal_weight_code);
                }
                else
                {
                    if (ph.picture_coding_type == PictureHeader.PredictiveCoded)
                    {
                        pred.predictInField(refFields, mbX << 4, mbY << 4, predFwd, bits, motion_type, 0,
                                            ph.pictureCodingExtension.picture_structure - 1);
                    }
                    else
                    {
                        pred.predictInField(new Picture[] { refFrames[refIdx], refFrames[refIdx] }, mbX << 4, mbY << 4,
                                            predFwd, bits, motion_type, 0, ph.pictureCodingExtension.picture_structure - 1);
                    }
                }
            }
            else if (ph.picture_coding_type == PictureHeader.PredictiveCoded)
            {
                predFwd = new int[][] { new int[256], new int[1 << (chromaFormat + 5)], new int[1 << (chromaFormat + 5)] };
                pred.reset();
                mvZero(context, ph, pred, mbX, mbY, predFwd);
            }

            int[][] predBack = null;
            if (mbType.macroblock_motion_backward != 0)
            {
                predBack = new int[][] { new int[256], new int[1 << (chromaFormat + 5)], new int[1 << (chromaFormat + 5)] };
                if (ph.pictureCodingExtension == null || ph.pictureCodingExtension.picture_structure == PictureCodingExtension.Frame)
                {
                    pred.predictInFrame(refFrames[0], mbX << 4, mbY << 4, predBack, bits, motion_type, 1,
                                        spatial_temporal_weight_code);
                }
                else
                {
                    pred.predictInField(new Picture[] { refFrames[0], refFrames[0] }, mbX << 4, mbY << 4, predBack, bits,
                                        motion_type, 1, ph.pictureCodingExtension.picture_structure - 1);
                }
            }
            context.lastPredB = mbType;
            int[][] pp = mbType.macroblock_intra == 1 ? new int[][] { new int[256], new int[1 << (chromaFormat + 5)],
                                                                      new int[1 << (chromaFormat + 5)] } : buildPred(predFwd, predBack);

            //if (mbType.macroblock_intra != 0 && concealmentMv)
            //Assert.assertEquals(1, bits.read1Bit()); // Marker

            int cbp = mbType.macroblock_intra == 1 ? 0xfff : 0;

            if (mbType.macroblock_pattern != 0)
            {
                cbp = readCbPattern(bits);
            }

            VLC vlcCoeff = MPEGConst.vlcCoeff0;

            if (ph.pictureCodingExtension != null && mbType.macroblock_intra == 1 &&
                ph.pictureCodingExtension.intra_vlc_format == 1)
            {
                vlcCoeff = MPEGConst.vlcCoeff1;
            }

            int[] qScaleTab = ph.pictureCodingExtension != null && ph.pictureCodingExtension.q_scale_type == 1 ? MPEGConst.qScaleTab2
                    : MPEGConst.qScaleTab1;
            int qScale = qScaleTab[qScaleCode[0]];

            int intra_dc_mult = 8;

            if (ph.pictureCodingExtension != null)
            {
                intra_dc_mult = 8 >> ph.pictureCodingExtension.intra_dc_precision;
            }

            int blkCount = 6 + (chromaFormat == SequenceExtension.Chroma420 ? 0 : (chromaFormat == SequenceExtension.Chroma422 ? 2 : 6));

            int[] block = new int[64];
            //        System.out.print(mbAddr + ": ");
            for (int i = 0, cbpMask = 1 << (blkCount - 1); i < blkCount; i++, cbpMask >>= 1)
            {
                if ((cbp & cbpMask) == 0)
                {
                    continue;
                }
                int[] qmat = context.qMats[(i >= 4 ? 1 : 0) + (mbType.macroblock_intra << 1)];

                if (mbType.macroblock_intra == 1)
                {
                    blockIntra(bits, vlcCoeff, block, context.intra_dc_predictor, i, context.scan,
                               sh.hasExtensions() || ph.hasExtensions() ? 12 : 8, intra_dc_mult, qScale, qmat);
                }
                else
                {
                    blockInter(bits, vlcCoeff, block, context.scan,
                               sh.hasExtensions() || ph.hasExtensions() ? 12 : 8, qScale, qmat);
                }

                mapBlock(block, pp[MPEGConst.BLOCK_TO_CC[i]], i, dctType, chromaFormat);
            }

            put(pp, buf, stride, chromaFormat, mbX, mbY, context.codedWidth, context.codedHeight >> vertStep, vertOff,
                vertStep);

            return(mbAddr);
        }
Пример #4
0
 public MPEGPred(MPEGPred other)
 {
     this.fCode         = other.fCode;
     this.chromaFormat  = other.chromaFormat;
     this.topFieldFirst = other.topFieldFirst;
 }