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

📄 motest.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 4 页
字号:
    for (m = MOT_16x8; m <= MOT_4x8; m ++)    {      sadsPtr += 16;      partSad = sadsPtr[0];      if (sadsPtr[0] < bestSad)      {        bestSad   = partSad;        *bestLazyMode = m;      }    }    break;  case MOT_4x8:    bestSad = sadsPtr[0] + sadsPtr[4];    for (m = MOT_16x8; m <= MOT_8x8; m ++)    {      sadsPtr += 16;      partSad = sadsPtr[0] + sadsPtr[4];      if (partSad < bestSad)      {        bestSad   = partSad;        *bestLazyMode = m;      }    }    break;  case MOT_8x4:    bestSad = sadsPtr[0] + sadsPtr[1];    for (m = MOT_16x8; m <= MOT_8x8; m ++)    {      sadsPtr += 16;      partSad = sadsPtr[0] + sadsPtr[1];      if (partSad < bestSad)      {        bestSad   = partSad;        *bestLazyMode = m;      }    }    break;  case MOT_8x8:    bestSad = sadsPtr[0] + sadsPtr[1] + sadsPtr[4] + sadsPtr[5];    for (m = MOT_16x8; m <= MOT_8x16; m ++)    {      sadsPtr += 16;      partSad = sadsPtr[0] + sadsPtr[1] + sadsPtr[4] + sadsPtr[5];      if (partSad < bestSad)      {        bestSad   = partSad;        *bestLazyMode = m;      }    }    break;  case MOT_8x16:    bestSad  = sadsPtr[0] + sadsPtr[1] + sadsPtr[4]  + sadsPtr[5];    bestSad += sadsPtr[8] + sadsPtr[9] + sadsPtr[12] + sadsPtr[13];    break;  case MOT_16x8:    bestSad  = sadsPtr[0] + sadsPtr[1] + sadsPtr[2] + sadsPtr[3];    bestSad += sadsPtr[4] + sadsPtr[5] + sadsPtr[6] + sadsPtr[7];    break;  }  return bestSad;}/* * mesPrepareProfile: * * Parameters: *      pMeProf             Parameters for controlling ME *      pRefFrm             Reference frame buffer to provide frame information *      encPar              Encoding parameters (motion range, etc.) *      nRefFrames          Number of reference frames * * Function: *      Prepare the structure for controlling the ME.  * * Returns: *      - */void mesPrepareProfile(meProfile_s *pMeProf,                        refFrmBuf_s *pRefFrm,                       encParams_s *encPar,                       int         nRefFrames){  int i, j;  // at least 1 reference frame  pMeProf->area0[0] = pRefFrm->searchArea.x0;  pMeProf->area1[0] = pRefFrm->searchArea.x1;  pMeProf->area0[1] = pRefFrm->searchArea.y0;  pMeProf->area1[1] = pRefFrm->searchArea.y1;  // Hadamard transform is not used in MODE_DECISION_SIMPLE mode#ifndef DISABLE_RDO  pMeProf->hadamard = ! ((encPar->rdo & 0x0F) == MODE_DECISION_SIMPLE);  pMeProf->profile  =     (encPar->profile << 4) | ((encPar->rdo & 0x0F) == MODE_DECISION_RDO);#else  pMeProf->hadamard = 1;  pMeProf->profile  = encPar->profile << 4;#endif  pMeProf->interModeFlags = encPar->modeFlags;    // from MOT_16x16 to MOT_4x4  // for reference frame 0, MOT_16x16  for (i = 0; i < 2; i ++)    for (j = 0; j < 2; j ++)      pMeProf->range[i][j] = (int16) (encPar->range * 4);  // half range for other modes  if (encPar->rangeMod & 1)    for (j = 0; j < 2; j ++)      pMeProf->range[1][j] >>= 1;  // half range for other reference frames  if (encPar->rangeMod & 2)    for (i = 0; i < 2; i ++)      pMeProf->range[i][1] >>= 1;  for (i = 0; i < 2; i ++)    for (j = 0; j < 2; j ++)      if (pMeProf->range[i][j] < 16)        // scaled up by 4        pMeProf->range[i][j] = 16;  if ((pMeProf->profile >> 4) == PROF_CODING_SPEED)  {    pMeProf->searchCtrFlag = 0;    pMeProf->pruneTreeFlag = 1;                   // 0 or 1    pMeProf->pruneThUnit   = 5;    pMeProf->subsampling   = 8;                     // 4, 8, 16  }  else  {    pMeProf->searchCtrFlag  = 0;#ifndef DISABLE_RDO    if ((encPar->rdo & 0x0F) == MODE_DECISION_RDO)      pMeProf->pruneTreeFlag = 0;                 // 0 or 1    else#endif      pMeProf->pruneTreeFlag = 1;                 // 0 or 1    pMeProf->pruneThUnit    = 1;    pMeProf->subsampling = 4;                     // 4, 8, 16  }  // can not support this feature if there are multiple reference frames  if (nRefFrames > 1)    pMeProf->pruneTreeFlag  = 0;                  // 0 or 1}int PrecomputeRefPointers(macroblock_s *pMb,                          refFrmBuf_s  **refBufList,                           int          nRefFrames,                             u_int8       *refBlkPtrs[][16],                          u_int16      *refPartSum[]){  int i, j;  int refWidth;  // pre-compute all the reference block pointers,    refWidth = refBufList[0]->yBufWidth;  for (i = 0; i < nRefFrames; i ++)  {    u_int8 *refMbPtr;    refFrmBuf_s *pRefFrm;    pRefFrm = refBufList[i];    refMbPtr = pRefFrm->y + (pMb->idxY * MBK_SIZE << 1) * refWidth +       (pMb->idxX * MBK_SIZE << 1);    // refPartSum is not used that often, so only compute the MB pointer    refPartSum[i] = pRefFrm->partSums +       (pMb->idxY * MBK_SIZE) * (refWidth >> 1) + (pMb->idxX * MBK_SIZE);    for (j = 0; j < BLK_PER_MB * BLK_PER_MB; j ++)    {      int k;      k = j % 4;      refBlkPtrs[i][j] = refMbPtr + (k * BLK_SIZE << 1);      if (k == 3)        refMbPtr += refWidth * (BLK_SIZE << 1);    }  }  return refWidth;}/* * mesBasicMode: * * Parameters: *      pMb                 Macroblock information *      pMeProf             Parameters for controlling ME *      mbPart              Define a region within macroblock *      refBlkPtrs          Pointers to blocks in the reference MB *      refPartSum          Partial sum of blocks in reference MB *      mode                Prediction mode, define prediction block size *      blkMvBits           Number of MV bits of this block * * Function: *      Search the best vectors for one of basic modes: 16x16, 16x8, 8x16,  *      8x8, 8x4, 4x8, 4x4.  * * Returns: *      Minimal SAD for the MB or sub-MB being predicted. */static int mesBasicMode(macroblock_s *pMb,                         meProfile_s  *pMeProf,                        mbPart_s     *mbPart,                         u_int8       **refBlkPtrs,                         u_int16      *refPartSum,                        int          mode,                        int          *blkMvBits){  int bestLazyMode;  int16 *blkSadsBuf;  motVec_s predVec, bestVec;  blkState_s *current;  int mbPartSad, mpBlkAddr;  mpBlkAddr  = mbPart->y0 * BLK_PER_MB + mbPart->x0;  current    = & pMb->current[mbPart->y0][mbPart->x0];  blkSadsBuf = & pMeProf->blkSADs[current->ref][mode][0];  predVec    = mcpFindPredMv(pMb, current->ref, mode, mpBlkAddr);  mbPart->vlcMvBitsX = uvlcBitsSigned - predVec.x + 511;  mbPart->vlcMvBitsY = uvlcBitsSigned - predVec.y + 511;  // should we perform search at all?  bestLazyMode = mode;  mbPartSad    = 0;  // perform this only for the last reference frame  if (pMeProf->pruneTreeFlag && (mode > MOT_16x16))  {    mbPartSad = mesBlockLazyMatch(      & pMeProf->blkSADs[0][MOT_16x16][mpBlkAddr], mode, & bestLazyMode);    if (mbPartSad >= modeNumBlocks[mode] * pMeProf->pruneTreeTh)      bestLazyMode = mode;               // set it to the original mode    //else bestLazyMode should be set to be < mode  }  if (bestLazyMode == mode)  {    mesDetermineSearchRegion(pMeProf, & predVec, pMb, mbPart);    mbPart->orig = & pMb->origY[mbPart->y0 * BLK_SIZE][mbPart->x0 * BLK_SIZE];    // Motion block position in reference frame    // y has been upsampled    mbPart->ref  = refBlkPtrs[mpBlkAddr];    if (mode <= MOT_8x8)    {      // SEA is only performed when size is 8x8 or up      mbPart->partSum = (int *) pMb->partSums + mpBlkAddr;      mbPart->refPartSum = refPartSum +         (mbPart->y0 * BLK_SIZE) * (mbPart->refWidth >> 1) +         (mbPart->x0 * BLK_SIZE);    }    if (pMeProf->lc3.low_complex_prof3)          bestVec = mesFindMotionBlock_fast(mbPart, pMeProf, & mbPartSad );    else      bestVec = mesFindMotionBlock(mbPart, pMeProf, & mbPartSad);    // we will calculate the sad after Hadamard anyway    if (pMeProf->hadamard)      mbPartSad = findSATD4Blk(mbPart->orig, mbPart->ref, mbPart->refWidth,         mbPart->width, mbPart->height, bestVec.x, bestVec.y, & blkSadsBuf[mpBlkAddr]   );    else      mbPartSad = findSAD4Blk(mbPart->orig, mbPart->ref, mbPart->refWidth,         mbPart->width, mbPart->height, bestVec.x, bestVec.y, & blkSadsBuf[mpBlkAddr]);    /* Favor 16x16 blocks that have zero motion */    if (mbPart->mode == MOT_16x16)    {      if ((bestVec.x | bestVec.y) == 0)        mbPartSad -= mbPart->lambda * ZERO_VEC_SAD;    }  }  else  {    // no additional search, but need to calculate SAD    // get MV from skipMotVecs as the best vector, only need 1 MV as area    // sharing the same vector in skipMotVecs always larger than size of     // current partition, ME is from large to small partitions.    // do not need to copy blkSADs and skipMotVecs to the current mode,     // as blkSADs of the current mode has been set to a large value,     // current mode will never be picked as a replacement.    if (bestLazyMode < MOT_8x8)      bestVec = pMb->modeMvRef[bestLazyMode][mpBlkAddr].mv;    else      bestVec = pMb->skipMVs[bestLazyMode - MOT_8x8][mpBlkAddr];  }  // only need to copy this one position, others will be filled later  current[0].mv = bestVec;  // add the motion vector to the overall SAD  *blkMvBits = mbPart->vlcMvBitsX[bestVec.x] + mbPart->vlcMvBitsY[bestVec.y];  mbPartSad += mbPart->lambda * (*blkMvBits);  return mbPartSad;}int encoRecoBlock(u_int8 origBlk[][MBK_SIZE],                   u_int8 predBlk[][MBK_SIZE],                   int    coeff[BLK_SIZE][BLK_SIZE],                  u_int8 *reco,                   int    recoWidth,                   int    picType,                  int    qp);/* * mesMbPartCost: * * Parameters: *      pMb                 Macroblock information *      refBlkPtrs          Pointers to blocks in the reference MB *      refWidth            Reference buffer width *      mpX0                Addr of 1st 4x4 block, X *      mpY0                Addr of 1st 4x4 block, Y *      mbPartW             Width of the MB partition, in 4x4 blocks *      mbPartH             Height of the MB partition, in 4x4 blocks *      pMse                For getting the MSE * * Function: *      Evaluate the cost of encoding the MB partition.  * * Returns: *      Number of bits spent on encoding the MB partition. */int mesMbPartCost(macroblock_s *pMb,                   u_int8       *refBlkPtrs[16],                   int          refWidth,                  int          mpX0,                   int          mpY0,                   int          mbPartW,                   int          mbPartH,                  int          *pMse){  int i, j, bits, mse, numCoefs, numNonZeroBlks, nonZero;  u_int8 predBlk[4][16], reco[16];  int coeff[4][4];  bits = 0;  mse  = 0;  numNonZeroBlks = 0;  for (j = mpY0; j < mpY0 + mbPartH; j ++)  {    for (i = mpX0; i < mpX0 + mbPartW; i ++)    {      u_int8 *origBlk, *refBlk;      blkState_s *blkInfo;      if (mbPartH + mbPartW == 4)         // MOT_8x8        blkInfo = & pMb->current[j][i];      else        blkInfo = & pMb->current[mpY0][mpX0];      origBlk = & pMb->origY[j * BLK_SIZE][i * BLK_SIZE];      // get the quarter-pixel interpolated luminance predictor      refBlk = refBlkPtrs[j * 4 + i] + (blkInfo->mv.y >> 1) * refWidth + (blkInfo->mv.x >> 1);      mcpGetQuarterPixels(refBlk, refWidth, blkInfo->mv.x, blkInfo->mv.y, 4, 4, predBlk);      nonZero = encoRecoBlock((u_int8 (*)[MBK_SIZE]) origBlk, predBlk, coeff, reco, 4, SLICE_P, pMb->qp);      if (nonZero)        numNonZeroBlks ++;      mse += CalculateSsd(origBlk, MBK_SIZE, reco, 4, BLK_SIZE, BLK_SIZE);      bibInit(& pMb->mbBs);      bits += streamSend4x4Blk(& pMb->mbBs, pMb, 1, COMP_LUMA, i, j,         coeff, BLK_CAT_Y, & numCoefs);      blkInfo->numLumaCoefs = (int8) numCoefs;    }  }  if (numNonZeroBlks == 0)

⌨️ 快捷键说明

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