Exemplo n.º 1
0
        public void Read(BitReader bitReader)
        {
            FirstMBInSlice    = bitReader.DecodeUnsignedExpGolomb();
            SliceType         = ReadSliceType(bitReader);
            PICParameterSetID = bitReader.DecodeUnsignedExpGolomb();
            FrameNum          = bitReader.GetUIntFromNBits(_frameNumBits);

            if (!_sps.FrameMBSOnly)
            {
                FieldPicFlag = bitReader.GetNextBit();
                if (FieldPicFlag)
                {
                    BottomFieldFlag = bitReader.GetNextBit();
                }
            }

            if (_nalu.NALUType == NALUnitType.IDRSlice)
            {
                IDRPictureID    = bitReader.DecodeUnsignedExpGolomb();
                PrevRefFrameNum = 0;
            }

            if (_sps.gPicOrderCntType == 0)
            {
                PictureOrderCountLSB = bitReader.GetUIntFromNBits((ushort)(_sps.gMaxPicOrderCntLsbMinus4 + 4u));
                if (_pps.PICOrderPresentFlag && !FieldPicFlag)
                {
                    DeltaPictureOrderCountBottom = bitReader.DecodeSignedExpGolomb();
                }
            }

            if ((_sps.gPicOrderCntType == 1) && !_sps.DeltaPicOrderAlwaysZero)
            {
                DeltaPictureOrderCount    = new int[2];
                DeltaPictureOrderCount[0] = bitReader.DecodeSignedExpGolomb();
                if (_pps.PICOrderPresentFlag && !FieldPicFlag)
                {
                    DeltaPictureOrderCount[1] = bitReader.DecodeSignedExpGolomb();
                }
            }

            if (_pps.RedundantPICCountPresentFlag)
            {
                RedundantPictureCount = bitReader.DecodeUnsignedExpGolomb();
            }

            if (SliceType == SliceTypes.B)
            {
                DirectSpatialMVPredFlag = bitReader.GetNextBit();
            }

            if ((SliceType == SliceTypes.P) || (SliceType == SliceTypes.SP) || (SliceType == SliceTypes.B))
            {
                NumRefIdxActiveOverrideFlag = bitReader.GetNextBit();
                if (NumRefIdxActiveOverrideFlag)
                {
                    NumRefIdx10ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb();
                    if (SliceType == SliceTypes.B)
                    {
                        NumRefIdx11ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb();
                    }
                }
            }

            ReferencePictureListReordering(bitReader);

            if ((_pps.WeightedPredFlag && ((SliceType == SliceTypes.P) || (SliceType == SliceTypes.SP))) ||
                ((_pps.WeightedBiPredIDC == 1) && (SliceType == SliceTypes.B)))
            {
                PredictionWeightTable(bitReader);
            }

            if (_nalu.NALRefIDC != 0)
            {
                DecodedReferencePictureMarking(bitReader);
            }

            if (_pps.EntropyCodingModeFlag && (SliceType != SliceTypes.I) && (SliceType != SliceTypes.SI))
            {
                uint initIdc = bitReader.DecodeUnsignedExpGolomb();
                if (initIdc < 4)
                {
                    CABACInitIDC = (byte)initIdc;
                }
                else
                {
                    throw new Exception("SliceHeader: bad CABACInitIDC");
                }
            }

            SliceQPDelta = bitReader.DecodeSignedExpGolomb();
            SliceQPy     = 26 + _pps.PICInitQPMinus26 + SliceQPDelta;

            if ((SliceType == SliceTypes.SP) || (SliceType == SliceTypes.SI))
            {
                if (SliceType == SliceTypes.SP)
                {
                    SP4SwitchFlag = bitReader.GetNextBit();
                }
                SliceQSDelta = bitReader.DecodeSignedExpGolomb();
                SliceQSy     = 26 + _pps.PICInitQSMinus26 + SliceQSDelta;
            }

            if (_pps.DeblockingFilterControlPresentFlag)
            {
                DisableDeblockingFilterIDC = bitReader.DecodeUnsignedExpGolomb();
                if (DisableDeblockingFilterIDC != 1)
                {
                    SliceAlphaC0OffsetDiv2 = bitReader.DecodeSignedExpGolomb();
                    SliceBetaOffsetDiv2    = bitReader.DecodeSignedExpGolomb();
                }
            }

            if ((_pps.NumSliceGroupsMinus1 > 0) && (_pps.SliceGroupMapType >= 3) && (_pps.SliceGroupMapType <= 5))
            {
                SliceGroupChangeCycle = bitReader.GetUIntFromNBits(BitReader.CalcBitsNeededToRepresent(_pps.NumSliceGroupsMinus1 + 1));
            }

            // once the header is read, we can derive the MacroBlock to SliceGroup mapping (Section 8.2.2 of H264 Spec)
            if (_pps.NumSliceGroupsMinus1 > 0)
            {
                MbToSliceGroupMap = DeriveMB2SliceGroupMap();
            }
        }
