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); }
/// <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(); }
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); }
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); }
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(); }