📄 macroblock.c
字号:
* 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 + -