Exemplo n.º 2
0
        public override void Read(BitReader bitReader)
        {
            base.Read(bitReader);

            PICParamSetID         = bitReader.DecodeUnsignedExpGolomb();
            SEQParamSetID         = bitReader.DecodeUnsignedExpGolomb();
            EntropyCodingModeFlag = bitReader.GetNextBit();
            PICOrderPresentFlag   = bitReader.GetNextBit();
            NumSliceGroupsMinus1  = bitReader.DecodeUnsignedExpGolomb();
            if (NumSliceGroupsMinus1 > 0)
            {
                SliceGroupMapType = bitReader.DecodeUnsignedExpGolomb();
                switch (SliceGroupMapType)
                {
                case 0:
                    RunLengthMinus1 = new uint[NumSliceGroupsMinus1 + 1];
                    for (int grp = 0; grp <= NumSliceGroupsMinus1; grp++)
                    {
                        RunLengthMinus1[grp] = bitReader.DecodeUnsignedExpGolomb();
                    }
                    break;

                case 1:
                    break;

                case 2:
                    TopLeft     = new uint[NumSliceGroupsMinus1 + 1];
                    BottomRight = new uint[NumSliceGroupsMinus1 + 1];
                    for (int grp = 0; grp <= NumSliceGroupsMinus1; grp++) // standards doc, this reads grp < NumSliceGroupsMinus1
                    {
                        TopLeft[grp]     = bitReader.DecodeUnsignedExpGolomb();
                        BottomRight[grp] = bitReader.DecodeUnsignedExpGolomb();
                    }
                    break;

                case 3:
                case 4:
                case 5:
                    SliceGroupChangeDirectionFlag = bitReader.GetNextBit();
                    SliceGroupChangeRateMinus1    = bitReader.DecodeUnsignedExpGolomb();
                    break;

                case 6:
                    PICSizeInMapUnitsMinus1 = bitReader.DecodeUnsignedExpGolomb();
                    SliceGroupID            = new uint[PICSizeInMapUnitsMinus1 + 1];
                    ushort bitCount = BitReader.CalcBitsNeededToRepresent(NumSliceGroupsMinus1 + 1);
                    for (int grp = 0; grp <= PICSizeInMapUnitsMinus1; grp++)
                    {
                        SliceGroupID[grp] = bitReader.GetUIntFromNBits(bitCount);
                    }
                    break;

                default:
                    throw new Exception("BitReader: bad slice group map type");
                }
            }
            NumRefIDx10ActiveMinus1            = bitReader.DecodeUnsignedExpGolomb();
            NumRefIDx11ActiveMinus1            = bitReader.DecodeUnsignedExpGolomb();
            WeightedPredFlag                   = bitReader.GetNextBit();
            WeightedBiPredIDC                  = (ushort)bitReader.GetUIntFromNBits(2);
            PICInitQPMinus26                   = bitReader.DecodeSignedExpGolomb();
            PICInitQSMinus26                   = bitReader.DecodeSignedExpGolomb();
            ChromaQPIndexOffset                = bitReader.DecodeSignedExpGolomb();
            DeblockingFilterControlPresentFlag = bitReader.GetNextBit();
            ConstrainedIntraPredFlag           = bitReader.GetNextBit();
            RedundantPICCountPresentFlag       = bitReader.GetNextBit();
            bitReader.DiscardTrailingBits();
        }