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

📄 loopfilter.c

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