Beispiel #1
0
        private IMacroblockType GetMacroBlockType()
        {
            //Table 7-10,7-11,..
            switch (_sliceState.SliceType)
            {
            case SliceType.I:
                uint mbTypeI = _reader.GetExpGolombCoded(25);
                return(MacroblockType.GetMbTypeI(mbTypeI));

            case SliceType.Si:
                uint mbTypeSi = _reader.GetExpGolombCoded(26);
                return(MacroblockType.GetMbTypeSi(mbTypeSi));

            case SliceType.P:
            case SliceType.Sp:
                uint mbTypeP = _reader.GetExpGolombCoded(30);
                return(MacroblockType.GetMbTypeP(mbTypeP));

            case SliceType.B:
                uint mbTypeB = _reader.GetExpGolombCoded(48);
                return(MacroblockType.GetMbTypeB(mbTypeB));
            }

            throw new InvalidOperationException("Current type not set");
        }
        private IMacroblockType GetMbTypeI()
        {
            const uint ctxOffset = 3;

            if (_arithmeticDecoder.DecodeDecision(ctxOffset + _mbFlags.GetMbTypeCtxIdxInc()) == 0)
            {
                return(MacroblockType.GetMbTypeI(0));
            }

            _mbFlags.SetMbTypeNotZero();

            return(GetMbTypeIntra(ctxOffset, MbTypeIntraCtxIdxIncIntraSlice));
        }
        private IMacroblockType GetMbTypeB()
        {
            const uint ctxOffsetPrefix = 27;

            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + _mbFlags.GetMbTypeCtxIdxInc()) == 0)
            {
                return(MacroblockType.GetMbTypeB(0));
            }

            _mbFlags.SetMbTypeNotZero();

            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 3) == 0)
            {
                return(MacroblockType.GetMbTypeB(1U + _arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 5)));
            }
            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 4) == 0)
            {
                return(MacroblockType.GetMbTypeB(3U + GetFixedLength((ctxOffsetPrefix + 5), 3)));
            }
            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 5) == 0)
            {
                return(MacroblockType.GetMbTypeB(12U + GetFixedLength((ctxOffsetPrefix + 5), 3)));
            }
            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 5) == 1)
            {
                return(MacroblockType.GetMbTypeB(11U + (11U * _arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 5))));
            }
            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 5) == 0)
            {
                return(MacroblockType.GetMbTypeB(20U + _arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 5)));
            }

            const uint ctxOffsetSuffix = 32;

            if (_arithmeticDecoder.DecodeDecision(ctxOffsetSuffix) == 0)
            {
                return(MacroblockType.GetMbTypeI(0));
            }

            return(GetMbTypeIntra(ctxOffsetSuffix, MbTypeIntraCtxIdxIncInterSlice));
        }
        private IMacroblockType GetMbTypeIntra(uint ctxOffset, uint[] binIdxCtxIdxInc)
        {
            if (_arithmeticDecoder.DecodeTerminate() == 1)
            {
                return(MacroblockType.GetMbTypeI(25));                // I_PCM
            }

            // First decision determines 'CodedBlockPatternLuma' (0 for '0', 1 for '15')
            uint mbType = (12U * _arithmeticDecoder.DecodeDecision(ctxOffset + binIdxCtxIdxInc[2]));

            // Next 1-2 bits determine 'CodedBlockPatternChroma' (0, 1 or 2)
            if (_arithmeticDecoder.DecodeDecision(ctxOffset + binIdxCtxIdxInc[3]) == 1)
            {
                mbType += (1 + (uint)_arithmeticDecoder.DecodeDecision(ctxOffset + binIdxCtxIdxInc[4])) << 2;
            }

            // Final 2 bits determine the 'intra_chroma_pred_mode'
            mbType |= (uint)_arithmeticDecoder.DecodeDecision(ctxOffset + binIdxCtxIdxInc[5]) << 1;
            mbType |= _arithmeticDecoder.DecodeDecision(ctxOffset + binIdxCtxIdxInc[6]);
            return(MacroblockType.GetMbTypeI(mbType + 1));
        }
        private IMacroblockType GetMbTypeP()
        {
            // Note: The 'MbTypeNotZero' flag is not used in P-slices!

            // Table 9-37 – Binarization for macroblock types in P, SP, and B slices
            const uint ctxOffsetPrefix = 14;

            if (_arithmeticDecoder.DecodeDecision(ctxOffsetPrefix) == 0)
            {
                // 9.3.3.1.2 Assignment process of ctxIdxInc using prior decoded bin values
                uint b1 = _arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + 1);
                uint b2 = _arithmeticDecoder.DecodeDecision(ctxOffsetPrefix + (b1 + 2));
                return(MacroblockType.GetMbTypeP((b1 << 1) ^ (3 * b2)));
            }

            const uint ctxOffsetSuffix = 17;

            if (_arithmeticDecoder.DecodeDecision(ctxOffsetSuffix) == 0)
            {
                return(MacroblockType.GetMbTypeI(0));
            }

            return(GetMbTypeIntra(ctxOffsetSuffix, MbTypeIntraCtxIdxIncInterSlice));
        }
        protected YuvFrameBuffer outputFrameBuffer; // encoded frame

        #endregion Fields

        #region Constructors

        protected AbstractEncodingMode(Macroblock macroblock, MacroblockType mbType)
        {
            this.macroblock = macroblock;
            this.mbType = mbType;
        }