Ejemplo n.º 1
0
        public int GetCostLuma16(Vp8ModeScore rd, Vp8EncProba proba, Vp8Residual res)
        {
            int r = 0;

            // re-import the non-zero context.
            this.NzToBytes();

            // DC
            res.Init(0, 1, proba);
            res.SetCoeffs(rd.YDcLevels);
            r += res.GetResidualCost(this.TopNz[8] + this.LeftNz[8]);

            // AC
            res.Init(1, 0, proba);
            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    int ctx = this.TopNz[x] + this.LeftNz[y];
                    res.SetCoeffs(rd.YAcLevels.AsSpan((x + (y * 4)) * 16, 16));
                    r            += res.GetResidualCost(ctx);
                    this.TopNz[x] = this.LeftNz[y] = res.Last >= 0 ? 1 : 0;
                }
            }

            return(r);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Same as CodeResiduals, but doesn't actually write anything.
        /// Instead, it just records the event distribution.
        /// </summary>
        private void RecordResiduals(Vp8EncIterator it, Vp8ModeScore rd)
        {
            int  x, y, ch;
            var  residual = new Vp8Residual();
            bool i16      = it.CurrentMacroBlockInfo.MacroBlockType == Vp8MacroBlockType.I16X16;

            it.NzToBytes();

            if (i16)
            {
                // i16x16
                residual.Init(0, 1, this.Proba);
                residual.SetCoeffs(rd.YDcLevels);
                int res = residual.RecordCoeffs(it.TopNz[8] + it.LeftNz[8]);
                it.TopNz[8]  = res;
                it.LeftNz[8] = res;
                residual.Init(1, 0, this.Proba);
            }
            else
            {
                residual.Init(0, 3, this.Proba);
            }

            // luma-AC
            for (y = 0; y < 4; y++)
            {
                for (x = 0; x < 4; x++)
                {
                    int          ctx    = it.TopNz[x] + it.LeftNz[y];
                    Span <short> coeffs = rd.YAcLevels.AsSpan(16 * (x + (y * 4)), 16);
                    residual.SetCoeffs(coeffs);
                    int res = residual.RecordCoeffs(ctx);
                    it.TopNz[x]  = res;
                    it.LeftNz[y] = res;
                }
            }

            // U/V
            residual.Init(0, 2, this.Proba);
            for (ch = 0; ch <= 2; ch += 2)
            {
                for (y = 0; y < 2; y++)
                {
                    for (x = 0; x < 2; x++)
                    {
                        int ctx = it.TopNz[4 + ch + x] + it.LeftNz[4 + ch + y];
                        residual.SetCoeffs(rd.UvLevels.AsSpan(16 * ((ch * 2) + x + (y * 2)), 16));
                        int res = residual.RecordCoeffs(ctx);
                        it.TopNz[4 + ch + x]  = res;
                        it.LeftNz[4 + ch + y] = res;
                    }
                }
            }

            it.BytesToNz();
        }
Ejemplo n.º 3
0
        public int GetCostLuma4(Span <short> levels, Vp8EncProba proba, Vp8Residual res)
        {
            int x = this.I4 & 3;
            int y = this.I4 >> 2;
            int r = 0;

            res.Init(0, 3, proba);
            int ctx = this.TopNz[x] + this.LeftNz[y];

            res.SetCoeffs(levels);
            r += res.GetResidualCost(ctx);
            return(r);
        }
Ejemplo n.º 4
0
        public int GetCostUv(Vp8ModeScore rd, Vp8EncProba proba, Vp8Residual res)
        {
            int r = 0;

            // re-import the non-zero context.
            this.NzToBytes();

            res.Init(0, 2, proba);
            for (int ch = 0; ch <= 2; ch += 2)
            {
                for (int y = 0; y < 2; y++)
                {
                    for (int x = 0; x < 2; x++)
                    {
                        int ctx = this.TopNz[4 + ch + x] + this.LeftNz[4 + ch + y];
                        res.SetCoeffs(rd.UvLevels.AsSpan(((ch * 2) + x + (y * 2)) * 16, 16));
                        r += res.GetResidualCost(ctx);
                        this.TopNz[4 + ch + x] = this.LeftNz[4 + ch + y] = res.Last >= 0 ? 1 : 0;
                    }
                }
            }

            return(r);
        }
Ejemplo n.º 5
0
        private void CodeResiduals(Vp8EncIterator it, Vp8ModeScore rd, Vp8Residual residual)
        {
            int  x, y, ch;
            bool i16     = it.CurrentMacroBlockInfo.MacroBlockType == Vp8MacroBlockType.I16X16;
            int  segment = it.CurrentMacroBlockInfo.Segment;

            it.NzToBytes();

            int pos1 = this.bitWriter.NumBytes();

            if (i16)
            {
                residual.Init(0, 1, this.Proba);
                residual.SetCoeffs(rd.YDcLevels);
                int res = this.bitWriter.PutCoeffs(it.TopNz[8] + it.LeftNz[8], residual);
                it.TopNz[8] = it.LeftNz[8] = res;
                residual.Init(1, 0, this.Proba);
            }
            else
            {
                residual.Init(0, 3, this.Proba);
            }

            // luma-AC
            for (y = 0; y < 4; y++)
            {
                for (x = 0; x < 4; x++)
                {
                    int          ctx    = it.TopNz[x] + it.LeftNz[y];
                    Span <short> coeffs = rd.YAcLevels.AsSpan(16 * (x + (y * 4)), 16);
                    residual.SetCoeffs(coeffs);
                    int res = this.bitWriter.PutCoeffs(ctx, residual);
                    it.TopNz[x] = it.LeftNz[y] = res;
                }
            }

            int pos2 = this.bitWriter.NumBytes();

            // U/V
            residual.Init(0, 2, this.Proba);
            for (ch = 0; ch <= 2; ch += 2)
            {
                for (y = 0; y < 2; y++)
                {
                    for (x = 0; x < 2; x++)
                    {
                        int ctx = it.TopNz[4 + ch + x] + it.LeftNz[4 + ch + y];
                        residual.SetCoeffs(rd.UvLevels.AsSpan(16 * ((ch * 2) + x + (y * 2)), 16));
                        int res = this.bitWriter.PutCoeffs(ctx, residual);
                        it.TopNz[4 + ch + x] = it.LeftNz[4 + ch + y] = res;
                    }
                }
            }

            int pos3 = this.bitWriter.NumBytes();

            it.LumaBits = pos2 - pos1;
            it.UvBits   = pos3 - pos2;
            it.BitCount[segment, i16 ? 1 : 0] += it.LumaBits;
            it.BitCount[segment, 2]           += it.UvBits;
            it.BytesToNz();
        }