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

📄 meutility.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 3 页
字号:
void matchBlockLong(mbPart_s *mbPart,                     int startX, int stopX, int startY, int stopY,                     int step,                     motVec_s *bestVec,                    int *bestSad,                    int low_complex_prof3){  motVec_s lclBestVec;  int j, vecX, vecY;  int currSad;  int lclBestSad;  int overhead;  int refW, blkH;  int lambda;  int partialSum = 0;  int *origPsPtr;  u_int16 *refPsPtr;  u_int8 *refLine, *refPtr, *orig;  u_int16 *refPsLine;   const int8 *vlcMvBitsX;  // *retSad should have the SAD of the best estimate already  // could be INT_MAX if such an estimate is not available  lclBestSad = *bestSad;  lclBestVec = *bestVec;  blkH = mbPart->height;  orig = mbPart->orig;  refW = mbPart->refWidth;  lambda = mbPart->lambdaCoarse;  vlcMvBitsX = mbPart->vlcMvBitsX;  switch (mbPart->width)  {  case 4:    /* Scan motion vectors within search area */    for (vecY = startY; vecY <= stopY; vecY += step) {      refLine   = & mbPart->ref[(vecY >> 1) * refW];      overhead = (int) mbPart->vlcMvBitsY[vecY] * lambda;      for (vecX = startX; vecX <= stopX; vecX += step) {        /* Take into account number fo bits spent for motion vector */        currSad = lambda * vlcMvBitsX[vecX] + overhead;        /* Accumulate sad until no pels left or sad is worse than best so far */        if (currSad < lclBestSad) {          refPtr = refLine + (vecX >> 1);          findSAD2_4x(orig, refPtr, refW, blkH, currSad, lclBestSad, j);          if (currSad < lclBestSad) {            lclBestSad   = currSad;            lclBestVec.x = (int16)vecX;            lclBestVec.y = (int16)vecY;          }        }      }    }    break;  case 8:    /* Scan motion vectors within search area */    for (vecY = startY; vecY <= stopY; vecY += step) {      refPsLine = & mbPart->refPartSum[(vecY >> 2) * (refW >> 1)];      refLine = & mbPart->ref[(vecY >> 1) * refW];      overhead = (int) mbPart->vlcMvBitsY[vecY] * lambda;      for (vecX = startX; vecX <= stopX; vecX += step) {        /* Take into account number fo bits spent for motion vector */        currSad = lambda * vlcMvBitsX[vecX] + overhead;       // calculate the partial results here                // : take away partial sum        if (!low_complex_prof3) {          refPsPtr = refPsLine + (vecX >> 2);           origPsPtr = mbPart->partSum;          partialSum = 0;          if (blkH >= 8)            partialSum  = abs(refPsPtr[0] - origPsPtr[0]);          if (blkH == 16)            partialSum += abs(refPsPtr[4 * refW] - origPsPtr[8]);        }        /* Accumulate sad until no pels left or sad is worse than best so far */        // : take away partial sum        if  ( (  (!low_complex_prof3) && (partialSum + currSad < lclBestSad) )                   || (low_complex_prof3)  )        {          refPtr = refLine + (vecX >> 1);          currSad = findSad2_8x(orig, refPtr, refW, blkH, currSad, lclBestSad);          if (currSad < lclBestSad) {            lclBestSad   = currSad;            lclBestVec.x = (int16)vecX;            lclBestVec.y = (int16)vecY;          }        }              }    }    break;      default:    // blk->width == 16    /* Scan motion vectors within search area */    for (vecY = startY; vecY <= stopY; vecY += step) {      refPsLine = & mbPart->refPartSum[(vecY >> 2) * (refW >> 1)];      refLine = & mbPart->ref[(vecY >> 1) * refW];      overhead = (int) mbPart->vlcMvBitsY[vecY] * lambda;      for (vecX = startX; vecX <= stopX; vecX += step) {        /* Take into account number fo bits spent for motion vector */        currSad = lambda * vlcMvBitsX[vecX] + overhead;        if (mbPart->mode == MOT_16x16)        {          if ((vecY | vecX) == 0)            currSad -= lambda * ZERO_VEC_SAD;        }        // calculate the partial results here                        // : take away partial sum        if (!low_complex_prof3)        {          refPsPtr = refPsLine + (vecX >> 2);           origPsPtr = mbPart->partSum;          partialSum  = abs(refPsPtr[0]  - origPsPtr[0]);          partialSum += abs(refPsPtr[8]  - origPsPtr[2]);          if (blkH == 16)          {            partialSum += abs(refPsPtr[4 * refW + 0]  - origPsPtr[8]);            partialSum += abs(refPsPtr[4 * refW + 8]  - origPsPtr[10]);          }        }        // : take away partial sum        /* Accumulate sad until no pels left or sad is worse than best so far */        if ( ( (!low_complex_prof3) && (partialSum + currSad < lclBestSad) )                || (low_complex_prof3)  )        {          refPtr = refLine + (vecX >> 1);           currSad = findSad2_16x(orig, refPtr, refW, blkH, currSad, lclBestSad);          if (currSad < lclBestSad) {            lclBestSad   = currSad;            lclBestVec.x = (int16)vecX;            lclBestVec.y = (int16)vecY;          }        }      }    }    break;  }  *bestSad = lclBestSad;  *bestVec = lclBestVec;}// center has been searched alreadymotVec_s searchPatt[9] ={  {-1,  0}, { 0, -1}, { 1,  0}, { 0,  1},  {-1, -1}, { 1, -1}, {-1,  1}, { 1,  1},  {0, 0}};int matchBlockLocal4(mbPart_s *mbPart,                      int step,                     motVec_s *bestVec,                     int *bestSad,                     int *neighborSads){  motVec_s centerVec, lclBestVec;  int i, vecX, vecY;  int currSad;  int lclBestSad;  int lambda;  int centerBest;  motVec_s lclSearchPatt[8];  lambda = mbPart->lambdaCoarse;  centerVec   = *bestVec;  lclBestVec  = *bestVec;  lclBestSad  = *bestSad;  for (i = 0; i < 4; i ++)  {    lclSearchPatt[i].x = (int16) (searchPatt[i].x * step);    lclSearchPatt[i].y = (int16) (searchPatt[i].y * step);  }  /* Scan motion vectors within search area */  centerBest = 1;  for (i = 0; i < 4; i ++)  {    vecX = centerVec.x + lclSearchPatt[i].x;    vecY = centerVec.y + lclSearchPatt[i].y;    /* Take into account number fo bits spent for motion vector */    currSad = lambda *       (mbPart->vlcMvBitsX[vecX] + mbPart->vlcMvBitsY[vecY]);    /* Favor 16x16 blocks that have zero motion */    if (mbPart->mode == MOT_16x16)    {      if ((vecY | vecX) == 0)        currSad -= lambda * ZERO_VEC_SAD;    }    /* Accumulate sad until no pels left or sad is worse than best so far */    currSad = findSAD2(mbPart->orig, mbPart->ref, mbPart->refWidth,       mbPart->width, mbPart->height, vecX, vecY, currSad, INT_MAX);    neighborSads[i] = currSad;    if (currSad < lclBestSad) {      centerBest = 0;      lclBestSad   = currSad;      lclBestVec.x = (int16)vecX;      lclBestVec.y = (int16)vecY;    }  }  *bestVec = lclBestVec;  *bestSad = lclBestSad;  return centerBest;}void matchBlockDiamond(mbPart_s *mbPart,                        int step,                       motVec_s *bestVec,                       int *bestSad,                        int hadamard){  motVec_s centerVec, lclBestVec, lastBestVec;  int i, vecX, vecY;  int currSad;  int lclBestSad;  int lambda;  int numPositions;  motVec_s lclSearchPatt[9];  lambda = mbPart->lambdaCoarse;  centerVec   = *bestVec;  lclBestVec  = *bestVec;  lclBestSad  = *bestSad;  lastBestVec = lclBestVec;  if (mbPart->profile == PROF_CODING_SPEED)    numPositions = 6;  else    numPositions = 9;  for (i = 0; i < numPositions; i ++)  {    lclSearchPatt[i].x = (int16) (searchPatt[i].x * step);    lclSearchPatt[i].y = (int16) (searchPatt[i].y * step);  }  /* Scan motion vectors within search area */  for (i = 0; i < numPositions; i ++)  {    vecX = centerVec.x + lclSearchPatt[i].x;    vecY = centerVec.y + lclSearchPatt[i].y;    /* Take into account number fo bits spent for motion vector */    currSad = lambda *       (mbPart->vlcMvBitsX[vecX] + mbPart->vlcMvBitsY[vecY]);    /* Favor 16x16 blocks that have zero motion */    if (mbPart->mode == MOT_16x16)    {      if ((vecY | vecX) == 0)        currSad -= lambda * ZERO_VEC_SAD;    }    /* Accumulate sad until no pels left or sad is worse than best so far */    if (currSad < lclBestSad) {      if (step == 1)      {        currSad = findSATD4(mbPart->orig, mbPart->ref, mbPart->refWidth,           mbPart->width, mbPart->height, vecX, vecY, currSad, lclBestSad, hadamard);      }      else      {        currSad = findSAD2(mbPart->orig, mbPart->ref, mbPart->refWidth,           mbPart->width, mbPart->height, vecX, vecY, currSad, lclBestSad);      }      if (currSad < lclBestSad) {        lclBestSad   = currSad;        lclBestVec.x = (int16)vecX;        lclBestVec.y = (int16)vecY;      }    }    // let's see if the center is changed    if (mbPart->profile == PROF_CODING_SPEED)    {      if (i == 3)      {        if ((lastBestVec.x == lclBestVec.x) && (lastBestVec.y == lclBestVec.y))          break;        else        {          if (lastBestVec.x == lclBestVec.x)          {            // either top or bottom, need to search the left or right            lclSearchPatt[4].x = (int16) (-step);            lclSearchPatt[4].y = (int16) (lclBestVec.y - centerVec.y);            lclSearchPatt[5].x = (int16) (step);            lclSearchPatt[5].y = (int16) (lclBestVec.y - centerVec.y);          }          else          {            // either left or right, need to search the top or bottom            lclSearchPatt[4].x = (int16) (lclBestVec.x - centerVec.x);            lclSearchPatt[4].y = (int16) (-step);            lclSearchPatt[5].x = (int16) (lclBestVec.x - centerVec.x);            lclSearchPatt[5].y = (int16) (step);          }        }       }    }  }  *bestVec = lclBestVec;  *bestSad = lclBestSad;}/* * MergeTree * * Parameters: *      mrPairs            Stores 1 pair of (ref + mv) for each block in MB,  *                         no matter how the MB is partitioned. *      interMode          Inter-prediction mode for the MB * * Function: *      Check if all the partitions have the same MV and ref. If it is, change *      the mode to MOT_16x16, so it can be skipped if other conditions allow. *      Sometimes, an MB or sub-MB can be separated into multiple partitions *      but all the partitions have the same motion vector. Sometimes it is *      due to the greedy search, and they should be merged. Sometimes  *      encoding multiple motion vectors can cost less bits because of some *      prediction rules favor this particular separation.  * * Returns: *      - */int MergeTree(blkState_s *mrPairs,               int        *interMode){  int i;  int merged;  int newInterMode;  newInterMode = *interMode;  merged = 1;  if (*interMode == MOT_8x8)  {    for (i = 0; i < 16; i ++)    {      if (mrPairs[0].mv.x != mrPairs[i].mv.x ||         mrPairs[0].mv.y != mrPairs[i].mv.y ||        mrPairs[0].ref != mrPairs[i].ref)      {        merged = 0;        break;      }    }  }  else  {    if (*interMode == MOT_16x8)    {      if (mrPairs[0].mv.x != mrPairs[8].mv.x ||        mrPairs[0].mv.y != mrPairs[8].mv.y ||        mrPairs[0].ref != mrPairs[8].ref)        merged = 0;    }    if (*interMode == MOT_8x16)    {      if (mrPairs[0].mv.x != mrPairs[2].mv.x ||        mrPairs[0].mv.y != mrPairs[2].mv.y ||        mrPairs[0].ref != mrPairs[2].ref)        merged = 0;    }  }  // merge has happened at the MB level  if (merged)    *interMode = MOT_16x16;  return merged;}

⌨️ 快捷键说明

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