Example #1
0
        private CoeffToken GetCoeffToken(CodedCoefficients codedCoefficients, uint subBlockIndex)
        {
            var nC         = codedCoefficients.PredictTotalCoeff(_currMbAddr, subBlockIndex);
            var coeffToken = _reader.GetVlc(LookupCoeffTokenVlcTable(nC));

            if (coeffToken.TotalCoeff == 255 /*invalid*/)
            {
                _readerState.Invalidate();
                return(new CoeffToken(0, 0));
            }

            codedCoefficients.UpdateTotalCoeff((int)_currMbAddr, subBlockIndex, coeffToken.TotalCoeff);
            return(coeffToken);
        }
Example #2
0
        private void Residual(IMacroblockType macroBlockType, int startIdx, int endIdx)
        {
            ResidualLuma(macroBlockType, startIdx, endIdx, _lumaCodedCoefficients);

            if (_sequenceState.IsChromaSubsampling)             // Chroma format 4:2:0 or 4:2:2
            {
                uint numSubBlocks = (4 * ChromaFormat.NumC8X8); // in 4x4 blocks
                if (IsChromaDcResidualPresent() && (startIdx == 0))
                {
                    for (uint iCbCr = 0; iCbCr < 2; iCbCr++)
                    {
                        var coeffToken = GetChromaCoeffToken();
                        if (coeffToken.TotalCoeff != 0)
                        {
                            ResidualBlockCavlc(0, (int)(numSubBlocks - 1), (int)numSubBlocks, coeffToken);
                        }
                    }
                }
                if (IsChromaAcResidualPresent())
                {
                    for (uint iCbCr = 0; iCbCr < 2; iCbCr++)
                    {
                        CodedCoefficients codedCoefficients = _chromaCodedCoefficients[iCbCr];
                        for (uint i = 0; i < numSubBlocks; i++)
                        {
                            var coeffToken = GetCoeffToken(codedCoefficients, i);
                            if (coeffToken.TotalCoeff != 0)
                            {
                                ResidualBlockCavlc(Math.Max(0, (startIdx - 1)), (endIdx - 1), 15, coeffToken);
                            }
                        }
                    }
                }
                else
                {
                    // Clear non-zero coefficient predictions for non-coded blocks
                    _chromaCodedCoefficients[Cb].UpdateTotalCoeff((int)_currMbAddr, 0);
                    _chromaCodedCoefficients[Cr].UpdateTotalCoeff((int)_currMbAddr, 0);
                }
            }
            else if (ChromaFormat == ChromaFormat.YCbCr444)
            {
                ResidualLuma(macroBlockType, startIdx, endIdx, _chromaCodedCoefficients[0]);                 // Cb
                ResidualLuma(macroBlockType, startIdx, endIdx, _chromaCodedCoefficients[1]);                 // Cr
            }
        }
Example #3
0
        public CavlcSliceData(INalUnitReader reader, IState readerState)
        {
            _reader                  = reader;
            _readerState             = readerState;
            _sliceState              = reader.State.SliceState;
            _pictureState            = _sliceState.PictureState;
            _sequenceState           = _pictureState.SequenceState;
            _coeffTokenChromaDc      = (ChromaFormat == ChromaFormat.YCbCr420) ? CoeffTokenChromaDc420 : CoeffTokenChromaDc422;
            _lumaCodedCoefficients   = new CodedCoefficients(_sliceState, PicHeightInMbs, SubBlockPartition.Luma);
            _chromaCodedCoefficients = new CodedCoefficients[2];
            _subMbTypes              = new ISubMacroblockType[4];

            SubBlockPartition chromaSubBlockPartition = ChromaArrayTypeSubBlockPartitions[_sequenceState.ChromaFormat.ChromaFormatIdc];

            for (int i = 0; i < _chromaCodedCoefficients.Length; i++)
            {
                _chromaCodedCoefficients[i] = new CodedCoefficients(_sliceState, PicHeightInMbs, chromaSubBlockPartition);
            }

            MbToSliceGroupMap = _mbToSliceGroup.CreateMacroBlockToSliceGroupMap(_sliceState);
        }
Example #4
0
        private void ResidualLuma(IMacroblockType macroBlockType, int startIdx, int endIdx, CodedCoefficients codedCoefficients)
        {
            if ((startIdx == 0) && macroBlockType.IsIntra16X16)
            {
                var coeffTokenDc = GetCoeffToken(codedCoefficients, 0);
#if DEBUG
                H264Debug.WriteLine("   coeff_token( luma dc )={0}", coeffTokenDc);
#endif
                if (coeffTokenDc.TotalCoeff != 0)
                {
                    ResidualBlockCavlc(0, 15, 16, coeffTokenDc);
                }
            }
            for (uint i8X8 = 0; i8X8 < 4; i8X8++)
            {
                if (IsLumaBitSet(i8X8))
                {
                    for (uint i4X4 = 0; i4X4 < 4; i4X4++)
                    {
                        uint subBlkIdx  = ((i8X8 << 2) + i4X4);
                        var  coeffToken = GetCoeffToken(codedCoefficients, subBlkIdx);
#if DEBUG
                        H264Debug.WriteLine("   coeff_token={0}", coeffToken);
#endif
                        if (coeffToken.TotalCoeff != 0)
                        {
                            if (macroBlockType.IsIntra16X16)
                            {
                                ResidualBlockCavlc(Math.Max(0, (startIdx - 1)), (endIdx - 1), 15, coeffToken);
                            }
                            else
                            {
                                ResidualBlockCavlc(startIdx, endIdx, 16, coeffToken);
                            }
                        }
                    }
                }
                else
                {
                    // Clear non-zero coefficient predictions for non-coded blocks
                    for (uint i4X4 = 0; i4X4 < 4; i4X4++)
                    {
                        codedCoefficients.UpdateTotalCoeff((int)_currMbAddr, (4 * i8X8) + i4X4, 0);
                    }
                }
            }
        }