private void GetMotionVector(MotionField motionField, MacroblockPartition mbPart)
        {
#if DEBUG
            int dmvx = 0, dmvy = 0;
#endif
            if (_arithmeticDecoder.DecodeDecision(40 + motionField.GetCtxIdxInc(_currMbAddr, mbPart, 0)) == 1)
            {
                uint dx = GetAbsMotionVectorComponent(40);                 // dx coordinate?
                motionField.UpdateComponent(_currMbAddr, mbPart, 0, dx);
#if DEBUG
                dmvx = (_arithmeticDecoder.DecodeBypass() == 1) ? -(int)dx : (int)dx; // sign?
#else
                _arithmeticDecoder.DecodeBypass();                                    // sign
#endif
            }
            if (_arithmeticDecoder.DecodeDecision(47 + motionField.GetCtxIdxInc(_currMbAddr, mbPart, 1)) == 1)
            {
                uint dy = GetAbsMotionVectorComponent(47);                 // dy coordinate?
                motionField.UpdateComponent(_currMbAddr, mbPart, 1, dy);
#if DEBUG
                dmvy = (_arithmeticDecoder.DecodeBypass() == 1) ? -(int)dy : (int)dy; // sign?
#else
                _arithmeticDecoder.DecodeBypass();                                    // sign
#endif
            }
#if DEBUG
            H264Debug.WriteLine("   dmv={0},{1}", dmvx, dmvy);
#endif
        }
        // 9.3.3.1.1.7 Derivation process of ctxIdxInc for the syntax elements mvd_l0 and mvd_l1
        public uint GetCtxIdxInc(uint mbAddr, MacroblockPartition mbPart, uint compIdx)
        {
            uint absMvdCompA;

            if (mbPart.SubMbPartIdxA < 16)
            {
                absMvdCompA = _motionVectors[mbAddr, mbPart.SubMbPartIdxA, compIdx];
            }
            else
            {
                uint mbAddrA = _sliceState.GetMbAddrA(mbAddr);
                absMvdCompA = (mbAddrA == uint.MaxValue) ? 0U : _motionVectors[mbAddrA, (mbPart.SubMbPartIdxA & 15), compIdx];
            }

            uint absMvdCompB;

            if (mbPart.SubMbPartIdxB < 16)
            {
                absMvdCompB = _motionVectors[mbAddr, mbPart.SubMbPartIdxB, compIdx];
            }
            else
            {
                uint mbAddrB = _sliceState.GetMbAddrB(mbAddr);
                absMvdCompB = (mbAddrB == uint.MaxValue) ? 0U : _motionVectors[mbAddrB, (mbPart.SubMbPartIdxB & 15), compIdx];
            }

            uint absMvdComp = (absMvdCompA + absMvdCompB);

            return((absMvdComp < 3) ? 0U : ((absMvdComp > 32) ? 2U : 1U));
        }
        public void UpdateComponent(uint mbAddr, MacroblockPartition mbPart, uint compIdx, uint absValue)
        {
            var byteValue = (byte)Math.Min(absValue, 127);

            foreach (uint subBlkIdx in mbPart.MbPartSubBlks)
            {
                _motionVectors[mbAddr, subBlkIdx, compIdx] = byteValue;
            }
        }