📄 umc_h264_enc_cpb.cpp
字号:
m_mbinfo.MV[1] = align_pointer<H264DecoderMacroblockMVs *> (m_mbinfo.MV[0]+ nMBCount, ALIGN_VALUE); m_mbinfo.RefIdxs[0] = align_pointer<H264DecoderMacroblockRefIdxs *> (m_mbinfo.MV[1] + nMBCount, ALIGN_VALUE); m_mbinfo.RefIdxs[1] = align_pointer<H264DecoderMacroblockRefIdxs *> (m_mbinfo.RefIdxs[0] + nMBCount, ALIGN_VALUE); m_mbinfo.mbs = align_pointer<H264DecoderMacroblockGlobalInfo *> (m_mbinfo.RefIdxs[1] + nMBCount, ALIGN_VALUE);#endif Ipp32u uBufSize; Ipp32u uNumberOf4x4Blocks; Ipp32u uNumMBs; //uWidthInMBs = macroBlockSize().width; //uHeightInMBs = macroBlockSize().height; uWidth = MB_Frame_Width<<4; uHeight = MB_Frame_Height<<4; //uWidthIn4x4Blocks = macroBlockSize().width<<2; //uHeightIn4x4Blocks = macroBlockSize().height<<2;#if 0 // Table lookup to generate block position, dependent on frame width // Removes IMUL bottleneck from Calc_One_MV_Predictor // Initialize table for Calc_One_MV_Predictor // 11 bits -> 2048 entries // index[0:10] = INTRA_AboveLeft(10) INTRA_Above(9) INTRA_Left(8) uBlock(4:7) uEdgeType(0:3) // bit 0 - bIntraMBLeft // bit 1 - bIntraMBAbove // bit 2 - bIntraMBAboveLeft // index[0:9] = INTRA_AboveRight(9) uRBlockOrder(4:7) uEdgeType(0:3) // bit 3 - bIntraMBAboveRight // bit 4 - bNoBlockAboveRight // index[0:8] = blockshape (7:8) bIntraMBAboveRight(6) bIntraMBAbove(5) bIntraMBLeft(4) uBlock(0:3) // bits 5:7 - pMVPred option for(int i=0; i < 2048; i++) { int uEdgeType = i & 0xF; int uBlock = (i >> 4) & 0xF; int Lintra = i & 0x100; int Aintra = i & 0x200; int ALintra = i & 0x400; Ipp8u block_order = block_subblock_mapping[uBlock]; Ipp8u bNoBlockAbove = !(uEdgeType & MBEdgeTypeIsNotTopEdge) && top_edge_tab16[block_order]; Ipp8u bNoBlockLeft = !(uEdgeType & MBEdgeTypeIsNotLeftEdge) && left_edge_tab16[block_order]; Ipp8u bNoBlockAboveLeft = ( // Upper left MB corner !(uEdgeType & MBEdgeTypeIsNotUpperLeftCorner) && (block_order == 0)) || ( // Top edge, _not_ upper left MB corner !(uEdgeType & MBEdgeTypeIsNotTopEdge) && top_edge_tab16[block_order] && !(left_edge_tab16[block_order])) || ( // Left edge, _not_ upper left MB corner !(uEdgeType & MBEdgeTypeIsNotLeftEdge) && left_edge_tab16[block_order] && !(top_edge_tab16[block_order])); Ipp8u bIntraMBLeft = bNoBlockLeft || (!(uEncNotEdge[block_order] & MBEdgeTypeIsNotLeftEdge) && Lintra); Ipp8u bIntraMBAbove = bNoBlockAbove || (!(uEncNotEdge[block_order] & MBEdgeTypeIsNotTopEdge) && Aintra); Ipp8u bIntraMBAboveLeft = bNoBlockAboveLeft || (!(uEncNotEdge[block_order] & MBEdgeTypeIsNotUpperLeftCorner) && ALintra); int URBlockOrder = uBlock; int ARintra = Lintra; Ipp8u bNoBlockAboveRight = ( // Upper right MB corner !(uEdgeType & MBEdgeTypeIsNotRightEdge) && (URBlockOrder == 5)) || ( // Top edge, _not_ upper right MB corner !(uEdgeType & MBEdgeTypeIsNotTopEdge) && top_edge_tab16[URBlockOrder] && !(right_edge_tab16[URBlockOrder])) || ( // Right edge, _not_ upper right MB corner right_edge_tab16[URBlockOrder] && !(top_edge_tab16[URBlockOrder])) || // Upper right block not coded yet in block order (URBlockOrder == 3) || (URBlockOrder == 11); Ipp8u bIntraMBAboveRight = bNoBlockAboveRight || (!(uEncNotEdge[URBlockOrder] & MBEdgeTypeIsNotRightEdge) && ARintra); int MVbits; uBlock = i & 0xF; int bDiffRefLeft = (i >> 4) & 1; int bDiffRefAbove = (i >> 5) & 1; int bDiffRefAboveRight = (i >> 6) & 1; int Shape = (i >> 7) & 3; // Gets set to false if a 8x16 or 16x8 special prediction is used Ipp8u bDoMedianPred = true; if (Shape) { // 8x16 and 16x8 block sizes if (Shape == 2) { // 16x8 if ((uBlock == 0) && !(bDiffRefAbove)) { // 16x8 - Top block - Above uses same ref and not Intra // Predict from Above in this case MVbits = 5; bDoMedianPred = false; } else if ((uBlock == 8) && !(bDiffRefLeft)) { // 16x8 - Bottom block - Left uses same ref and not Intra // Predict from Left in this case MVbits = 6; bDoMedianPred = false; } } else { // 8x16 if ((uBlock == 0) && !(bDiffRefLeft)) { // 8x16 - Left block - Left uses same ref and not Intra // Predict from Left in this case MVbits = 6; bDoMedianPred = false; } else if ((uBlock == 2) && !(bDiffRefAboveRight)) { // 8x16 - Right block - Above Right uses same ref and not Intra // Predict from Above-Right in this case MVbits = 3; bDoMedianPred = false; } } } if (bDoMedianPred) // Median Prediction MVbits = (i>>4) & 7; C1MVtable[i] = bIntraMBLeft | (bIntraMBAbove << 1) | (bIntraMBAboveLeft << 2) | (bIntraMBAboveRight << 3) | (bNoBlockAboveRight << 4) | (MVbits << 5); }#endif uNumMBs = MB_Frame_Width * MB_Frame_Height; uNumberOf4x4Blocks = uNumMBs<<4; uNumSlices = (Ipp16u) num_slices; uSliceLength = uNumMBs / num_slices; uSliceRemainder = uNumMBs % num_slices; use_implicit_weighted_bipred = 0; //m_tr_wrap_around = 0;//pPrevFrm->GetWrapAround(); // temp buffer used during encoding, size: // 16*16/MB prediction for direct B * 1 byte/result = 256 // 16*16/MB temp working buffer for direct B * 1 byte/result = 256 // 16*16/MB prediction for BiPred B * 1 byte/result = 256 // + 16 blocks/MB * 16 MC results * 1 byte/result = 256 // + 16 blocks/MB * 16 ME subpel interpolation results * 1 byte/result = 256 // + 16 transform results * 4 bytes/result = 64 // + 16 quant results * 2 bytes/result = 32 // + 16 dequant results * 4 bytes/result = 64 // + 16 luma dc coeffs * 4 bytes/result = 64 // = 1504 bytes. Add 15 to 16-byte align. m_pAllocatedMBEncodeBuffer = (Ipp8u *) H264_Allocate(1504+512, true /*zero-init*/); if (m_pAllocatedMBEncodeBuffer) { // 16-byte align buffer start pPred4DirectB = H264_ALIGN(m_pAllocatedMBEncodeBuffer, 16); pTempBuff4DirectB = pPred4DirectB + 256; pPred4BiPred = pPred4DirectB + 512; pMBEncodeBuffer = pPred4DirectB + 768; } // motion vector storage // a buffer is needed for two (for both fields) previous and current // need space for 2 vectors for each luma block uBufSize = Ipp32u(sizeof(T_ECORE_MV) * uNumberOf4x4Blocks * (4+2) + sizeof(T_ECORE_BIGMV) * uNumberOf4x4Blocks * 4+ 15); m_pAllocatedMVBuffer = (Ipp8u *) H264_Allocate(uBufSize, true /*zero-init*/); if (m_pAllocatedMVBuffer) { // 16-byte align buffer start // storage for direct B mode pMVL0 = (T_ECORE_MV *) H264_ALIGN(m_pAllocatedMVBuffer, 16); pMVL1 = pMVL0 + uNumberOf4x4Blocks; pDMVL0 = (T_ECORE_BIGMV *) ((T_ECORE_MV *)pMVL1 + uNumberOf4x4Blocks); pDMVL1 = pDMVL0 + uNumberOf4x4Blocks; } for (int k=0;k<16;k++) { block_positions[k]=(k&3)+(k>>2)*(MB_Frame_Width<<2); } // Reference index storage for the current and previous frames. uBufSize = Ipp32u(sizeof(T_RefIdx) * uNumberOf4x4Blocks * (4+2) + 15); m_pAllocatedRefIdxBuffer = (Ipp8u *) H264_Allocate(uBufSize, true /*zero-init*/); if (m_pAllocatedRefIdxBuffer) { // 16-byte align buffer start // storage for reference index buffers, per 4x4 pRefIdxL0 = (T_RefIdx *) H264_ALIGN(m_pAllocatedRefIdxBuffer, 16); pRefIdxL1 = pRefIdxL0 + uNumberOf4x4Blocks; } // advanced intra mode storage // a buffer is needed for current // need space for mode for each luma block uBufSize = Ipp32u(sizeof(T_AIMode) * uNumberOf4x4Blocks + 15); m_pAllocatedAIBuffer = (Ipp8u *) H264_Allocate(uBufSize, true /*zero-init*/); if (m_pAllocatedAIBuffer) { // 16-byte align buffer start pAIMode = (T_AIMode *) H264_ALIGN(m_pAllocatedAIBuffer, 16); } // NumCoeffs (non-zero) storage // need space for each 4x4 luma & chroma AC block uBufSize = Ipp32u(sizeof(T_NumCoeffs) * (uNumberOf4x4Blocks + (uNumberOf4x4Blocks >> 1)) + 15); m_pAllocatedNCBuffer = (Ipp8u *) H264_Allocate(uBufSize, true /*zero-init*/); if (m_pAllocatedNCBuffer) { // 16-byte align buffer start pYNumCoeffs = (T_NumCoeffs *) H264_ALIGN(m_pAllocatedNCBuffer, 16); pUNumCoeffs = pYNumCoeffs + uNumberOf4x4Blocks; pVNumCoeffs = pUNumCoeffs + (uNumberOf4x4Blocks>>2); } // MB info storage (2 prev fields + 1 current uBufSize = Ipp32u(sizeof(T_EncodeMBData) * uNumMBs * 3 + 15); m_pAllocatedMBDataBuffer = (Ipp8u *) H264_Allocate(uBufSize, true /*zero-init*/); if (m_pAllocatedMBDataBuffer) { // 16-byte align buffer start pMBData = (T_EncodeMBData *) H264_ALIGN(m_pAllocatedMBDataBuffer, 16); } // Per Slice Data storage uBufSize = Ipp32u(sizeof(SliceData) * num_slices + 15); m_pAllocatedSliceDataBase = (Ipp8u *) H264_Allocate(uBufSize, true /*zero-init*/); if (m_pAllocatedSliceDataBase) { // 16-byte align buffer start pSliceDataBase = (SliceData *) H264_ALIGN(m_pAllocatedSliceDataBase, 16); } pMBOffsets = new T_EncodeMBOffsets[uNumMBs]; // Now check if we got all the memory needed if (NULL == m_pAllocatedMBEncodeBuffer || NULL == m_pAllocatedMVBuffer || NULL == m_pAllocatedRefIdxBuffer || NULL == m_pAllocatedAIBuffer || NULL == m_pAllocatedNCBuffer || NULL == m_pAllocatedMBDataBuffer || NULL == m_pAllocatedSliceDataBase || NULL == pMBOffsets ) { ps = UMC_FAILED_TO_ALLOCATE_BUFFER; goto done; } /*// Initialize all of the MB data and offset arrays InitializeMBData();*/ // Allocate frame buffer for reconstructed Disposable frames, required for advanced // intra prediction while coding the Disposable frames. }done: return ps;} // H264EncoderFrame::allocateParsedFrameData(const sDimensions &size)H264EncoderFrame::~H264EncoderFrame(){ // Just to be safe. deallocateParsedFrameData();}StatusH264EncoderFrame::allocate(const sDimensions &lumaSize,Ipp32s num_slices){ Status ps = UMC_OK; // Clear our state, since allocate is called when we are about // to decode into this frame buffer. m_wasEncoded = false; m_dimensions = lumaSize; // Don't reset m_activeReference or m_lockedForDisplay as these are handled // depending on frame type or by the calling application, respectively ps = allocateParsedFrameData(lumaSize,num_slices); if (ps == UMC_OK) ps = H264EncYUVWorkSpace::allocate(lumaSize,num_slices); fPitch = pitch(); return ps;}void H264EncoderFrame::UpdateFrameNumWrap(Ipp32s CurrFrameNum, Ipp32s MaxFrameNum,Ipp8u CurrPicStruct){ if (isShortTermRef()) { m_FrameNumWrap = m_FrameNum; if (m_FrameNum > CurrFrameNum) m_FrameNumWrap -= MaxFrameNum; if (CurrPicStruct>=FRM_STRUCTURE) { setPicNum(m_FrameNumWrap,0); m_PictureStructureForRef = FRM_STRUCTURE; } else { m_PictureStructureForRef = FLD_STRUCTURE; if (m_bottom_field_flag[0]) { //1st - bottom, 2nd - top if (isShortTermRef(0)) m_PicNum[0] = (2*m_FrameNumWrap)+(CurrPicStruct==BOTTOM_FLD_STRUCTURE); if (isShortTermRef(1)) m_PicNum[1] = (2*m_FrameNumWrap)+(CurrPicStruct==TOP_FLD_STRUCTURE); } else { //1st - top , 2nd - bottom if (isShortTermRef(0)) setPicNum((2*m_FrameNumWrap)+(CurrPicStruct==TOP_FLD_STRUCTURE),0); if (isShortTermRef(1)) setPicNum((2*m_FrameNumWrap)+(CurrPicStruct==BOTTOM_FLD_STRUCTURE),1); } } }} // updateFrameNumWrap//////////////////////////////////////////////////////////////////////////////// updateLongTermPicNum// Updates m_LongTermPicNum for if long term reference, based upon// m_LongTermFrameIdx.//////////////////////////////////////////////////////////////////////////////void H264EncoderFrame::UpdateLongTermPicNum(Ipp8u CurrPicStruct){ if (isLongTermRef()) { if (CurrPicStruct>=FRM_STRUCTURE) { m_LongTermPicNum[0] = m_LongTermFrameIdx; m_LongTermPicNum[1] = m_LongTermFrameIdx; } else { if (m_bottom_field_flag[0]) { //1st - bottom, 2nd - top m_LongTermPicNum[0] = 2*m_LongTermFrameIdx+(CurrPicStruct==BOTTOM_FLD_STRUCTURE); m_LongTermPicNum[1] = 2*m_LongTermFrameIdx+(CurrPicStruct==TOP_FLD_STRUCTURE); } else { //1st - top , 2nd - bottom m_LongTermPicNum[0] = 2*m_LongTermFrameIdx+(CurrPicStruct==TOP_FLD_STRUCTURE); m_LongTermPicNum[1] = 2*m_LongTermFrameIdx+(CurrPicStruct==BOTTOM_FLD_STRUCTURE); } } }} // updateLongTermPicNumH264EncoderFrameList::~H264EncoderFrameList(){ H264EncoderFrame *pCurr = m_pHead; while (pCurr) { H264EncoderFrame *pNext = pCurr->future(); delete pCurr; pCurr = pNext; } m_pHead = m_pTail = 0;}H264EncoderFrame* H264EncoderFrameList::detachHead(){ H264EncoderFrame *pHead = m_pHead; if (pHead) { m_pHead = m_pHead->future(); if (m_pHead) m_pHead->setPrevious(0); else { m_pTail = 0; } } m_pCurrent = m_pHead; return pHead;}void H264EncoderFrameList::RemoveFrame(H264EncoderFrame *pFrm){ H264EncoderFrame *pPrev = pFrm->previous(); H264EncoderFrame *pFut = pFrm->future(); if (pFrm==m_pHead) //must be equal to pPrev==NULL { VM_ASSERT(pPrev==NULL); detachHead(); } else { if (pFut==NULL) { m_pTail = pPrev; pPrev->setFuture(0); } else { pPrev->setFuture(pFut); pFut->setPrevious(pPrev); } } m_pCurrent = m_pHead;}//////////////////////////////////////////////////////////////////////////////// append// Appends a new decoded frame buffer to the "end" of the linked list//////////////////////////////////////////////////////////////////////////////voidH264EncoderFrameList::append(H264EncoderFrame *pFrame){ // Error check if (!pFrame) { // Sent in a NULL frame return; } // Has a list been constructed - is their a head? if (!m_pHead) { // Must be the first frame appended // Set the head to the current m_pHead = pFrame; m_pHead->setPrevious(0); m_pCurrent = m_pHead; } if (m_pTail) { // Set the old tail as the previous for the current pFrame->setPrevious(m_pTail); // Set the old tail's future to the current m_pTail->setFuture(pFrame); } else { // Must be the first frame appended // Set the tail to the current m_pTail = pFrame; } // The current is now the new tail m_pTail = pFrame; m_pTail->setFuture(0); //}voidH264EncoderFrameList::insertAtCurrent(H264EncoderFrame *pFrame){ if (m_pCurrent)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -