protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mpCb, int[][] mpCr) { var maxW = Macroblock.MbChromaWidth; var maxH = Macroblock.MbChromaHeight; if (!access.IsLeftAvailable(maxH)) return false; var p = new Point(); // predC[ x, y ] = p[ -1, y ], // with x = 0..MbWidthC - 1 and y = 0..MbHeightC - 1 for (var i = 0; i < maxH; i++) { access.GetNeighbour(-1, i, maxW, maxH, p); for (var j = 0; j < maxW; j++) { mpCb[i][j] = codedFrameBuffer.GetCb8Bit(p.X, p.Y); mpCr[i][j] = codedFrameBuffer.GetCr8Bit(p.X, p.Y); } } return true; }
protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mpCb, int[][] mpCr) { var p = new Point(); var maxW = Macroblock.MbChromaWidth; var maxH = Macroblock.MbChromaHeight; var upAvail = access.IsUpAvailable(maxW); var leftAvail = access.IsLeftAvailable(maxH); // For each chroma block of 4x4 samples indexed by // chroma4x4BlkIdx = 0..( 1 << ( ChromaArrayType + 1 ) ) – 1 for (var chroma4X4BlkIdx = 0; chroma4X4BlkIdx < 4; chroma4X4BlkIdx++) { var predCb = 0; var predCr = 0; var sumUpCb = 0; var sumUpCr = 0; var sumLeftCb = 0; var sumLeftCr = 0; var xO = PosX(chroma4X4BlkIdx); var yO = PosY(chroma4X4BlkIdx); // sum(x' = 0 to 3) { p[x' + xO, -1] } if (upAvail) { for (var i = 0; i < ChromaBlkWidth; i++) { access.GetNeighbour(i, -1, maxW, maxH, p); sumUpCb += codedFrameBuffer.GetCb8Bit(p.X + xO, p.Y); sumUpCr += codedFrameBuffer.GetCr8Bit(p.X + xO, p.Y); } } // sum(y' = 0 to 3) { p[-1, y' + yO] } if (leftAvail) { for (var i = 0; i < ChromaBlkHeight; i++) { access.GetNeighbour(-1, i, maxW, maxH, p); sumLeftCb += codedFrameBuffer.GetCb8Bit(p.X, p.Y + yO); sumLeftCr += codedFrameBuffer.GetCr8Bit(p.X, p.Y + yO); } } // TOP-LEFT and BOTTOM-RIGHT if (((xO == 0) && (yO == 0)) || ((xO > 0) && (yO > 0))) { if (upAvail && leftAvail) { // predC[x+xO, y+yO] = (sumUp + sumLeft + 4) >> 3 predCb = (sumUpCb + sumLeftCb + 4) >> 3; predCr = (sumUpCr + sumLeftCr + 4) >> 3; } else if (leftAvail) { // predC[x+xO, y+yO] = (sumLeft + 2) >> 2 predCb = (sumLeftCb + 2) >> 2; predCr = (sumLeftCr + 2) >> 2; } else if (upAvail) { // predC[x+xO, y+yO] = (sumUp + 2) >> 2 predCb = (sumUpCb + 2) >> 2; predCr = (sumUpCr + 2) >> 2; } else { // predC[x+xO, y+yO] = (1 << ( BitDepthC – 1 )) predCb = 1 << (bitDepthC - 1); predCr = 1 << (bitDepthC - 1); } } // TOP-RIGHT else if ((xO > 0) && (yO == 0)) { if (upAvail) { // predC[x+xO, y+yO] = (sumUp + 2) >> 2 predCb = (sumUpCb + 2) >> 2; predCr = (sumUpCr + 2) >> 2; } else if (leftAvail) { // predC[x+xO, y+yO] = (sumLeft + 2) >> 2 predCb = (sumLeftCb + 2) >> 2; predCr = (sumLeftCr + 2) >> 2; } else { // predC[x+xO, y+yO] = (1 << ( BitDepthC – 1 )) predCb = 1 << (bitDepthC - 1); predCr = 1 << (bitDepthC - 1); } } // BOTTOM-LEFT else if ((xO == 0) && (yO > 0)) { if (leftAvail) { // predC[x+xO, y+yO] = (sumLeft + 2) >> 2 predCb = (sumLeftCb + 2) >> 2; predCr = (sumLeftCr + 2) >> 2; } else if (upAvail) { // predC[x+xO, y+yO] = (sumUp + 2) >> 2 predCb = (sumUpCb + 2) >> 2; predCr = (sumUpCr + 2) >> 2; } else { // predC[x+xO, y+yO] = (1 << ( BitDepthC – 1 )) predCb = 1 << (bitDepthC - 1); predCr = 1 << (bitDepthC - 1); } } // store DC prediction for (var j = yO; j < ChromaBlkHeight + yO; j++) { for (var i = xO; i < ChromaBlkWidth + xO; i++) { mpCb[j][i] = predCb; mpCr[j][i] = predCr; } } } return true; }
protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mpCb, int[][] mpCr) { var maxW = Macroblock.MbChromaWidth; var maxH = Macroblock.MbChromaHeight; var upAvail = access.IsUpAvailable(maxW); var leftAvail = access.IsLeftAvailable(maxH); var leftUpAvail = access.IsLeftUpAvailable(); if (!upAvail || !leftAvail || !leftUpAvail) return false; // Note: used (chroma_block_width >> 1) instead of (xCF + 4) // Note: used (chroma_block_height >> 1) instead of (yCF + 4) var hCb = 0; var vCb = 0; var hCr = 0; var vCr = 0; var pUp = new Point(); var pLeft = new Point(); var pLeftUp = new Point(); access.GetNeighbour(0, -1, maxW, maxH, pUp); access.GetNeighbour(-1, 0, maxW, maxH, pLeft); access.GetNeighbour(-1, -1, maxW, maxH, pLeftUp); // H = sum(x' = 0 to (3 + xCF)){ (x'+1) * (p[4 + xCF + x', -1] - p[2 + xCF -x', -1]) } for (var i = 1; i <= (maxW >> 1); i++) { var x = i - 1; // x' hCb += i*(codedFrameBuffer.GetCb8Bit(pUp.X + (maxW >> 1) + x, pUp.Y) - codedFrameBuffer.GetCb8Bit(pUp.X + (maxW >> 1) - 2 - x, pUp.Y)); hCr += i*(codedFrameBuffer.GetCr8Bit(pUp.X + (maxW >> 1) + x, pUp.Y) - codedFrameBuffer.GetCr8Bit(pUp.X + (maxW >> 1) - 2 - x, pUp.Y)); } // V = sum(y' = 0 to (3 + yCF)){ (y'+1) * (p[-1, 4 + yCF + y'] - p[-1, 2 + yCF - y']) } for (var i = 1; i <= (maxH >> 1); i++) { var y = i - 1; // y' vCb += i*(codedFrameBuffer.GetCb8Bit(pLeft.X, pLeft.Y + (maxH >> 1) + y) - codedFrameBuffer.GetCb8Bit(pLeft.X, pLeft.Y + (maxH >> 1) - 2 - y)); vCr += i*(codedFrameBuffer.GetCr8Bit(pLeft.X, pLeft.Y + (maxH >> 1) + y) - codedFrameBuffer.GetCr8Bit(pLeft.X, pLeft.Y + (maxH >> 1) - 2 - y)); } // a = 16 * ( p[ -1, MbHeightC - 1 ] + p[ MbWidthC - 1, -1 ] ) var aCb = 16*(codedFrameBuffer.GetCb8Bit(pLeft.X, pLeft.Y + maxH - 1) + codedFrameBuffer.GetCb8Bit(pUp.X + maxH - 1, pUp.Y)); var aCr = 16*(codedFrameBuffer.GetCr8Bit(pLeft.X, pLeft.Y + maxH - 1) + codedFrameBuffer.GetCr8Bit(pUp.X + maxH - 1, pUp.Y)); // b = ( ( 34 – 29 * ( ChromaArrayType == 3 ) ) * H + 32 ) >> 6 var bCb = ((maxW == 8 ? 17 : 5)*hCb + 2*maxW) >> (maxW == 8 ? 5 : 6); var bCr = ((maxW == 8 ? 17 : 5)*hCr + 2*maxW) >> (maxW == 8 ? 5 : 6); // c = ( ( 34 – 29 * ( ChromaArrayType != 1 ) ) * V + 32 ) >> 6 var cCb = ((maxH == 8 ? 17 : 5)*vCb + 2*maxH) >> (maxH == 8 ? 5 : 6); var cCr = ((maxH == 8 ? 17 : 5)*vCr + 2*maxH) >> (maxH == 8 ? 5 : 6); // predC[ x, y ] = Clip1C( ( a + b * ( x – 3 – xCF ) + c * ( y – 3 – yCF ) + 16 ) >> 5 ), // with x = 0..MbWidthC - 1 and y = 0..MbHeightC - 1 for (var j = 0; j < maxH; j++) { for (var i = 0; i < maxW; i++) { var predCb = (aCb + (i - (maxW >> 1) + 1)*bCb + (j - (maxH >> 1) + 1)*cCb + 16) >> 5; var predCr = (aCr + (i - (maxW >> 1) + 1)*bCr + (j - (maxH >> 1) + 1)*cCr + 16) >> 5; mpCb[j][i] = MathHelper.Clip(maxImagePelValue, predCb); mpCr[j][i] = MathHelper.Clip(maxImagePelValue, predCr); } } return true; }