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

📄 macroblock.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* Store CBP, qp, mbType for loopfilter*/  // change cbpY order, so we do not have to modify loop filter implementation  mb->mbThis->cbp = mb->rastercbpY | (mb->cbpC << 16) |    ((mb->lumaNonzeroDC != 0) << 24) | (mb->cbpChromaDC << 25);  mb->mbThis->qp  = (int8) mb->qp;  mb->mbThis->intraModeChroma = (int8) mb->intraModeChroma;    if (mb->type == MBK_INTRA)  {    mb->mbThis->mbType = (int8)((mb->intraType == MBK_INTRA_TYPE1)       ? MB_TYPE_INTRA_4x4 : MB_TYPE_INTRA_16x16);  }  else    // mb->interMode = 2, MOT_COPY (skipped MOT_16x16)    mb->mbThis->mbType = (int8)(mb->interMode + 2);  // Copy motion vectors of the best model to motion vector buffer  for (j = 0; j < BLK_PER_MB;  j ++)    for (i = 0; i < BLK_PER_MB;  i ++)      mb->mbThis->blkInfo[j][i] = mb->current[j][i];  /*   * Update MB mode statistics   */  if (mb->type == MBK_INTRA) {    if (mb->intraType == MBK_INTRA_TYPE1)      stat->intraModeCtr1 += 1;    else      stat->intraModeCtr2[mb->intra16x16mode] += 1;  }  else    stat->interModeCtr[mb->interMode] += 1;         // temporary}void mbkModeSelection(rateCtrl_s        *pbRC,                         macroblock_s   *mb,                          meProfile_s    *pMeProf,                         refFrmBuf_s    **refBufList,                         int            nRefFrames,                          int            picType,                         encParams_s    *encPar,                         int            *mapRIR,                         int            *channelDistortion,                         int            forcedIRNo,                           int            *forcedIR,                         int      mbNum){    int i, j;  costMeasure_s intraCost, interCost, intra16x16Cost, intra4x4Cost;  double thr;  int picWidth;  int mbkPerLine;  int chromaIntraSad;  int constrainedIntra;  int chromaModeAvail[IPR_CHROMA_NUM_MODES];  int fIntra;  int8 i4x4Modes[4][4];  u_int8 colMbY[MBK_SIZE][MBK_SIZE];  u_int8 colMbC[MBK_SIZE/2][2 * (MBK_SIZE/2)];  int ssd0 = 0;  float scale;#ifndef DISABLE_RDO  encPar->rdo |=     RDO_INTRA_LUMA_4x4 |     RDO_INTRA_CHROMA |//    RDO_INTRA_LUMA_16x16 |    RDO_INTER;#endif#ifndef DISABLE_RDO  if((encPar->rdo & 0x0F) == MODE_DECISION_RDO)    scale=1.0f;  else#endif    scale=3.0f;  picWidth = encPar->picWidth;  mbkPerLine = picWidth / MBK_SIZE;  fIntra = 0;    if(encPar->nRandomIntraRefresh != 0 ) {    for (i = 0; i < encPar->nRandomIntraRefresh; i ++) {      if (mapRIR[i] == mb->mbAddr)        fIntra = 1 ;//Force Intra    }  }  // An MB is forced to be Intra Refreshed with fixed frequecy  if (encPar->sIntraRefresh != 0 && forcedIRNo > 0) {    if (forcedIR[mbNum] == 0)       fIntra=1;        forcedIR[mbNum]--;  }    constrainedIntra = encPar->constIpred && (IS_SLICE_P(picType));  getMbAvailability(mb, picWidth, constrainedIntra);  // If inter picture, find best inter mode  interCost = initCostMeasure;  // set the initial condition of the macroblock, and calculate skipPredMv  mbkLoadNeighbors(mb);  mb->qp = rc_getMBQP(pbRC,mb,picType,mb->idxY*mbkPerLine+mb->idxX);  mb->qpC = qpChroma[clip(MIN_QP, MAX_QP, mb->qp + encPar->chromaQpIdx)];  if (IS_SLICE_P(picType) && !fIntra) {      // picType == IMG_INTER    int interSad;// Do Motion Search and find the best mode based on SAD    interSad = mesFindMotionFullSearch(mb, pMeProf, refBufList, nRefFrames);      if(encPar->sIntraRefresh)    {      // get the colocated MB      mcpGetColocatedMb(mb, refBufList, colMbY, colMbC);#ifndef DISABLE_RDO      if((encPar->rdo & 0x0F) == MODE_DECISION_RDO)      {            scale=1.0f;      // calculate the MSE between current and previous MB, it will be used as a metric of channel distortion      ssd0  = CalculateSsd        (& mb->origY[0][0],     16, &colMbY[0][0],     16, 16, 16);      ssd0 += CalculateSsd        (& mb->origC[0][0],     16, &colMbC[0][0],     16, 8, 8);      ssd0 += CalculateSsd        (& mb->origC[0][0] + 8, 16, &colMbC[0][0] + 8, 16, 8, 8);      }      else#endif         {        // calculate the MSE between current and previous MB, it will be used as a metric of channel distortion      ssd0  = CalculateSad        (& mb->origY[0][0],     16, &colMbY[0][0],     16, 16, 16);      ssd0 += CalculateSad        (& mb->origC[0][0],     16, &colMbC[0][0],     16, 8, 8);      ssd0 += CalculateSad        (& mb->origC[0][0] + 8, 16, &colMbC[0][0] + 8, 16, 8, 8);      }    }  //If RDO is disabled, the best inter-mode is selected by the above function#ifndef DISABLE_RDO    mdInterModeDecision(mb, refBufList, nRefFrames, picWidth, picType,       encPar->rdo, ssd0, & interCost);#else    mdInterModeDecision(mb, refBufList, nRefFrames, picWidth, picType,       0, ssd0, & interCost);#endif    interCost.sad = interSad;    mb->actualInterSad = interSad;           // DBG    // prefer inter by 4 lambda    interCost.sad -= mb->lambda * 4;#ifndef DISABLE_RDO    if ((encPar->rdo & 0x0F) != MODE_DECISION_RDO) {#endif     interCost.cost = interCost.sad;#ifndef DISABLE_RDO    }#endif  }  // --------------------------------------------------------------------------  // Find the best 16x16 intra prediction    intra16x16Cost = initCostMeasure;  if (mb->qp >= MIN_QP + 12)    mb->intra16x16enabled = 1;  else    mb->intra16x16enabled = 0;  if (mb->intra16x16enabled) {    //   : skip whole 16x16 check when inter cost small    if ( ((pMeProf->lc3.low_complex_prof3) && (interCost.sad>TH_IPR_16x16) )            || (! pMeProf->lc3.low_complex_prof3)             || (encPar->sIntraRefresh == 1))        {#ifndef DISABLE_RDO       if(encPar->sIntraRefresh)      mdIntraPredLuma16x16(mb, picWidth, picType,            MAX_COST, encPar->rdo, & intra16x16Cost, encPar->low_complex_prof3);       else         mdIntraPredLuma16x16(mb, picWidth, picType,            interCost.sad, encPar->rdo, & intra16x16Cost, encPar->low_complex_prof3);#else       if(encPar->sIntraRefresh)      mdIntraPredLuma16x16(mb, picWidth, picType,          MAX_COST, 0, & intra16x16Cost, encPar->low_complex_prof3);       else          mdIntraPredLuma16x16(mb, picWidth, picType,             interCost.sad, 0, & intra16x16Cost, encPar->low_complex_prof3);#endif    }  }  // Find the best 4x4 intra prediction  /* Compute error threshold for doing 4x4 intra search */  if (!IS_SLICE_I(picType) #ifndef DISABLE_RDO    && (encPar->rdo & 0x0F) != MODE_DECISION_RDO#endif    )    thr = -0.000933 * (mb->qp-12) * (mb->qp-12) - 0.004673 * (mb->qp-12) + 2.133227;  else    thr = MAX_COST;  // --------------------------------------------------------------------------  // Get intra 4x4 predictions and choose best of 4x4 mode and 16x16 mode.  // Only if inter error is small enough, 4x4 intra is not checked.  intra4x4Cost = initCostMeasure;  if (IS_SLICE_I(picType) || !mb->intra16x16enabled || thr*interCost.sad > intra16x16Cost.sad && !(encPar->sIntraRefresh == 1) )  {    //  : intra pred    if (( (pMeProf->lc3.low_complex_prof3) && (intra16x16Cost.sad>TH_IPR_4x4) )         || (! pMeProf->lc3.low_complex_prof3)         || (encPar->sIntraRefresh == 1) )    {#ifndef DISABLE_RDO      if(encPar->sIntraRefresh)         mdIntraPredLuma4x4(mb, picWidth, picType, MAX_COST,         encPar->rdo & 0x0F, & intra4x4Cost, pMeProf->lc3.low_complex_prof3);      else         mdIntraPredLuma4x4(mb, picWidth, picType, interCost.sad,         encPar->rdo & 0x0F, & intra4x4Cost, pMeProf->lc3.low_complex_prof3);             #else      if(encPar->sIntraRefresh)       mdIntraPredLuma4x4(mb, picWidth, picType, MAX_COST,         0, & intra4x4Cost, pMeProf->lc3.low_complex_prof3);      else         mdIntraPredLuma4x4(mb, picWidth, picType, interCost.sad,          0, & intra4x4Cost, pMeProf->lc3.low_complex_prof3);#endif      // save i4x4 modes here, buffer "current" will be used for other purpose      for (j = 0; j < 4; j ++)        for (i = 0; i < 4; i ++)          i4x4Modes[j][i] = mb->current[j][i].i4x4Mode;    }  } #ifndef DISABLE_RDO  mdIntraModeDecision(mb, refBufList, picWidth, picType, encPar->rdo, ssd0,    & intra16x16Cost, & intra4x4Cost, & intraCost);#else  mdIntraModeDecision(mb, refBufList, picWidth, picType, 0, ssd0,    & intra16x16Cost, & intra4x4Cost, & intraCost);#endif    // --------------------------------------------------------------------------  // Choose the better one between intra and inter  if (IS_SLICE_I(picType) || (mdGetCost(mb, &intraCost,scale) < mdGetCost(mb, &interCost,scale))) {      int mbType, i, numNonPredicted;    mb->type = MBK_INTRA;            // calculate the actual SAD by excluding the syntax bits    mbType = ((IS_SLICE_P(picType)) ? 5 : 0) + streamGetMbTypeIntra      (mb->intraType, mb->intra16x16mode, 0, 0, 0);    mb->intraSyntaxBits = uvlcBitsUnsigned[mbType];     // bits on sending 4x4 intra prediction modes    if (mb->intraType == MBK_INTRA_TYPE1)    {      numNonPredicted = 0;      for (i = 0; i < 16; i ++)        if (mb->ipTab[i] >= 0)          numNonPredicted ++;      mb->intraSyntaxBits += 16 + numNonPredicted * 3;    }    mb->minSad = intraCost.sad;    mb->minActualSad = mb->actualIntraSad;    mb->minMSE = intraCost.mse;  }  else {        mb->type   = MBK_INTER;    mb->minSad = interCost.sad;    mb->minActualSad = mb->actualInterSad;    mb->minMSE = interCost.mse;  }  if(pbRC->bit_rate > 0)  {        if (      (mb->type == MBK_INTER) &&      (mb->modeMvRef[MOT_16x16][0].ref == 0) &&      (mb->modeMvRef[MOT_16x16][0].mv.x == mb->skipPredMv.x) &&      (mb->modeMvRef[MOT_16x16][0].mv.y == mb->skipPredMv.y) &&       mbNum>0)                  pbRC->currentFrame_MBQp[mbNum]=pbRC->currentFrame_MBQp[mbNum-1];          else      pbRC->currentFrame_MBQp[mbNum]=mb->qp;         }          // get the data ready for encoding  if (mb->type == MBK_INTRA)  {    if (mb->intraType == MBK_INTRA_TYPE2)      for (j = 0; j < BLK_PER_MB;  j ++)        for (i = 0; i < BLK_PER_MB;  i ++)          i4x4Modes[j][i] = IPR_MODE_DC;    for (j = 0; j < BLK_PER_MB;  j ++) {      for (i = 0; i < BLK_PER_MB;  i ++) {        mb->current[j][i].mv.x = 0;        mb->current[j][i].mv.y = 0;        mb->current[j][i].ref  = -1;    // available but intra        mb->current[j][i].i4x4Mode = i4x4Modes[j][i];      }    }       // perform chroma prediction#ifndef DISABLE_RDO    if ((encPar->rdo & 0x0F) != MODE_DECISION_RDO)#endif    {      iprGetPredChroma(mb->predIntraC, chromaModeAvail, mb->recoU, mb->recoV,         picWidth >> 1, mb->mbAvailMapIntra);      chromaIntraSad = mdIntraPredChroma(mb, chromaModeAvail, pMeProf->hadamard);    }  }  else  {    int8 interI4x4Mode;   // get the inter pixel predictors    mcpGetPred(mb, refBufList);        // set the i4x4Mode according to constrainedIntra    interI4x4Mode = (int8)((constrainedIntra) ? IPR_MODE_NA : IPR_MODE_DC);    for (j = 0; j < BLK_PER_MB;  j ++)      for (i = 0; i < BLK_PER_MB;  i ++)        mb->current[j][i].i4x4Mode = interI4x4Mode;      }  // if Intra coded, forced Intra Refresh is postponed.   if (forcedIRNo > 0 && mb->type == MBK_INTRA) {    if (forcedIR[mbNum] < 2*FORCE_INTRA_FREQUENCY)      forcedIR[mbNum] += forcedIRNo+1;  }  // update the channel distortion   if (channelDistortion) {    if (mb->type == MBK_INTRA)      channelDistortion[mb->idxY*mbkPerLine+mb->idxX] = intraCost.cDistortion;    else      channelDistortion[mb->idxY*mbkPerLine+mb->idxX] = interCost.cDistortion;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -