Example #1
0
        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
            }
        }