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