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

📄 macroblock.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Get u */  recoPtr = reco->u + pixY*width + pixX;  for (y = 0; y < MBK_SIZE/2; y++) {    for (x = 0; x < MBK_SIZE/2; x++) {      bibGetByte(bitbuf, &byteRet);      recoPtr[y*width+x] = (u_int8)byteRet;    }  }  /* Get v */  recoPtr = reco->v + pixY*width + pixX;  for (y = 0; y < MBK_SIZE/2; y++) {    for (x = 0; x < MBK_SIZE/2; x++) {      bibGetByte(bitbuf, &byteRet);      recoPtr[y*width+x] = (u_int8)byteRet;    }  }  return MBK_OK;}/* * * getMbAvailability: * * Parameters: *      mb                    Macroblock object *      mbData                Buffers for for macroblock attributes *      picWidth              Picture width *      constrainedIntra      Constrained intra prediction flag * * Function: *      Get neighboring macroblock availability info *       * Returns: *      Macroblock availability bits: *        bit 0 : left macroblock *        bit 1 : upper macroblock *        bit 2 : upper-right macroblock *        bit 3 : upper-left macroblock *        bit 4 : left macroblock (intra) *        bit 5 : upper macroblock (intra) *        bit 6 : upper-right macroblock (intra) *        bit 7 : upper-left macroblock (intra) */static int getMbAvailability(macroblock_s *mb, mbAttributes_s *mbData,                             int picWidth, int constrainedIntra){  int mbsPerLine;  int mbAddr;  int currSliceIdx;  int *sliceMap;  int8 *mbTypeTable;  int mbAvailBits;  mbsPerLine = picWidth/MBK_SIZE;  mbAddr = mb->idxY*mbsPerLine+mb->idxX;  sliceMap = & mbData->sliceMap[mbAddr];  currSliceIdx = sliceMap[0];  mbAvailBits = 0;  /* Check availability of left macroblock */  if (mb->idxX > 0 && sliceMap[-1] == currSliceIdx)    mbAvailBits |= 0x11;  /* Check availability of upper, upper-left and upper-right macroblocks */  if (mb->idxY > 0) {    sliceMap -= mbsPerLine;    /* Check availability of upper macroblock */    if (sliceMap[0] == currSliceIdx)      mbAvailBits |= 0x22;    /* Check availability of upper-right macroblock */    if (mb->idxX+1 < mbsPerLine && sliceMap[1] == currSliceIdx)      mbAvailBits |= 0x44;    /* Check availability of upper-left macroblock */    if (mb->idxX > 0 && sliceMap[-1] == currSliceIdx)      mbAvailBits |= 0x88;  }  /*   * Check availability of intra MB if constrained intra is enabled   */  if (constrainedIntra) {     mbTypeTable = & mbData->mbTypeTable[mbAddr];    /* Check availability of left intra macroblock */    if ((mbAvailBits & 0x10) && mbTypeTable[-1] != MBK_INTRA)      mbAvailBits &= ~0x10;    /* Check availability of upper, upper-left and upper-right intra macroblocks */    if (mbAvailBits & (0x20|0x40|0x80)) {      mbTypeTable -= mbsPerLine;      /* Check availability of upper intra macroblock */      if ((mbAvailBits & 0x20) && mbTypeTable[0] != MBK_INTRA)        mbAvailBits &= ~0x20;      /* Check availability of upper-right intra macroblock */      if ((mbAvailBits & 0x40) && mbTypeTable[1] != MBK_INTRA)        mbAvailBits &= ~0x40;      /* Check availability of upper-left intra macroblock */      if ((mbAvailBits & 0x80) && mbTypeTable[-1] != MBK_INTRA)        mbAvailBits &= ~0x80;    }  }  return mbAvailBits;}#ifdef CHECK_SUB_MB_RECT_SIZE/* * checkSubMbRectSize: * * Parameters: *      vecs                Motion vectors for the frame *      picWidth            Picture width *      blkX                Sub-macroblock X index within frame *      blkY                Sub-macroblock Y index within frame * * Function: *      Check whether motion vectors for the current sub-macroblock *      conform to the AVC/H.264 standard's  rect size restriction. * * Returns: *      1 for vectors ok, 0 for vectors not ok. */static int checkSubMbRectSize(motVec_s *vecs, int picWidth, int blkX, int blkY){  int blksPerRow;  int minX, maxX, minY, maxY;  int vecDiffX, vecDiffY;  int rectSize;  int i, j;  blksPerRow = picWidth/BLK_SIZE;  vecs += blksPerRow*blkY + blkX;  minX = minY = 32767;  maxX = maxY = -32768;  for (j = 0; j < BLK_PER_MB/2; j++) {    for (i = 0; i < BLK_PER_MB/2; i++) {      minX = min(minX, vecs[j*blksPerRow+i].x + i*BLK_SIZE*4);      maxX = max(maxX, vecs[j*blksPerRow+i].x + i*BLK_SIZE*4);      minY = min(minY, vecs[j*blksPerRow+i].y + j*BLK_SIZE*4);      maxY = max(maxY, vecs[j*blksPerRow+i].y + j*BLK_SIZE*4);    }  }  vecDiffX = (maxX>>2) - (minX>>2);  vecDiffY = (maxY>>2) - (minY>>2);  rectSize = (vecDiffX + BLK_SIZE + 6) * (vecDiffY + BLK_SIZE + 6);  if (rectSize <= 576)    return 1;  else    return 0;}/* * checkAllSubMbRectSizes: * * Parameters: *      vecs                Motion vectors for the frame *      picWidth            Picture width *      blkX                Sub-macroblock X index within frame *      blkY                Sub-macroblock Y index within frame * * Function: *      Check whether motion vectors for the current macroblock *      conform to the AVC/H.264 standard's rect size restriction. * * Returns: *      1 for vectors ok, 0 for vectors not ok. */static int checkAllSubMbRectSizes(motVec_s *vecs, int picWidth, int blkX, int blkY){  int i, j;  for (j = 0; j < BLK_PER_MB; j+=BLK_PER_MB/2) {    for (i = 0; i < BLK_PER_MB; i+=BLK_PER_MB/2) {      if (!checkSubMbRectSize(vecs, picWidth, blkX+i, blkY+j))        return 0;    }  }  return 1;}#endif/* * * mbkDecode: * * Parameters: *      mb                    Macroblock parameters *      reco                  Pointer to reconstruction frame *      ref                   Reference frame list *      numRefFrames          Number of reference frames active *      mbData                Buffer for macroblock attributes *      picWidth              Picture width *      picHeight             Picture height *      picType               Picture type (intra/inter) *      bitbuf                Bitbuffer handle * * Function: *      Decodes one macroblock *       * Returns: *      - * */int mbkDecode(macroblock_s *mb, frmBuf_s *reco, frmBuf_s **ref, int numRefFrames,              mbAttributes_s *mbData, int picWidth, int picHeight, int picType,              int constIpred, int chromaQpIdx,  int mbIdxX, int mbIdxY,              void *streamBuf){  int8 ipTab[BLK_PER_MB*BLK_PER_MB];  int diffVecs[BLK_PER_MB*BLK_PER_MB][2];  int hasDc;  int pixOffset;  int constrainedIntra;  int copyMbFlag;  int mbAddr;  int pcmMbFlag;  int retCode;  mb->idxX = mbIdxX;  mb->idxY = mbIdxY;  mb->blkX = mbIdxX*BLK_PER_MB;  mb->blkY = mbIdxY*BLK_PER_MB;  mb->pixX = mbIdxX*MBK_SIZE;  mb->pixY = mbIdxY*MBK_SIZE;  mbAddr = mb->idxY*(picWidth/MBK_SIZE)+mb->idxX;  copyMbFlag = pcmMbFlag = 0;  constrainedIntra = constIpred && !(IS_SLICE_I(picType));  mb->mbAvailBits = getMbAvailability(mb, mbData, picWidth, constrainedIntra);  /*   * Read macroblock bits   */  retCode = getMacroblock(mb, numRefFrames, ipTab, mbData->numCoefUpPred, diffVecs,                            picType, chromaQpIdx, (bitbuffer_s *)streamBuf);  if (retCode < 0)    return retCode;  /* Set PCM glag */  if (mb->type == MBK_INTRA && mb->intraType == MBK_INTRA_TYPE_PCM)    pcmMbFlag = 1;  /*   * Get intra/inter prediction   */  if (mb->type == MBK_INTRA) {    mbData->mbTypeTable[mbAddr] = MBK_INTRA;    mcpClearMBmotion(mb->idxX, mb->idxY, picWidth, mbData->refIdxTable,                     -1, mbData->motVecTable);    if (mb->intraType == MBK_INTRA_TYPE1) {      iprPutIntraModes(mb->mbAvailBits>>4, ipTab, mb->ipModesLeftPred,                       &mbData->ipModesUpPred[mb->blkX]);      iprPredLuma4x4blocks(mb->coefY, reco->y, picWidth, ipTab,                           mb->mbAvailBits>>4, mb->idxX, mb->idxY, mb->cbpY, mb->qp);    }    else {      iprClearMBintraPred(mb->ipModesLeftPred, &mbData->ipModesUpPred[mb->blkX]);      if (!pcmMbFlag)        iprPredLuma16x16(mb->predY, mb->intraMode,                         &reco->y[(mb->idxY*MBK_SIZE-1)*picWidth+mb->idxX*MBK_SIZE-1],                         picWidth, mb->mbAvailBits>>4);    }    if (pcmMbFlag) {      if (recoPcmMb(reco, mb->pixX, mb->pixY, picWidth, (bitbuffer_s *)streamBuf) < 0)        return MBK_ERROR;    }    else {      int offset = (mbIdxY*(MBK_SIZE/2)-1)*(picWidth>>1)+mbIdxX*(MBK_SIZE/2)-1;      iprPredChroma(mb->predC, &reco->u[offset], &reco->v[offset],                    picWidth>>1, mb->mbAvailBits>>4, mb->intraModeChroma);    }  }  else {    mbData->mbTypeTable[mbAddr] = (int8)(mb->interMode+1);    iprClearMBintraPred(mb->ipModesLeftPred, &mbData->ipModesUpPred[mb->blkX]);    /* If COPY MB, put skip motion vectors */    if (mb->interMode == MOT_COPY) {      copyMbFlag = mcpPutSkipModeVectors(mb->idxX, mb->idxY, picWidth,                                         mbData->refIdxTable,                                         mbData->motVecTable, mb->mbAvailBits);      mb->interMode = MOT_16x16;    }    else      mcpPutVectors(mb->idxX, mb->idxY, mb->interMode, mb->inter8x8modes,                    mb->refNum, picWidth, mbData->refIdxTable, numRefFrames,                    mbData->motVecTable, mb->mbAvailBits, diffVecs);#ifdef CHECK_SUB_MB_RECT_SIZE    if (!checkAllSubMbRectSizes(mbData->motVecTable, picWidth, mb->blkX, mb->blkY)) {      deb2f(stderr, "Sub-macroblock rect size violation (%i,%i) !!\n", mb->blkX, mb->blkY);    }#endif    if (copyMbFlag)      mcpCopyMacroblock(reco, ref[0], mb->pixX, mb->pixY, picWidth);    else      mcpGetPred(mb->predY, mb->predC, mb->idxX, mb->idxY, ref, picWidth,                 picHeight, mbData->motVecTable, mbData->refIdxTable);  }  /*   * Decode prediction error & reconstruct MB   */  if (!copyMbFlag && !pcmMbFlag) {    /* If 4x4 intra mode, luma prediction error is already transformed */    if (!(mb->type == MBK_INTRA && mb->intraType == MBK_INTRA_TYPE1)) {      hasDc = (mb->type == MBK_INTRA && mb->intraType == MBK_INTRA_TYPE2) ? 1 : 0;      pedRecoLumaMB(mb->predY, mb->dcCoefY, hasDc, mb->coefY,                    &reco->y[mb->pixY*picWidth+mb->pixX], picWidth,                    mb->qp, mb->cbpY);    }    pixOffset = ((mb->pixY*picWidth)>>2)+(mb->pixX>>1);    pedRecoChromaMB(mb->predC, mb->dcCoefC, mb->coefC, &reco->u[pixOffset],                    &reco->v[pixOffset], picWidth>>1, mb->qpC,                    mb->cbpChromaDC, mb->cbpC);  }  /*   * Store qp and coded block pattern for current macroblock   */  if (pcmMbFlag)    mbData->qpTable[mbAddr] = 0;  else    mbData->qpTable[mbAddr] = (int8)mb->qp;  mbData->cbpTable[mbAddr] = mb->cbpY;  return MBK_OK;}

⌨️ 快捷键说明

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