📄 loopfilter.c
字号:
} } }}/* * * loopChromaIntraMbEdge: * * Parameters: * dest Pixels to be filtered (U) * dir Filter direction (horiz/vert) * alphaIdx Filter alpha index * betaIdx Filter beta index * edgeDir Edge direction (horiz/vert) * dest2 Pixels to be filtered (V) * * Function: * Filter intra MB edge. * * Returns: * - * */static void loopChromaIntraMbEdge(u_int8 *dest, int dir, int alphaIdx, int betaIdx, int edgeDir, u_int8 *dest2){ int i; int alpha, beta; int delta; int orig[2*BLK_SIZE]; alpha = alphaTab[alphaIdx]; beta = betaTab[betaIdx]; for (i = 0; i < 2*MBK_SIZE/2; i++, dest+=edgeDir) { if (i == MBK_SIZE/2) dest = dest2; orig[2] = dest[-2*dir]; orig[3] = dest[ -dir]; orig[4] = dest[ 0]; orig[5] = dest[ dir]; /* The step across the block boundaries */ delta = abs(orig[3]-orig[4]); /* Find right activity parameter dr and left activity parameter dl */ if (delta < alpha && abs(orig[4]-orig[5]) < beta && abs(orig[3]-orig[2]) < beta) { dest[ -dir] = (u_int8)((orig[3] + orig[5] + 2*orig[2] + 2) >> 2); dest[ 0] = (u_int8)((orig[2] + orig[4] + 2*orig[5] + 2) >> 2); } }}/* * * filFilterMB: * * Parameters: * recoY Luminance pixels * recoU Chrominance U pixels * recoV Chrominance V pixels * 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(u_int8 *recoY, u_int8 *recoU, u_int8 *recoV, mbAttributes_s *mbData, int picWidth, int chromaQpIdx, int mbX, int mbY){ int *sliceMap; int8 *mbTab; int8 *qpTab; int *cbpTab; motVec_s *motVecs; int8 *refTab; int picWidthC, mbsPerLine, blksX, mbNum, blkNum; int mbAvailableLeft, mbAvailableUp; int bx, by, bxStart; int edgeStrH[BLK_PER_MB][BLK_PER_MB]; int edgeStrV[BLK_PER_MB][BLK_PER_MB]; motVec_s *vecPtr; int cbp, cbpTmp; int8 *refPtr; int qp, qpC; int edge_qp, edge_qpC; int filterMode; int alphaOffs; int betaOffs; int strongFilterH, strongFilterV; abIdx_s abIdx, abIdxMbEdge; abIdx_s *currAbIdx; picWidthC = picWidth>>1; /* picWidth/2 */ mbsPerLine = picWidth>>MBK_SIZE_LOG2; /* picWidth/MBK_SIZE */ blksX = picWidth>>BLK_SIZE_LOG2; /* picWidth/BLK_SIZE */ mbNum = mbY*mbsPerLine+mbX; blkNum = mbY*BLK_PER_MB*blksX+mbX*BLK_PER_MB; filterMode = mbData->filterModeTab[mbNum]; if (filterMode == 1) /* filterMode 1: loopfilter disabled */ return; alphaOffs = mbData->alphaOffset[mbNum]; betaOffs = mbData->betaOffset[mbNum]; mbTab = mbData->mbTypeTable + mbNum; qpTab = mbData->qpTable + mbNum; sliceMap = mbData->sliceMap + mbNum; /* filterMode 0: filter all edges, filterMode 2: don't filter slice edges */ mbAvailableLeft = mbX > 0 && (filterMode == 0 || (sliceMap[0] == sliceMap[-1 ])); mbAvailableUp = mbY > 0 && (filterMode == 0 || (sliceMap[0] == sliceMap[-mbsPerLine])); /* * Initialize horizontal and vertical boundary strength values */ /* If INTRA MB, stregths are 3 */ if (mbTab[0] == MBK_INTRA) { for (by = 0; by < BLK_PER_MB; by++) { edgeStrH[1][by] = edgeStrV[1][by] = 3; edgeStrH[2][by] = edgeStrV[2][by] = 3; edgeStrH[3][by] = edgeStrV[3][by] = 3; } strongFilterH = strongFilterV = 1; } else { cbpTab = mbData->cbpTable + mbNum; motVecs = mbData->motVecTable + blkNum; refTab = mbData->refIdxTable + blkNum; /* * Init. horizontal block boundary strengths */ vecPtr = motVecs; refPtr = refTab; cbp = cbpTab[0]; if (mbAvailableLeft && (mbTab[-1] != MBK_INTRA)) { strongFilterH = 0; /* Left MB is available and is not intra MB */ cbp = ((cbpTab[-1] >> 3) & 0x1111) | ((cbp << 1) & ~0x1111) | cbp; bxStart = 0; } else { strongFilterH = 1; cbp = cbp | (cbp >> 1); bxStart = 1; } /* Assign strength values to horizontal block boundaries */ for (by = 0; by < BLK_PER_MB; by++, cbp>>=4) { cbpTmp = cbp; bx = bxStart; do { if (cbpTmp & 1) edgeStrH[bx][by] = 2; else { edgeStrH[bx][by] = (refPtr[bx-1] != refPtr[bx]) || ((abs(vecPtr[bx-1].x - vecPtr[bx].x) | abs(vecPtr[bx-1].y - vecPtr[bx].y)) >= 4) ? 1 : 0; } cbpTmp >>= 1; } while (++bx < BLK_PER_MB); vecPtr += blksX; refPtr += blksX; } /* * Init. vertical block boundary strengths */ cbp = cbpTab[0]; if (mbAvailableUp && (mbTab[-mbsPerLine] != MBK_INTRA)) { strongFilterV = 0; /* Upper MB is available and is not intra MB */ cbp = ((cbpTab[-mbsPerLine] >> 12) & 0x000f) | (cbp << 4) | cbp; vecPtr = motVecs; refPtr = refTab; by = 0; } else { strongFilterV = 1; cbp = cbp | (cbp >> 4); vecPtr = motVecs + blksX; refPtr = refTab + blksX; by = 1; } /* Assign strength values to vertical block boundaries */ do { for (bx = 0; bx < BLK_PER_MB; bx++, cbp>>=1) { if (cbp & 1) edgeStrV[by][bx] = 2; else { edgeStrV[by][bx] = (refPtr[-blksX+bx] != refPtr[bx]) || ((abs(vecPtr[-blksX+bx].x - vecPtr[bx].x) | abs(vecPtr[-blksX+bx].y - vecPtr[bx].y)) >= 4) ? 1 : 0; } } vecPtr += blksX; refPtr += blksX; } while (++by < BLK_PER_MB); } /* End else (MB == INTRA) */ /* * Get qp for current MB and initialize alpha and beta indices */ qp = qpTab[0]; qpC = qpChroma[clip(MIN_QP, MAX_QP, qp+chromaQpIdx)]; abIdx.alphaIdx = clip(MIN_QP, MAX_QP, qp + alphaOffs); abIdx.betaIdx = clip(MIN_QP, MAX_QP, qp + betaOffs); abIdx.alphaIdxC = clip(MIN_QP, MAX_QP, qpC + alphaOffs); abIdx.betaIdxC = clip(MIN_QP, MAX_QP, qpC + betaOffs); /* * Initialize qp, alpha index and beta index for horizontal MB edge * and filter the MB edge */ if (mbAvailableLeft) { if (qp != qpTab[-1]) { edge_qp = (qp + qpTab[-1] + 1) >> 1; edge_qpC = (qpC + qpChroma[clip(MIN_QP, MAX_QP, qpTab[-1]+chromaQpIdx)] + 1) >> 1; abIdxMbEdge.alphaIdx = clip(MIN_QP, MAX_QP, edge_qp + alphaOffs); abIdxMbEdge.betaIdx = clip(MIN_QP, MAX_QP, edge_qp + betaOffs); abIdxMbEdge.alphaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + alphaOffs); abIdxMbEdge.betaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + betaOffs); currAbIdx = &abIdxMbEdge; } else currAbIdx = &abIdx; if (strongFilterH) { loopLumaIntraMbEdge(recoY, 1, currAbIdx->alphaIdx, currAbIdx->betaIdx, picWidth); loopChromaIntraMbEdge(recoU, 1, currAbIdx->alphaIdxC, currAbIdx->betaIdxC, picWidthC, recoV); currAbIdx = &abIdx; bx = 1; } else bx = 0; } else { currAbIdx = &abIdx; bx = 1; } /* Filter block edges */ loopLuma(recoY + bx*BLK_SIZE, 1, currAbIdx, &abIdx, picWidth, &edgeStrH[bx][0], BLK_PER_MB-bx); loopChroma(recoU + bx*(2*BLK_SIZE/2), 1, currAbIdx, &abIdx, picWidthC, &edgeStrH[2*bx][0], recoV + bx*(2*BLK_SIZE/2), (BLK_PER_MB-bx)>>1); /* * Initialize qp, alpha index and beta index for vertical MB edge * and filter intra MB edge */ if (mbAvailableUp) { if (qp != qpTab[-mbsPerLine]) { edge_qp = (qp + qpTab[-mbsPerLine] + 1) >> 1; edge_qpC = (qpC + qpChroma[clip(MIN_QP, MAX_QP, qpTab[-mbsPerLine]+chromaQpIdx)] + 1) >> 1; abIdxMbEdge.alphaIdx = clip(MIN_QP, MAX_QP, edge_qp + alphaOffs); abIdxMbEdge.betaIdx = clip(MIN_QP, MAX_QP, edge_qp + betaOffs); abIdxMbEdge.alphaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + alphaOffs); abIdxMbEdge.betaIdxC = clip(MIN_QP, MAX_QP, edge_qpC + betaOffs); currAbIdx = &abIdxMbEdge; } else currAbIdx = &abIdx; /* Filter intra MB edge in vertical direction */ if (strongFilterV) { loopLumaIntraMbEdge(recoY, picWidth, currAbIdx->alphaIdx, currAbIdx->betaIdx, 1); loopChromaIntraMbEdge(recoU, picWidthC, currAbIdx->alphaIdxC, currAbIdx->betaIdxC, 1, recoV); currAbIdx = &abIdx; by = 1; } else by = 0; } else { currAbIdx = &abIdx; by = 1; } /* Filter block edges */ loopLuma(recoY + by*BLK_SIZE*picWidth, picWidth, currAbIdx, &abIdx, 1, &edgeStrV[by][0], BLK_PER_MB-by); loopChroma(recoU + by*(2*BLK_SIZE/2)*picWidthC, picWidthC, currAbIdx, &abIdx, 1, &edgeStrV[2*by][0], recoV + by*(2*BLK_SIZE/2)*picWidthC, (BLK_PER_MB-by)>>1);}/* * * filFilterMB: * * Parameters: * recoBuf Frame buffer for reconstruction * mbData Tables of MB attributes * picWidth Frame width in pixels * picHeight Frame width in pixels * 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 picWidth, int picHeight, int chromaQpIdx){ int i, j; u_int8 *y, *u, *v; y = recoBuf->y; u = recoBuf->u; v = recoBuf->v; for (j = 0; j < picHeight/MBK_SIZE; j++) { for (i = 0; i < picWidth/MBK_SIZE; i++) { filFilterMB(y, u, v, mbData, picWidth, chromaQpIdx, i, j); y += MBK_SIZE; u += MBK_SIZE/2; v += MBK_SIZE/2; } y += (MBK_SIZE -1)*picWidth; u += (MBK_SIZE/2-1)*(picWidth>>1); v += (MBK_SIZE/2-1)*(picWidth>>1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -