private void ResidualBlockCavlc(int startIdx, int endIdx, int maxNumCoeff, CoeffToken coeffToken) { int suffixLength = ((coeffToken.TotalCoeff > 10) && (coeffToken.TrailingOnes < 3)) ? 1 : 0; #if DEBUG H264Debug.Write(" - levels="); if (coeffToken.TrailingOnes > 0) { uint signs = _reader.GetBits(coeffToken.TrailingOnes); // (n) x trailing_ones_sign_flag for (int i = 0; i < coeffToken.TrailingOnes; i++) { H264Debug.Write((((signs & (1 << (coeffToken.TrailingOnes - 1 - i))) == 0) ? "1," : "-1,")); } } #else _reader.GetBits(coeffToken.TrailingOnes); // (n) x trailing_ones_sign_flag #endif for (int i = coeffToken.TrailingOnes; i < coeffToken.TotalCoeff; i++) { int levelCode = GetCoefficientLevelCode(suffixLength); // The first non-zero coefficient after 'trailing ones' must be larger than 1, // unless the maximum count of trailing ones, i.e. 3, was reached. // This will further reduce the amount of bits required to represent a // coefficient level. if ((i == coeffToken.TrailingOnes) && (i /*trailing ones*/ < 3)) { levelCode += 2; // 2 instead of 1, because the lowest bit is the sign bit! } #if DEBUG H264Debug.Write("{0},", ((levelCode % 2) == 0) ? ((levelCode + 2) >> 1) : ((-levelCode - 1) >> 1)); #endif // Automatically adjust the suffix length if high coefficients levels are // encountered, to reduce the number of bits required to represent subsequent // high coefficient levels. if (suffixLength == 0) { suffixLength = 1; } if (suffixLength < 6) { int absLevelMinusOne = (levelCode >> 1); if (absLevelMinusOne >= (3 << (suffixLength - 1))) { suffixLength++; } } } #if DEBUG H264Debug.WriteLine(); #endif if (coeffToken.TotalCoeff < (endIdx - startIdx + 1)) { int zerosLeft = GetTotalZeros(coeffToken.TotalCoeff, maxNumCoeff); // total_zeros #if DEBUG H264Debug.WriteLine(" - total_zeros={0}", zerosLeft); H264Debug.WriteLine("ShowBits(32) = {0:x8} at {1:x8}", _reader.ShowBits(32), _reader.Position); H264Debug.Write(" - run_before="); #endif for (int i = 0; i < (coeffToken.TotalCoeff - 1) && (zerosLeft > 0); i++) { #if DEBUG int runBefore = _reader.GetVlc(RunBeforeTable[Math.Min(zerosLeft, 7)]); zerosLeft -= runBefore; // run_before H264Debug.Write("{0},", runBefore); #else zerosLeft -= _reader.GetVlc(RunBeforeTable[Math.Min(zerosLeft, 7)]); // run_before #endif } #if DEBUG H264Debug.WriteLine(); #endif } }