private void SubMacroBlockPrediction()
        {
            if (_sliceState.SliceType == SliceType.B)
            {
                for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
                {
                    uint subMbType = GetSubMbTypeB();
                    _subMbTypes[mbPartIdx] = SubMacroblockType.GetSubMbTypeB(subMbType);
                }
            }
            else             // P or Sp
            {
                for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
                {
                    uint subMbType = GetSubMbTypeP();
                    _subMbTypes[mbPartIdx] = SubMacroblockType.GetSubMbTypeP(subMbType);
                }
            }

            uint referencePictureCount0 = _sliceState.ActiveReferencePictureCount0;            //defaults to _pictureState.DefaultReferencePictureCount0;

            if (HasReferencePictureIndex(referencePictureCount0))
            {
                var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL0, _mbStateB.RefIdxL0);
                for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
                {
                    if (_subMbTypes[mbPartIdx].List0Predicted)
                    {
                        uint idx = MacroblockPartitioning.M8X8[mbPartIdx].Idx;
                        if (GetReferencePicture(referencePictureCount0, referencePictureIndex.GetCtxIdxInc(idx)))                         // ref_idx_l0[ mbPartIdx ]
                        {
                            referencePictureIndex.SetNonZeroRefIdx(idx);
                        }
                    }
                }
                _currMbState.RefIdxL0 = referencePictureIndex.Bits;
            }

            uint referencePictureCount1 = _sliceState.ActiveReferencePictureCount1;            //defaults to _pictureState.DefaultReferencePictureCount1;

            if (HasReferencePictureIndex(referencePictureCount1))
            {
                var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL1, _mbStateB.RefIdxL1);
                for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
                {
                    if (_subMbTypes[mbPartIdx].List1Predicted)
                    {
                        uint idx = MacroblockPartitioning.M8X8[mbPartIdx].Idx;
                        if (GetReferencePicture(referencePictureCount1, referencePictureIndex.GetCtxIdxInc(idx)))                         // ref_idx_l0[ mbPartIdx ]
                        {
                            referencePictureIndex.SetNonZeroRefIdx(idx);
                        }
                    }
                }
                _currMbState.RefIdxL1 = referencePictureIndex.Bits;
            }

            for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
            {
                ISubMacroblockType subMbType = _subMbTypes[mbPartIdx];
                if (subMbType.List0Predicted)
                {
                    MacroblockPartitioning macroblockPartitioning = subMbType.MacroblockPartitioning;
                    uint subMbPartOffset = (mbPartIdx * subMbType.NumSubMbPart);
                    for (uint subMbPartIdx = 0; subMbPartIdx < subMbType.NumSubMbPart; subMbPartIdx++)
                    {
                        GetMotionVector(_motionFieldL0, macroblockPartitioning[subMbPartOffset + subMbPartIdx]);                         // mvd_l0[ i ][ j ][ compIdx ]
                    }
                }
            }
            for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
            {
                ISubMacroblockType subMbType = _subMbTypes[mbPartIdx];
                if (subMbType.List1Predicted)
                {
                    MacroblockPartitioning macroblockPartitioning = subMbType.MacroblockPartitioning;
                    uint subMbPartOffset = (mbPartIdx * subMbType.NumSubMbPart);
                    for (uint subMbPartIdx = 0; subMbPartIdx < subMbType.NumSubMbPart; subMbPartIdx++)
                    {
                        GetMotionVector(_motionFieldL1, macroblockPartitioning[subMbPartOffset + subMbPartIdx]);                         // mvd_l1[ i ][ j ][ compIdx ]
                    }
                }
            }
        }
        // 7.3.5.1 Macroblock prediction syntax
        private void MacroBlockPrediction(IMacroblockType macroBlockType)
        {
            if (macroBlockType.IsIntra4X4 || macroBlockType.IsIntra16X16)
            {
                if (macroBlockType.IsIntra4X4)
                {
                    int lumaSubBlocks = _mbFlags.TransformSize8X8Flag ? 4 : 16;
                    for (int i = 0; i < lumaSubBlocks; i++)
                    {
                        if (GetPrevIntra4X4PredModeFlag() == 0)                   // prev_intra4x4_pred_mode_flag[luma4x4BlkIdx])
                        {
                            GetRemIntra4X4PredMode();                             // rem_intra4x4_pred_mode[luma4x4BlkIdx]
                        }
                    }
                }
                if (_sequenceState.IsChromaSubsampling)
                {
                    GetIntraChromaPredMode();                     // intra_chroma_pred_mode
                }
            }
            else if (!macroBlockType.IsDirect)
            {
                uint numMbPart = macroBlockType.NumMbPart;                 // either 1 or 2
                MacroblockPartitioning macroblockPartitioning = macroBlockType.MacroblockPartitioning;

                uint referencePictureCount0 = _sliceState.ActiveReferencePictureCount0;                //defaults to _pictureState.DefaultReferencePictureCount0;
                if (HasReferencePictureIndex(referencePictureCount0))
                {
                    var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL0, _mbStateB.RefIdxL0);
                    for (uint i = 0; i < numMbPart; i++)
                    {
                        if (macroBlockType.IsList0Predicted(i))
                        {
                            uint idx = macroblockPartitioning[i].Idx;
                            if (GetReferencePicture(referencePictureCount0, referencePictureIndex.GetCtxIdxInc(idx)))                             // ref_idx_l0[ mbPartIdx ]
                            {
                                referencePictureIndex.SetNonZeroRefIdx(idx);
                            }
                        }
                    }
                    _currMbState.RefIdxL0 = referencePictureIndex.Bits;
                }

                uint referencePictureCount1 = _sliceState.ActiveReferencePictureCount1;                //defaults to _pictureState.DefaultReferencePictureCount1;
                if (HasReferencePictureIndex(referencePictureCount1))
                {
                    var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL1, _mbStateB.RefIdxL1);
                    for (uint i = 0; i < numMbPart; i++)
                    {
                        if (macroBlockType.IsList1Predicted(i))
                        {
                            uint idx = macroblockPartitioning[i].Idx;
                            if (GetReferencePicture(referencePictureCount1, referencePictureIndex.GetCtxIdxInc(idx)))                             // ref_idx_l1[ mbPartIdx ]
                            {
                                referencePictureIndex.SetNonZeroRefIdx(idx);
                            }
                        }
                    }
                    _currMbState.RefIdxL1 = referencePictureIndex.Bits;
                }

                for (uint i = 0; i < numMbPart; i++)
                {
                    if (macroBlockType.IsList0Predicted(i))
                    {
                        GetMotionVector(_motionFieldL0, macroblockPartitioning[i]);                         // mvd_l0[ i ][ 0 ][ compIdx ]
                    }
                }
                for (uint i = 0; i < numMbPart; i++)
                {
                    if (macroBlockType.IsList1Predicted(i))
                    {
                        GetMotionVector(_motionFieldL1, macroblockPartitioning[i]);                         // mvd_l1[ i ][ 0 ][ compIdx ]
                    }
                }
            }
        }