public static void predictPlane(int[] residual, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int[] topLeft, int x) { int H = 0; for (int i = 0; i < 7; i++) { H += (i + 1) * (topLine[x + 8 + i] - topLine[x + 6 - i]); } H += 8 * (topLine[x + 15] - topLeft[0]); int V = 0; for (int j = 0; j < 7; j++) { V += (j + 1) * (leftRow[8 + j] - leftRow[6 - j]); } V += 8 * (leftRow[15] - topLeft[0]); int c = (5 * V + 32) >> 6; int b = (5 * H + 32) >> 6; int a = 16 * (leftRow[15] + topLine[x + 15]); int off = 0; for (int j = 0; j < 16; j++) { for (int i = 0; i < 16; i++, off++) { int val = CABAC.clip((a + b * (i - 7) + c * (j - 7) + 16) >> 5, 0, 255); residual[off] = CABAC.clip(residual[off] + val, 0, 255); } } }
public static void predictHorizontalDown(int[] residual, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int[] topLeft, int mbOffX, int blkX, int blkY) { int c0 = (topLeft[blkY >> 2] + leftRow[blkY] + 1) >> 1; int c1 = (leftRow[blkY] + 2 * topLeft[blkY >> 2] + topLine[mbOffX + blkX + 0] + 2) >> 2; int c2 = (topLeft[blkY >> 2] + 2 * topLine[mbOffX + blkX + 0] + topLine[mbOffX + blkX + 1] + 2) >> 2; int c3 = (topLine[mbOffX + blkX + 0] + 2 * topLine[mbOffX + blkX + 1] + topLine[mbOffX + blkX + 2] + 2) >> 2; int c4 = (leftRow[blkY] + leftRow[blkY + 1] + 1) >> 1; int c5 = (topLeft[blkY >> 2] + 2 * leftRow[blkY] + leftRow[blkY + 1] + 2) >> 2; int c6 = (leftRow[blkY + 1] + leftRow[blkY + 2] + 1) >> 1; int c7 = (leftRow[blkY] + 2 * leftRow[blkY + 1] + leftRow[blkY + 2] + 2) >> 2; int c8 = (leftRow[blkY + 2] + leftRow[blkY + 3] + 1) >> 1; int c9 = (leftRow[blkY + 1] + 2 * leftRow[blkY + 2] + leftRow[blkY + 3] + 2) >> 2; int off = (blkY << 4) + blkX; residual[off] = CABAC.clip(residual[off] + c0, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + c1, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + c2, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + c3, 0, 255); residual[off + 16] = CABAC.clip(residual[off + 16] + c4, 0, 255); residual[off + 17] = CABAC.clip(residual[off + 17] + c5, 0, 255); residual[off + 18] = CABAC.clip(residual[off + 18] + c0, 0, 255); residual[off + 19] = CABAC.clip(residual[off + 19] + c1, 0, 255); residual[off + 32] = CABAC.clip(residual[off + 32] + c6, 0, 255); residual[off + 33] = CABAC.clip(residual[off + 33] + c7, 0, 255); residual[off + 34] = CABAC.clip(residual[off + 34] + c4, 0, 255); residual[off + 35] = CABAC.clip(residual[off + 35] + c5, 0, 255); residual[off + 48] = CABAC.clip(residual[off + 48] + c8, 0, 255); residual[off + 49] = CABAC.clip(residual[off + 49] + c9, 0, 255); residual[off + 50] = CABAC.clip(residual[off + 50] + c6, 0, 255); residual[off + 51] = CABAC.clip(residual[off + 51] + c7, 0, 255); }
private void weight(int[] blk0, int stride, int off, int blkW, int blkH, int logWD, int w, int o, int[] outs) { int dva = 1 << (logWD - 1); if (logWD >= 1) { for (int i = 0; i < blkH; i++, off += stride - blkW) { for (int j = 0; j < blkW; j++, off++) { outs[off] = CABAC.clip(((blk0[off] * w + dva) >> logWD) + o, 0, 255); } } } else { for (int i = 0; i < blkH; i++, off += stride - blkW) { for (int j = 0; j < blkW; j++, off++) { outs[off] = CABAC.clip(blk0[off] * w + o, 0, 255); } } } }
public static void predictPlane(int[] planeData, int mbX, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int[] topLeft) { int H = 0, blkOffX = (mbX << 3); for (int i = 0; i < 3; i++) { H += (i + 1) * (topLine[blkOffX + 4 + i] - topLine[blkOffX + 2 - i]); } H += 4 * (topLine[blkOffX + 7] - topLeft[0]); int V = 0; for (int j = 0; j < 3; j++) { V += (j + 1) * (leftRow[4 + j] - leftRow[2 - j]); } V += 4 * (leftRow[7] - topLeft[0]); int c = (34 * V + 32) >> 6; int b = (34 * H + 32) >> 6; int a = 16 * (leftRow[7] + topLine[blkOffX + 7]); for (int off = 0, j = 0; j < 8; j++) { for (int i = 0; i < 8; i++, off++) { int val = (a + b * (i - 3) + c * (j - 3) + 16) >> 5; planeData[off] = CABAC.clip(planeData[off] + CABAC.clip(val, 0, 255), 0, 255); } } }
public static void predictHorizontalUp(int[] residual, bool leftAvailable, int[] leftRow, int mbOffX, int blkX, int blkY) { int c0 = ((leftRow[blkY] + leftRow[blkY + 1] + 1) >> 1); int c1 = ((leftRow[blkY] + (leftRow[blkY + 1] << 1) + leftRow[blkY + 2] + 2) >> 2); int c2 = ((leftRow[blkY + 1] + leftRow[blkY + 2] + 1) >> 1); int c3 = ((leftRow[blkY + 1] + (leftRow[blkY + 2] << 1) + leftRow[blkY + 3] + 2) >> 2); int c4 = ((leftRow[blkY + 2] + leftRow[blkY + 3] + 1) >> 1); int c5 = ((leftRow[blkY + 2] + (leftRow[blkY + 3] << 1) + leftRow[blkY + 3] + 2) >> 2); int c6 = leftRow[blkY + 3]; int off = (blkY << 4) + blkX; residual[off] = CABAC.clip(residual[off] + c0, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + c1, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + c2, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + c3, 0, 255); residual[off + 16] = CABAC.clip(residual[off + 16] + c2, 0, 255); residual[off + 17] = CABAC.clip(residual[off + 17] + c3, 0, 255); residual[off + 18] = CABAC.clip(residual[off + 18] + c4, 0, 255); residual[off + 19] = CABAC.clip(residual[off + 19] + c5, 0, 255); residual[off + 32] = CABAC.clip(residual[off + 32] + c4, 0, 255); residual[off + 33] = CABAC.clip(residual[off + 33] + c5, 0, 255); residual[off + 34] = CABAC.clip(residual[off + 34] + c6, 0, 255); residual[off + 35] = CABAC.clip(residual[off + 35] + c6, 0, 255); residual[off + 48] = CABAC.clip(residual[off + 48] + c6, 0, 255); residual[off + 49] = CABAC.clip(residual[off + 49] + c6, 0, 255); residual[off + 50] = CABAC.clip(residual[off + 50] + c6, 0, 255); residual[off + 51] = CABAC.clip(residual[off + 51] + c6, 0, 255); }
public static void predictVerticalRight(int[] residual, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int[] topLeft, int mbOffX, int blkX, int blkY) { int v1 = (topLeft[blkY >> 2] + topLine[mbOffX + blkX + 0] + 1) >> 1; int v2 = (topLine[mbOffX + blkX + 0] + topLine[mbOffX + blkX + 1] + 1) >> 1; int v3 = (topLine[mbOffX + blkX + 1] + topLine[mbOffX + blkX + 2] + 1) >> 1; int v4 = (topLine[mbOffX + blkX + 2] + topLine[mbOffX + blkX + 3] + 1) >> 1; int v5 = (leftRow[blkY] + 2 * topLeft[blkY >> 2] + topLine[mbOffX + blkX + 0] + 2) >> 2; int v6 = (topLeft[blkY >> 2] + 2 * topLine[mbOffX + blkX + 0] + topLine[mbOffX + blkX + 1] + 2) >> 2; int v7 = (topLine[mbOffX + blkX + 0] + 2 * topLine[mbOffX + blkX + 1] + topLine[mbOffX + blkX + 2] + 2) >> 2; int v8 = (topLine[mbOffX + blkX + 1] + 2 * topLine[mbOffX + blkX + 2] + topLine[mbOffX + blkX + 3] + 2) >> 2; int v9 = (topLeft[blkY >> 2] + 2 * leftRow[blkY] + leftRow[blkY + 1] + 2) >> 2; int v10 = (leftRow[blkY] + 2 * leftRow[blkY + 1] + leftRow[blkY + 2] + 2) >> 2; int off = (blkY << 4) + blkX; residual[off] = CABAC.clip(residual[off] + v1, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + v2, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + v3, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + v4, 0, 255); residual[off + 16] = CABAC.clip(residual[off + 16] + v5, 0, 255); residual[off + 17] = CABAC.clip(residual[off + 17] + v6, 0, 255); residual[off + 18] = CABAC.clip(residual[off + 18] + v7, 0, 255); residual[off + 19] = CABAC.clip(residual[off + 19] + v8, 0, 255); residual[off + 32] = CABAC.clip(residual[off + 32] + v9, 0, 255); residual[off + 33] = CABAC.clip(residual[off + 33] + v1, 0, 255); residual[off + 34] = CABAC.clip(residual[off + 34] + v2, 0, 255); residual[off + 35] = CABAC.clip(residual[off + 35] + v3, 0, 255); residual[off + 48] = CABAC.clip(residual[off + 48] + v10, 0, 255); residual[off + 49] = CABAC.clip(residual[off + 49] + v5, 0, 255); residual[off + 50] = CABAC.clip(residual[off + 50] + v6, 0, 255); residual[off + 51] = CABAC.clip(residual[off + 51] + v7, 0, 255); }
public static void predictVertical(int[] planeData, int mbX, bool topAvailable, int[] topLine) { for (int off = 0, j = 0; j < 8; j++) { for (int i = 0; i < 8; i++, off++) { planeData[off] = CABAC.clip(planeData[off] + topLine[(mbX << 3) + i], 0, 255); } } }
public static void predictHorizontal(int[] planeData, int mbX, bool leftAvailable, int[] leftRow) { for (int off = 0, j = 0; j < 8; j++) { for (int i = 0; i < 8; i++, off++) { planeData[off] = CABAC.clip(planeData[off] + leftRow[j], 0, 255); } } }
public static void copyAdd(int[] src, int srcOff, int[] dst, int dstOff) { dst[dstOff] = CABAC.clip(dst[dstOff] + src[srcOff], 0, 255); dst[dstOff + 1] = CABAC.clip(dst[dstOff + 1] + src[srcOff + 1], 0, 255); dst[dstOff + 2] = CABAC.clip(dst[dstOff + 2] + src[srcOff + 2], 0, 255); dst[dstOff + 3] = CABAC.clip(dst[dstOff + 3] + src[srcOff + 3], 0, 255); dst[dstOff + 4] = CABAC.clip(dst[dstOff + 4] + src[srcOff + 4], 0, 255); dst[dstOff + 5] = CABAC.clip(dst[dstOff + 5] + src[srcOff + 5], 0, 255); dst[dstOff + 6] = CABAC.clip(dst[dstOff + 6] + src[srcOff + 6], 0, 255); dst[dstOff + 7] = CABAC.clip(dst[dstOff + 7] + src[srcOff + 7], 0, 255); }
public static void predictHorizontal(int[] residual, bool leftAvailable, int[] leftRow, int x) { int off = 0; for (int j = 0; j < 16; j++) { for (int i = 0; i < 16; i++, off++) { residual[off] = CABAC.clip(residual[off] + leftRow[j], 0, 255); } } }
public static void predictVertical(int[] residual, bool topAvailable, int[] topLine, int x) { int off = 0; for (int j = 0; j < 16; j++) { for (int i = 0; i < 16; i++, off++) { residual[off] = CABAC.clip(residual[off] + topLine[x + i], 0, 255); } } }
public static void fillAdd(int[] dst, int off, int val) { for (int i = 0; i < 8; i++, off += 16) { dst[off] = CABAC.clip(dst[off] + val, 0, 255); dst[off + 1] = CABAC.clip(dst[off + 1] + val, 0, 255); dst[off + 2] = CABAC.clip(dst[off + 2] + val, 0, 255); dst[off + 3] = CABAC.clip(dst[off + 3] + val, 0, 255); dst[off + 4] = CABAC.clip(dst[off + 4] + val, 0, 255); dst[off + 5] = CABAC.clip(dst[off + 5] + val, 0, 255); dst[off + 6] = CABAC.clip(dst[off + 6] + val, 0, 255); dst[off + 7] = CABAC.clip(dst[off + 7] + val, 0, 255); } }
public static void predictDCInside(int[] planeData, int blkX, int blkY, int mbX, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine) { int s0, blkOffX = (blkX << 2) + (mbX << 3), blkOffY = blkY << 2; if (leftAvailable && topAvailable) { s0 = 0; for (int i = 0; i < 4; i++) { s0 += leftRow[i + blkOffY]; } for (int i = 0; i < 4; i++) { s0 += topLine[blkOffX + i]; } s0 = (s0 + 4) >> 3; } else if (leftAvailable) { s0 = 0; for (int i = 0; i < 4; i++) { s0 += leftRow[blkOffY + i]; } s0 = (s0 + 2) >> 2; } else if (topAvailable) { s0 = 0; for (int i = 0; i < 4; i++) { s0 += topLine[blkOffX + i]; } s0 = (s0 + 2) >> 2; } else { s0 = 128; } for (int off = (blkY << 5) + (blkX << 2), j = 0; j < 4; j++, off += 8) { planeData[off] = CABAC.clip(planeData[off] + s0, 0, 255); planeData[off + 1] = CABAC.clip(planeData[off + 1] + s0, 0, 255); planeData[off + 2] = CABAC.clip(planeData[off + 2] + s0, 0, 255); planeData[off + 3] = CABAC.clip(planeData[off + 3] + s0, 0, 255); } }
public static void predictVertical(int[] residual, bool topAvailable, int[] topLine, int mbOffX, int blkX, int blkY) { int off = (blkY << 4) + blkX; int toff = mbOffX + blkX; for (int j = 0; j < 4; j++) { residual[off] = CABAC.clip(residual[off] + topLine[toff], 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + topLine[toff + 1], 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + topLine[toff + 2], 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + topLine[toff + 3], 0, 255); off += 16; } }
public static void predictHorizontal(int[] residual, bool leftAvailable, int[] leftRow, int mbOffX, int blkX, int blkY) { int off = (blkY << 4) + blkX; for (int j = 0; j < 4; j++) { int l = leftRow[blkY + j]; residual[off] = CABAC.clip(residual[off] + l, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + l, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + l, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + l, 0, 255); off += 16; } }
private void weightPrediction(int[] blk0, int[] blk1, int stride, int off, int blkW, int blkH, int logWD, int w0, int w1, int o0, int o1, int[] outs) { int dvadva = 1 << logWD; int sum = (o0 + o1 + 1) >> 1; int logWDCP1 = logWD + 1; for (int i = 0; i < blkH; i++, off += stride - blkW) { for (int j = 0; j < blkW; j++, off++) { outs[off] = CABAC.clip(((blk0[off] * w0 + blk1[off] * w1 + dvadva) >> logWDCP1) + sum, 0, 255); } } }
public static void predictVerticalLeft(int[] residual, bool topAvailable, bool topRightAvailable, int[] topLine, int mbOffX, int blkX, int blkY) { int to = mbOffX + blkX; int tr0 = topLine[to + 3], tr1 = topLine[to + 3], tr2 = topLine[to + 3]; if (topRightAvailable) { tr0 = topLine[to + 4]; tr1 = topLine[to + 5]; tr2 = topLine[to + 6]; } int c0 = ((topLine[to] + topLine[to + 1] + 1) >> 1); int c1 = ((topLine[to + 1] + topLine[to + 2] + 1) >> 1); int c2 = ((topLine[to + 2] + topLine[to + 3] + 1) >> 1); int c3 = ((topLine[to + 3] + tr0 + 1) >> 1); int c4 = ((tr0 + tr1 + 1) >> 1); int c5 = ((topLine[to] + 2 * topLine[to + 1] + topLine[to + 2] + 2) >> 2); int c6 = ((topLine[to + 1] + 2 * topLine[to + 2] + topLine[to + 3] + 2) >> 2); int c7 = ((topLine[to + 2] + 2 * topLine[to + 3] + tr0 + 2) >> 2); int c8 = ((topLine[to + 3] + 2 * tr0 + tr1 + 2) >> 2); int c9 = ((tr0 + 2 * tr1 + tr2 + 2) >> 2); int off = (blkY << 4) + blkX; residual[off] = CABAC.clip(residual[off] + c0, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + c1, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + c2, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + c3, 0, 255); residual[off + 16] = CABAC.clip(residual[off + 16] + c5, 0, 255); residual[off + 17] = CABAC.clip(residual[off + 17] + c6, 0, 255); residual[off + 18] = CABAC.clip(residual[off + 18] + c7, 0, 255); residual[off + 19] = CABAC.clip(residual[off + 19] + c8, 0, 255); residual[off + 32] = CABAC.clip(residual[off + 32] + c1, 0, 255); residual[off + 33] = CABAC.clip(residual[off + 33] + c2, 0, 255); residual[off + 34] = CABAC.clip(residual[off + 34] + c3, 0, 255); residual[off + 35] = CABAC.clip(residual[off + 35] + c4, 0, 255); residual[off + 48] = CABAC.clip(residual[off + 48] + c6, 0, 255); residual[off + 49] = CABAC.clip(residual[off + 49] + c7, 0, 255); residual[off + 50] = CABAC.clip(residual[off + 50] + c8, 0, 255); residual[off + 51] = CABAC.clip(residual[off + 51] + c9, 0, 255); }
private static void predictVertical(int[] residual, bool topLeftAvailable, bool topRightAvailable, int[] topLeft, int[] topLine, int mbOffX, int blkX, int blkY) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); for (int i = 0, off = (blkY << 4) + blkX; i < 8; i++, off += 16) { residual[off] = CABAC.clip(residual[off] + topBuf[0], 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + topBuf[1], 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + topBuf[2], 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + topBuf[3], 0, 255); residual[off + 4] = CABAC.clip(residual[off + 4] + topBuf[4], 0, 255); residual[off + 5] = CABAC.clip(residual[off + 5] + topBuf[5], 0, 255); residual[off + 6] = CABAC.clip(residual[off + 6] + topBuf[6], 0, 255); residual[off + 7] = CABAC.clip(residual[off + 7] + topBuf[7], 0, 255); } }
private static void predictHorizontal(int[] residual, bool topLeftAvailable, int[] topLeft, int[] leftRow, int mbOffX, int blkX, int blkY) { interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); for (int i = 0, off = (blkY << 4) + blkX; i < 8; i++, off += 16) { residual[off] = CABAC.clip(residual[off] + leftBuf[i], 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + leftBuf[i], 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + leftBuf[i], 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + leftBuf[i], 0, 255); residual[off + 4] = CABAC.clip(residual[off + 4] + leftBuf[i], 0, 255); residual[off + 5] = CABAC.clip(residual[off + 5] + leftBuf[i], 0, 255); residual[off + 6] = CABAC.clip(residual[off + 6] + leftBuf[i], 0, 255); residual[off + 7] = CABAC.clip(residual[off + 7] + leftBuf[i], 0, 255); } }
public static void predictDC(int[] residual, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int x) { int s0; if (leftAvailable && topAvailable) { s0 = 0; for (int i = 0; i < 16; i++) { s0 += leftRow[i]; } for (int i = 0; i < 16; i++) { s0 += topLine[x + i]; } s0 = (s0 + 16) >> 5; } else if (leftAvailable) { s0 = 0; for (int i = 0; i < 16; i++) { s0 += leftRow[i]; } s0 = (s0 + 8) >> 4; } else if (topAvailable) { s0 = 0; for (int i = 0; i < 16; i++) { s0 += topLine[x + i]; } s0 = (s0 + 8) >> 4; } else { s0 = 128; } for (int i = 0; i < 256; i++) { residual[i] = CABAC.clip(residual[i] + s0, 0, 255); } }
public static void predictDiagonalDownLeft(int[] residual, bool topAvailable, bool topRightAvailable, int[] topLine, int mbOffX, int blkX, int blkY) { int to = mbOffX + blkX; int tr0 = topLine[to + 3], tr1 = topLine[to + 3], tr2 = topLine[to + 3], tr3 = topLine[to + 3]; if (topRightAvailable) { tr0 = topLine[to + 4]; tr1 = topLine[to + 5]; tr2 = topLine[to + 6]; tr3 = topLine[to + 7]; } int c0 = ((topLine[to] + topLine[to + 2] + 2 * (topLine[to + 1]) + 2) >> 2); int c1 = ((topLine[to + 1] + topLine[to + 3] + 2 * (topLine[to + 2]) + 2) >> 2); int c2 = ((topLine[to + 2] + tr0 + 2 * (topLine[to + 3]) + 2) >> 2); int c3 = ((topLine[to + 3] + tr1 + 2 * (tr0) + 2) >> 2); int c4 = ((tr0 + tr2 + 2 * (tr1) + 2) >> 2); int c5 = ((tr1 + tr3 + 2 * (tr2) + 2) >> 2); int c6 = ((tr2 + 3 * (tr3) + 2) >> 2); int off = (blkY << 4) + blkX; residual[off] = CABAC.clip(residual[off] + c0, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + c1, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + c2, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + c3, 0, 255); residual[off + 16] = CABAC.clip(residual[off + 16] + c1, 0, 255); residual[off + 17] = CABAC.clip(residual[off + 17] + c2, 0, 255); residual[off + 18] = CABAC.clip(residual[off + 18] + c3, 0, 255); residual[off + 19] = CABAC.clip(residual[off + 19] + c4, 0, 255); residual[off + 32] = CABAC.clip(residual[off + 32] + c2, 0, 255); residual[off + 33] = CABAC.clip(residual[off + 33] + c3, 0, 255); residual[off + 34] = CABAC.clip(residual[off + 34] + c4, 0, 255); residual[off + 35] = CABAC.clip(residual[off + 35] + c5, 0, 255); residual[off + 48] = CABAC.clip(residual[off + 48] + c3, 0, 255); residual[off + 49] = CABAC.clip(residual[off + 49] + c4, 0, 255); residual[off + 50] = CABAC.clip(residual[off + 50] + c5, 0, 255); residual[off + 51] = CABAC.clip(residual[off + 51] + c6, 0, 255); }
public static void predictDC(int[] residual, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int mbOffX, int blkX, int blkY) { int val; if (leftAvailable && topAvailable) { val = (leftRow[blkY] + leftRow[blkY + 1] + leftRow[blkY + 2] + leftRow[blkY + 3] + topLine[mbOffX + blkX] + topLine[mbOffX + blkX + 1] + topLine[mbOffX + blkX + 2] + topLine[mbOffX + blkX + 3] + 4) >> 3; } else if (leftAvailable) { val = (leftRow[blkY] + leftRow[blkY + 1] + leftRow[blkY + 2] + leftRow[blkY + 3] + 2) >> 2; } else if (topAvailable) { val = (topLine[mbOffX + blkX] + topLine[mbOffX + blkX + 1] + topLine[mbOffX + blkX + 2] + topLine[mbOffX + blkX + 3] + 2) >> 2; } else { val = 128; } int off = (blkY << 4) + blkX; for (int j = 0; j < 4; j++) { residual[off] = CABAC.clip(residual[off] + val, 0, 255); residual[off + 1] = CABAC.clip(residual[off + 1] + val, 0, 255); residual[off + 2] = CABAC.clip(residual[off + 2] + val, 0, 255); residual[off + 3] = CABAC.clip(residual[off + 3] + val, 0, 255); off += 16; } }
private static int getIdxAlpha(int sliceAlphaC0Offset, int avgQp) { return(CABAC.clip(avgQp + sliceAlphaC0Offset, 0, 51)); }
public static void predictDiagonalDownRight(int[] residual, bool leftAvailable, bool topAvailable, int[] leftRow, int[] topLine, int[] topLeft, int mbOffX, int blkX, int blkY) { int off = (blkY << 4) + blkX; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { if (x > y) { int t1; if (x - y - 2 == -1) { t1 = topLeft[blkY >> 2]; } else { t1 = topLine[mbOffX + blkX + x - y - 2]; } int t2; if (x - y - 1 == -1) { t2 = topLeft[blkY >> 2]; } else { t2 = topLine[mbOffX + blkX + x - y - 1]; } int t3; if (x - y == -1) { t3 = topLeft[blkY >> 2]; } else { t3 = topLine[mbOffX + blkX + x - y]; } residual[off + x] = CABAC.clip(residual[off + x] + ((t1 + 2 * t2 + t3 + 2) >> 2), 0, 255); } else if (x < y) { int l1; if (y - x - 2 == -1) { l1 = topLeft[blkY >> 2]; } else { l1 = leftRow[blkY + y - x - 2]; } int l2; if (y - x - 1 == -1) { l2 = topLeft[blkY >> 2]; } else { l2 = leftRow[blkY + y - x - 1]; } int l3; if (y - x == -1) { l3 = topLeft[blkY >> 2]; } else { l3 = leftRow[blkY + y - x]; } residual[off + x] = CABAC.clip(residual[off + x] + ((l1 + 2 * l2 + l3 + 2) >> 2), 0, 255); } else { residual[off + x] = CABAC.clip(residual[off + x] + ((topLine[mbOffX + blkX + 0] + 2 * topLeft[blkY >> 2] + leftRow[blkY] + 2) >> 2), 0, 255); } } off += 16; } }
private static int getIdxBeta(int sliceBetaOffset, int avgQp) { return(CABAC.clip(avgQp + sliceBetaOffset, 0, 51)); }
private void filterBs(int bs, int indexAlpha, int indexBeta, int[] pels, int p2Idx, int p1Idx, int p0Idx, int q0Idx, int q1Idx, int q2Idx, bool isChroma) { int p1 = pels[p1Idx]; int p0 = pels[p0Idx]; int q0 = pels[q0Idx]; int q1 = pels[q1Idx]; int alphaThresh = alphaTab[indexAlpha]; int betaThresh = betaTab[indexBeta]; bool filterEnabled = Math.Abs(p0 - q0) < alphaThresh && Math.Abs(p1 - p0) < betaThresh && Math.Abs(q1 - q0) < betaThresh; if (!filterEnabled) { return; } // System.out.printf("%h %h %h %h %h %h %h %h\n", q3, q2, q1, q0, p0, // p1, p2, p3); int tC0 = tcs[bs - 1][indexAlpha]; bool conditionP, conditionQ; int tC; if (!isChroma) { int ap = Math.Abs(pels[p2Idx] - p0); int aq = Math.Abs(pels[q2Idx] - q0); tC = tC0 + ((ap < betaThresh) ? 1 : 0) + ((aq < betaThresh) ? 1 : 0); conditionP = ap < betaThresh; conditionQ = aq < betaThresh; } else { tC = tC0 + 1; conditionP = false; conditionQ = false; } int sigma = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); sigma = sigma < -tC ? -tC : (sigma > tC ? tC : sigma); int p0n = p0 + sigma; p0n = p0n < 0 ? 0 : p0n; int q0n = q0 - sigma; q0n = q0n < 0 ? 0 : q0n; if (conditionP) { int p2 = pels[p2Idx]; int diff = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; diff = diff < -tC0 ? -tC0 : (diff > tC0 ? tC0 : diff); int p1n = p1 + diff; pels[p1Idx] = CABAC.clip(p1n, 0, 255); } if (conditionQ) { int q2 = pels[q2Idx]; int diff = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; diff = diff < -tC0 ? -tC0 : (diff > tC0 ? tC0 : diff); int q1n = q1 + diff; pels[q1Idx] = CABAC.clip(q1n, 0, 255); } pels[q0Idx] = CABAC.clip(q0n, 0, 255); pels[p0Idx] = CABAC.clip(p0n, 0, 255); }
public void mergePrediction(int refIdxL0, int refIdxL1, nVideo.Codecs.H264.H264Const.PartPred predType, int comp, int[] pred0, int[] pred1, int off, int stride, int blkW, int blkH, int[] outs, Frame[][] refs, Frame thisFrame) { PictureParameterSet pps = sh.pps; if (sh.slice_type == SliceType.P) { if (pps.weighted_pred_flag && sh.pred_weight_table != null) { PredictionWeightTable w = sh.pred_weight_table; weight(pred0, stride, off, blkW, blkH, comp == 0 ? w.luma_log2_weight_denom : w.chroma_log2_weight_denom, comp == 0 ? w.luma_weight[0][refIdxL0] : w.chroma_weight[0][comp - 1][refIdxL0], comp == 0 ? w.luma_offset[0][refIdxL0] : w.chroma_offset[0][comp - 1][refIdxL0], outs); } else { copyPrediction(pred0, stride, off, blkW, blkH, outs); } } else { if (!pps.weighted_pred_flag || sh.pps.weighted_bipred_idc == 0 || (sh.pps.weighted_bipred_idc == 2 && predType != nVideo.Codecs.H264.H264Const.PartPred.Bi)) { mergeAvg(pred0, pred1, stride, predType, off, blkW, blkH, outs); } else if (sh.pps.weighted_bipred_idc == 1) { PredictionWeightTable w = sh.pred_weight_table; int w0 = refIdxL0 == -1 ? 0 : (comp == 0 ? w.luma_weight[0][refIdxL0] : w.chroma_weight[0][comp - 1][refIdxL0]); int w1 = refIdxL1 == -1 ? 0 : (comp == 0 ? w.luma_weight[1][refIdxL1] : w.chroma_weight[1][comp - 1][refIdxL1]); int o0 = refIdxL0 == -1 ? 0 : (comp == 0 ? w.luma_offset[0][refIdxL0] : w.chroma_offset[0][comp - 1][refIdxL0]); int o1 = refIdxL1 == -1 ? 0 : (comp == 0 ? w.luma_offset[1][refIdxL1] : w.chroma_offset[1][comp - 1][refIdxL1]); mergeWeight(pred0, pred1, stride, predType, off, blkW, blkH, comp == 0 ? w.luma_log2_weight_denom : w.chroma_log2_weight_denom, w0, w1, o0, o1, outs); } else { int tb = CABAC.clip(thisFrame.getPOC() - refs[0][refIdxL0].getPOC(), -128, 127); int td = CABAC.clip(refs[1][refIdxL1].getPOC() - refs[0][refIdxL0].getPOC(), -128, 127); int w0 = 32, w1 = 32; if (td != 0 && refs[0][refIdxL0].isShortTerm() && refs[1][refIdxL1].isShortTerm()) { int tx = (16384 + Math.Abs(td / 2)) / td; int dsf = CABAC.clip((tb * tx + 32) >> 6, -1024, 1023) >> 2; if (dsf >= -64 && dsf <= 128) { w1 = dsf; w0 = 64 - dsf; } } mergeWeight(pred0, pred1, stride, predType, off, blkW, blkH, 5, w0, w1, 0, 0, outs); } } }
private void filterBs4(int indexAlpha, int indexBeta, int[] pels, int p3Idx, int p2Idx, int p1Idx, int p0Idx, int q0Idx, int q1Idx, int q2Idx, int q3Idx, bool isChroma) { int p0 = pels[p0Idx]; int q0 = pels[q0Idx]; int p1 = pels[p1Idx]; int q1 = pels[q1Idx]; int alphaThresh = alphaTab[indexAlpha]; int betaThresh = betaTab[indexBeta]; bool filterEnabled = Math.Abs(p0 - q0) < alphaThresh && Math.Abs(p1 - p0) < betaThresh && Math.Abs(q1 - q0) < betaThresh; if (!filterEnabled) { return; } bool conditionP, conditionQ; if (isChroma) { conditionP = false; conditionQ = false; } else { int ap = Math.Abs(pels[p2Idx] - p0); int aq = Math.Abs(pels[q2Idx] - q0); conditionP = ap < betaThresh && Math.Abs(p0 - q0) < ((alphaThresh >> 2) + 2); conditionQ = aq < betaThresh && Math.Abs(p0 - q0) < ((alphaThresh >> 2) + 2); } if (conditionP) { int p3 = pels[p3Idx]; int p2 = pels[p2Idx]; int p0n = (p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4) >> 3; int p1n = (p2 + p1 + p0 + q0 + 2) >> 2; int p2n = (2 * p3 + 3 * p2 + p1 + p0 + q0 + 4) >> 3; pels[p0Idx] = CABAC.clip(p0n, 0, 255); pels[p1Idx] = CABAC.clip(p1n, 0, 255); pels[p2Idx] = CABAC.clip(p2n, 0, 255); } else { int p0n = (2 * p1 + p0 + q1 + 2) >> 2; pels[p0Idx] = CABAC.clip(p0n, 0, 255); } if (conditionQ && !isChroma) { int q2 = pels[q2Idx]; int q3 = pels[q3Idx]; int q0n = (p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4) >> 3; int q1n = (p0 + q0 + q1 + q2 + 2) >> 2; int q2n = (2 * q3 + 3 * q2 + q1 + q0 + p0 + 4) >> 3; pels[q0Idx] = CABAC.clip(q0n, 0, 255); pels[q1Idx] = CABAC.clip(q1n, 0, 255); pels[q2Idx] = CABAC.clip(q2n, 0, 255); } else { int q0n = (2 * q1 + q0 + p1 + 2) >> 2; pels[q0Idx] = CABAC.clip(q0n, 0, 255); } }