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; } }