⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loopfilter.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 2 页
字号:
      }    }  }}/* * * 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 + -