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

📄 macroblock.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Function: *      Get neighboring macroblock availability info *       * Returns: *      - */static void getMbAvailability(macroblock_s *mb,                               int          picWidth,                               int          constrainedIntra){  int i, mbsPerLine;  int currSliceIdx;  mbsPerLine = picWidth/MBK_SIZE;    currSliceIdx = mb->mbThis->sliceMap;  // let's set them to unavailable at first  for (i = 0; i < 4; i ++)  {    mb->mbAvailMap[i] = 0;    mb->mbAvailMapIntra[i] = 0;  }  // Check availability of left macroblock  if (mb->idxX > 0 && mb->mbLeft->sliceMap == currSliceIdx) {    mb->mbAvailMap[0] = 1;    mb->mbAvailMapIntra[0] = (! constrainedIntra) ||       (mb->mbLeft->mbType <= MB_TYPE_INTRA_16x16);  }  /*   * Check availability of upper macroblock   */  if (mb->idxY > 0)  {    if (mb->mbUp->sliceMap == currSliceIdx) {      mb->mbAvailMap[1] = 1;      mb->mbAvailMapIntra[1] =         (! constrainedIntra) || (mb->mbUp->mbType <= MB_TYPE_INTRA_16x16);    }    /*    * Check availability of upper-right macroblock    */    if (mb->idxX + 1 < mbsPerLine && mb->mbUpRight->sliceMap == currSliceIdx) {      mb->mbAvailMap[2] = 1;      mb->mbAvailMapIntra[2] =         (! constrainedIntra) || (mb->mbUpRight->mbType <= MB_TYPE_INTRA_16x16);    }    /*    * Check availability of upper-left macroblock    */    if (mb->idxX > 0 && mb->mbUpLeft->sliceMap == currSliceIdx) {      mb->mbAvailMap[3] = 1;      mb->mbAvailMapIntra[3] =         (! constrainedIntra) || (mb->mbUpLeft->mbType <= MB_TYPE_INTRA_16x16);    }  }    // --------------------------------------------------------------------------  // additional intra MB parameter setup  // availability of the MB above the current macroblock  // should always be aligned at 32-bit boundary  // IPR_MODE_DC is chosen to tell the block is available  mb->i4x4CornersAvail[1][0] = mb->i4x4CornersAvail[2][0] =     mb->i4x4CornersAvail[3][0] = (u_int8)((mb->mbAvailMapIntra[0]) ? 3 : 2);  // fill the changing slots in upRightMode and upLeftMode  mb->i4x4CornersAvail[0][0] = (u_int8)    (((mb->mbAvailMapIntra[1] != 0) << 1) + (mb->mbAvailMapIntra[3] != 0));  mb->i4x4CornersAvail[0][1] = mb->i4x4CornersAvail[0][2] = (u_int8)    ((mb->mbAvailMapIntra[1]) ? 3 : 0);  mb->i4x4CornersAvail[0][3] = (u_int8)    (((mb->mbAvailMapIntra[2] != 0) << 1) + (mb->mbAvailMapIntra[1] != 0));}/* * * mbkLoadNeighbors: * * Parameters: *      pMb                 Macroblock information * * Function: *      Load all the related neighboring motion vectors in local storage *      "surround". Change the pointer directions if some macroblock *      becomes available or unavailable. *      We do it once for a macroblock, so do not need to worry about the  *      relationship in the motion estimation. * * Returns: *      - * */static void mbkLoadNeighbors(macroblock_s *pMb){  int i;  blkState_s *s;  blkState_s *c;  blkState_s blkStateNA = {{0, 0}, REF_NA, IPR_MODE_NA, 0};  motVec_s zeroVec = {0, 0};  s = pMb->surround;  c = & pMb->current[0][0];  // point to the start of the current macroblock  if (pMb->mbAvailMap[0])  {    for (i = 0; i < 4; i ++)    {      s[i] = pMb->mbLeft->blkInfo[i][3];      if (! pMb->mbAvailMapIntra[0])      // inter and constrainIntra        s[i].i4x4Mode = IPR_MODE_NA;    }  }  else    for (i = 0; i < 4; i ++)      s[i] = blkStateNA;  if (pMb->mbAvailMap[1])  {    for (i = 0; i < 4; i ++)    {      s[i + 4] = pMb->mbUp->blkInfo[3][i];      if (! pMb->mbAvailMapIntra[1])      // inter and constrainIntra        s[i + 4].i4x4Mode = IPR_MODE_NA;    }  }  else    for (i = 0; i < 4; i ++)      s[i + 4] = blkStateNA;  // up-right and up-left corners  s[8] = (pMb->mbAvailMap[2]) ? pMb->mbUpRight->blkInfo[3][0] : blkStateNA;  s[9] = (pMb->mbAvailMap[3]) ? pMb->mbUpLeft->blkInfo[3][3]  : blkStateNA;  // we need have to re-direct some pointers if the mbAvailMap has changed  if (pMb->mbAvailMap[1])  {    pMb->blkUpRight[1][0] = & s[6];    pMb->blkUpRight[2][0] = & s[5];  }  else  {    pMb->blkUpRight[1][0] = & s[9];    pMb->blkUpRight[2][0] = & s[9];  }  if (pMb->mbAvailMap[2])  {    // some pointers may have been re-directed    pMb->blkUpRight[0][0] = & s[8];    pMb->blkUpRight[1][2] = & s[8];    pMb->blkUpRight[2][3] = & s[8];  }  else  {    // redirect the pointers to use vecD as vecC    pMb->blkUpRight[0][0] = & s[9];    pMb->blkUpRight[1][2] = & s[5];    pMb->blkUpRight[2][3] = & s[6];  }  // calculate the MV predictor for skipped MB  if (! pMb->mbAvailMap[0] || ! pMb->mbAvailMap[1] ||    ((s[0].ref | s[0].mv.x | s[0].mv.y) == 0) ||    ((s[4].ref | s[4].mv.x | s[4].mv.y) == 0))  {    pMb->skipPredMv = zeroVec;  }  else    pMb->skipPredMv = mcpFindPredMv(pMb, 0, MOT_16x16, 0);}/* * mbkRasterCbpY: * * Parameters: *      cbpY                  Macroblock object * * Function: *      Convert cbpY from coding order to raster order.  *       * Returns: *      cbpY in raster order. */static int mbkRasterCbpY(int cbpY){  int rasterCbp;  rasterCbp  = cbpY & 0xC3C3;       // those are not changed  rasterCbp |= (cbpY & 0x000C) << 2;  rasterCbp |= (cbpY & 0x0030) >> 2;  rasterCbp |= (cbpY & 0x0C00) << 2;  rasterCbp |= (cbpY & 0x3000) >> 2;  return rasterCbp;}/* * mbkProcessData: * * Parameters: *      mb                    Macroblock object *      picType               Picture type (intra/inter) *      encPar                Encoding parameters (motion range, etc.) * * Function: *      Perform forward and backward transform/quatization.  *       * Returns: *      - */void mbkProcessData(macroblock_s *mb,                     int          picType,                     encParams_s  *encPar){  void *predPtr;  /*   * Transform, quantization & reconstruction   */  if (mb->type == MBK_INTER && mb->interMode == MOT_COPY)  {    // only need to get predicted MB to the reconstructed frame buffer    // Setup the cbp, and let pedRecoLumaMB do the copying operations    mb->cbpY = 0;    mb->rastercbpY  = 0;    mb->cbpChromaDC = 0;    mb->cbpC = 0;    mb->minMSE = 0;    pedRecoLumaMB(mb, mb->predY, 0, encPar->picWidth);    pedRecoChromaMB(mb, mb->predC, encPar->picWidth >> 1);    return;  }  /* If 4x4 intra mode, luma prediction error is already transformed */  if (! (mb->type == MBK_INTRA && mb->intraType == MBK_INTRA_TYPE1)) {    int skip;    if (mb->type == MBK_INTRA)    {      // mb->type == MBK_INTRA, must be intra16x16      predPtr = mb->predBlk2[mb->intra16x16mode];      skip = 1;    }    else    {      predPtr = mb->predY;      skip = 0;    }    mb->minMSE =  CalculateSad    (& mb->origY[0][0],     16, predPtr, encPar->picWidth, 16, 16);    pecCodeLumaMB(mb, predPtr, skip, picType);    pedRecoLumaMB(mb, predPtr, skip, encPar->picWidth);  }  predPtr = (mb->type == MBK_INTRA) ?     mb->predIntraC[mb->intraModeChroma] : mb->predC;  pecCodeChromaMB(mb, predPtr, picType);  pedRecoChromaMB(mb, predPtr, encPar->picWidth >> 1);  mb->rastercbpY = mbkRasterCbpY(mb->cbpY);  }/* * mbkSend: * * Parameters: *      stream                Generic stream buffer, bitbuffer/arith encoder *      mb                    Macroblock object *      nRefFrames            Number of reference frames in use *      picType               Picture type (intra/inter) *      stat                  Statistics * * Function: *      Code macroblock using VLC.  *       * Returns: *      Number of bits spent on encoding luma component. */int mbkSend(void         *stream,             macroblock_s *mb,             int          nRefFrames,             int          picType,            statSlice_s  *stat){  int lumaBits;  if (mb->type == MBK_INTER && mb->interMode == MOT_16x16 &&    (mb->cbpY | mb->cbpChromaDC | mb->cbpC) == 0)  {    if ((mb->current[0][0].ref == 0) &&      (mb->current[0][0].mv.x == mb->skipPredMv.x) &&      (mb->current[0][0].mv.y == mb->skipPredMv.y))      mb->interMode = MOT_COPY;      }  // set the bits related to mbType, and MVs  if (IS_SLICE_P(picType))  {    int i, j, skipFlag;    skipFlag = (mb->type == MBK_INTER) && (mb->interMode == MOT_COPY);    stat->bitsSkipLen += streamSendMbSkipFlag(stream, mb, skipFlag);    if (skipFlag)    {      for (j = 0; j < 4; j ++)        for (i = 0; i < 4; i ++)          mb->current[j][i].numLumaCoefs = 0;      * ((int *) & mb->mbThis->numChromaCoefs[0][0][0]) = 0;      * ((int *) & mb->mbThis->numChromaCoefs[1][0][0]) = 0;      mb->qp = mb->prevQp;      mb->deltaQp = 0;      return 0;    }  }  streamSendMbHeader(stream, mb, nRefFrames, picType, stat);  // Send transform coefficients  lumaBits = streamSendLumaCoeffs(stream, mb, stat);  streamSendChromaCoeffs(stream, mb, stat);  return lumaBits;}/* * mbkBeforeSlice: * * Parameters: *      mb                    Macroblock object *      sliceQp               Slice qp * * Function: *      Macroblock initialization before the slice is encoded.  *       * Returns: *      - */void mbkBeforeSlice(macroblock_s *mb,                    int          sliceQp){  mb->numSkipped  = 0;  mb->prevQp      = sliceQp;}/* * mbkFinishEnc: * * Parameters: *      mb                    Macroblock object *      stat                  Statistics * * Function: *      Save state information after the macroblock is encoded.  *       * Returns: *      - */void mbkFinishEnc(macroblock_s *mb,                  statSlice_s  *stat){  int i, j;

⌨️ 快捷键说明

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