📄 loopfilter.c
字号:
dest[-dir] = (u_int8)clip(0, 255, orig[3]+diff); dest[ 0] = (u_int8)clip(0, 255, orig[4]-diff); } } }}/* * * filFilterMB: * * Parameters: * recoBuf Frame buffer for reconstruction * mbData Table of MB attributes * picWidth Frame width in pixels * chromaQpIdx Chroma QP index relative to luma QP * alphaOffs Filter alpha offset * betaOffs Filter beta offset * mbX Macroblocks horizontal position * mbY Macroblocks vertical position * * Function: * Apply loopfilter on macroblock. * * Returns: * - * */void filFilterMB(frmBuf_s *recoBuf, mbAttributes_s *mbData, int chromaQpIdx, int mbX, int mbY){ motVec_s *motVecs; int8 *refTab; int mbsPerLine, blksX, mbAddr; int mbAvailableLeft, mbAvailableUp; int bx, by; int edgeStr[BLK_PER_MB][BLK_PER_MB][2]; motVec_s *vecPtr; int cbp; u_int8 *recoY, *recoU, *recoV; int str; int8 *refPtr; int qp, qpC; int edge_qp, edge_qpC; abIdx_s abIdx[2]; abIdx_s *currAbIdx; int filterMode; int alphaOffs; int betaOffs; int picWidth, picWidthC; mbState_s *pMbState, *pMbStateLeft, *pMbStateTop; motVecs = mbData->motVecTable; refTab = mbData->refIdxTable; picWidth = recoBuf->width; mbsPerLine = picWidth/MBK_SIZE; blksX = picWidth/BLK_SIZE; mbAddr = mbY*mbsPerLine+mbX; pMbState = mbData->mbStateArr + mbAddr; pMbStateLeft = pMbState - 1; pMbStateTop = pMbState - mbsPerLine; filterMode = pMbState->filterMode; alphaOffs = pMbState->alphaOffset; betaOffs = pMbState->betaOffset; qp = pMbState->qp; qpC = qpChroma[clip(MIN_QP, MAX_QP, qp + chromaQpIdx)]; if (filterMode == 1) /* filterMode 1: loopfilter disabled */ return; /* filterMode 0: filter all edges, filterMode 2: don't filter slice edges */ mbAvailableLeft = mbX > 0 && (filterMode == 0 || pMbState->sliceMap == pMbStateLeft->sliceMap); mbAvailableUp = mbY > 0 && (filterMode == 0 || pMbState->sliceMap == pMbStateTop->sliceMap); /* * Initialize horizontal and vertical boundary strength values */ /* If INTRA MB, stregths are 4 and 3 */ if (pMbState->mbType <= MB_TYPE_INTRA_16x16) { for (by = 0; by < BLK_PER_MB; by++) { edgeStr[by][0][0] = edgeStr[0][by][1] = 4; for (bx = 1; bx < BLK_PER_MB; bx++) { edgeStr[by][bx][0] = edgeStr[bx][by][1] = 3; } } } else { vecPtr = &motVecs[mbY*BLK_PER_MB*blksX+mbX*BLK_PER_MB]; refPtr = &refTab[mbY*BLK_PER_MB*blksX+mbX*BLK_PER_MB]; /* Init. horizontal boundary strengths at the MB edge */ if (mbAvailableLeft) { if (pMbStateLeft->mbType <= MB_TYPE_INTRA_16x16) { edgeStr[0][0][0] = edgeStr[1][0][0] = edgeStr[2][0][0] = edgeStr[3][0][0] = 4; } else { /* To see if at least 1 of 2 blocks at left MB edge are non-zero */ cbp = (pMbStateLeft->cbp >> 3) | pMbState->cbp; for (by = 0; by < BLK_PER_MB; by++, cbp>>=4) { if (cbp & 1) edgeStr[by][0][0] = 2; else edgeStr[by][0][0] = (refPtr[by*blksX-1] != refPtr[by*blksX]) || ((abs(vecPtr[by*blksX-1].x - vecPtr[by*blksX].x) | abs(vecPtr[by*blksX-1].y - vecPtr[by*blksX].y)) >= 4) ? 1 : 0; } } } /* Init. vertical boundary strengths at the MB edge */ if (mbAvailableUp) { if (pMbStateTop->mbType <= MB_TYPE_INTRA_16x16) { edgeStr[0][0][1] = edgeStr[0][1][1] = edgeStr[0][2][1] = edgeStr[0][3][1] = 4; } else { /* To see if at least 1 of 2 blocks at top MB edge are non-zero */ cbp = (pMbStateTop->cbp >> 12) | pMbState->cbp; for (bx = 0; bx < BLK_PER_MB; bx++, cbp>>=1) { if (cbp & 1) edgeStr[0][bx][1] = 2; else edgeStr[0][bx][1] = (refPtr[-blksX+bx] != refPtr[bx]) || ((abs(vecPtr[-blksX+bx].x - vecPtr[bx].x) | abs(vecPtr[-blksX+bx].y - vecPtr[bx].y)) >= 4) ? 1 : 0; } } } /* Init. horizontal block boundary strengths */ /* To see if at least 1 of 2 blocks at inner block V edge are non-zero */ cbp = (pMbState->cbp >> 1) | pMbState->cbp; for (by = 0; by < BLK_PER_MB; by++, cbp>>=1) { for (bx = 1; bx < BLK_PER_MB; bx++, cbp>>=1) { if (cbp & 1) edgeStr[by][bx][0] = 2; else edgeStr[by][bx][0] = (refPtr[by*blksX+bx-1] != refPtr[by*blksX+bx]) || ((abs(vecPtr[by*blksX+bx-1].x - vecPtr[by*blksX+bx].x) | abs(vecPtr[by*blksX+bx-1].y - vecPtr[by*blksX+bx].y)) >= 4) ? 1 : 0; } } /* Init. vertical block boundary strengths */ /* To see if at least 1 of 2 blocks at inner block V edge are non-zero */ cbp = (pMbState->cbp >> 4) | pMbState->cbp; for (by = 1; by < BLK_PER_MB; by++) { for (bx = 0; bx < BLK_PER_MB; bx++, cbp>>=1) { if (cbp & 1) edgeStr[by][bx][1] = 2; else edgeStr[by][bx][1] = (refPtr[(by-1)*blksX+bx] != refPtr[by*blksX+bx]) || ((abs(vecPtr[(by-1)*blksX+bx].x - vecPtr[by*blksX+bx].x) | abs(vecPtr[(by-1)*blksX+bx].y - vecPtr[by*blksX+bx].y)) >= 4) ? 1 : 0; } } } /* End else (MB == INTRA) */ picWidthC = picWidth>>1; /* picWidth/2 */ recoY = recoBuf->y + mbY*MBK_SIZE *picWidth + mbX*MBK_SIZE; recoU = recoBuf->u + mbY*(MBK_SIZE/2)*picWidthC + mbX*(MBK_SIZE/2); recoV = recoBuf->v + mbY*(MBK_SIZE/2)*picWidthC + mbX*(MBK_SIZE/2); abIdx[1].alphaIdx = clip(MIN_QP, MAX_QP, qp + alphaOffs); abIdx[1].betaIdx = clip(MIN_QP, MAX_QP, qp + betaOffs); abIdx[1].alphaIdxC = clip(MIN_QP, MAX_QP, qpC + alphaOffs); abIdx[1].betaIdxC = clip(MIN_QP, MAX_QP, qpC + betaOffs); /* * Filtering in horizontal direction */ if (mbAvailableLeft) { if (qp != pMbStateLeft->qp) { edge_qp = (qp + pMbStateLeft->qp + 1) >> 1; edge_qpC = (qpC + qpChroma[clip(MIN_QP, MAX_QP, pMbStateLeft->qp+chromaQpIdx)] + 1) >> 1; abIdx[0].alphaIdx = clip(MIN_QP, MAX_QP, edge_qp + alphaOffs); abIdx[0].betaIdx = clip(MIN_QP, MAX_QP, edge_qp + betaOffs); abIdx[0].alphaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + alphaOffs); abIdx[0].betaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + betaOffs); currAbIdx = &abIdx[0]; } else currAbIdx = &abIdx[1]; bx = 0; } else { currAbIdx = &abIdx[1]; bx = 1; } for (; bx < BLK_PER_MB; bx++) { for (by = 0; by < BLK_PER_MB; by++) { str = edgeStr[by][bx][0]; if (str > 0) { loopLuma(&recoY[by*BLK_SIZE*picWidth+bx*BLK_SIZE], 1, currAbIdx->alphaIdx, currAbIdx->betaIdx, picWidth, str); if ((bx&1) == 0) { loopChroma(&recoU[by*(BLK_SIZE/2)*picWidthC+bx*(BLK_SIZE/2)], 1, currAbIdx->alphaIdxC, currAbIdx->betaIdxC, picWidthC, str, &recoV[by*(BLK_SIZE/2)*picWidthC+bx*(BLK_SIZE/2)]); } } } currAbIdx = &abIdx[1]; } /* * Filtering in vertical direction */ if (mbAvailableUp) { if (qp != pMbStateTop->qp) { edge_qp = (qp + pMbStateTop->qp + 1) >> 1; edge_qpC = (qpC + qpChroma[clip(MIN_QP, MAX_QP, pMbStateTop->qp+chromaQpIdx)] + 1) >> 1; abIdx[0].alphaIdx = clip(MIN_QP, MAX_QP, edge_qp + alphaOffs); abIdx[0].betaIdx = clip(MIN_QP, MAX_QP, edge_qp + betaOffs); abIdx[0].alphaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + alphaOffs); abIdx[0].betaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + betaOffs); currAbIdx = &abIdx[0]; } else currAbIdx = &abIdx[1]; by = 0; } else { currAbIdx = &abIdx[1]; by = 1; } for (; by < BLK_PER_MB; by++) { for (bx = 0; bx < BLK_PER_MB; bx++) { str = edgeStr[by][bx][1]; if (str > 0) { loopLuma(&recoY[by*BLK_SIZE*picWidth+bx*BLK_SIZE], picWidth, currAbIdx->alphaIdx, currAbIdx->betaIdx, 1, str); if ((by&1) == 0) { loopChroma(&recoU[by*(BLK_SIZE/2)*picWidthC+bx*(BLK_SIZE/2)], picWidthC, currAbIdx->alphaIdxC, currAbIdx->betaIdxC, 1, str, &recoV[by*(BLK_SIZE/2)*picWidthC+bx*(BLK_SIZE/2)]); } } } currAbIdx = &abIdx[1]; }}/* * * filFilterMB: * * Parameters: * recoBuf Frame buffer for reconstruction * mbData Tables of MB attributes * chromaQpIdx Chroma QP index relative to luma QP * alphaOffs Filter alpha offset * betaOffs Filter beta offset * * Function: * Apply loopfilter on frame buffer. * * Returns: * - * */void filFilterFrame(frmBuf_s *recoBuf, mbAttributes_s *mbData, int chromaQpIdx){ int i, j; for (j = 0; j < recoBuf->height/MBK_SIZE; j++) { for (i = 0; i < recoBuf->width/MBK_SIZE; i++) { filFilterMB(recoBuf, mbData, chromaQpIdx, i, j); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -