📄 umc_h264_core_enc.cpp
字号:
// deblock filter just completed if (m_PicClass != DISPOSABLE_PIC) { // fill edge buffers of the reconstructed frame int pels_scale = 3;//(m_PicParamSet.picture_structure == FRAME_PICTURE)? 3: 2; ExpandPlane( m_pCurrentFrame->m_pYPlane+m_pCurrentFrame->y_line_shift, uWidthInMBs*16, uHeightInMBs*16, m_pCurrentFrame->uPitch, 3<<pels_scale); // was 16 ExpandPlane( m_pCurrentFrame->m_pUPlane+m_pCurrentFrame->uv_line_shift, uWidthInMBs*16>>1, uHeightInMBs*16>>1, m_pCurrentFrame->uPitch, 2<<pels_scale); // was 8 ExpandPlane( m_pCurrentFrame->m_pVPlane+m_pCurrentFrame->uv_line_shift, uWidthInMBs*16>>1, uHeightInMBs*16>>1, m_pCurrentFrame->uPitch, 2<<pels_scale); // was 8 }#if 0 Ipp8u *pYDst, *pUDst, *pVDst; Ipp32u uDstPitch; if (m_PicClass != DISPOSABLE_PIC) { pYDst = m_pCurrentFrame->m_pYPlane; pUDst = m_pCurrentFrame->m_pUPlane; pVDst = m_pCurrentFrame->m_pVPlane; uDstPitch = m_pCurrentFrame->m_pitch; } else { pYDst = m_pCurrentFrame->m_pYPlane; pUDst = m_pCurrentFrame->m_pUPlane; pVDst = m_pCurrentFrame->m_pVPlane; uDstPitch = m_pCurrentFrame->m_pitch; } // write reconstructed frame to file writeimage("e:\\tmp\\im2.raw",pYDst,pUDst,pVDst, uWidthInMBs<<4, uHeightInMBs<<4,uDstPitch,false,"ab");#endif} // End_Picture// This routine returns true if the current slice has coded a number of macroblocks// as INTRA that exceeded the INTRA_PERCENTAGE_THRESHOLD constant.bool H264VideoEncoder::Intra_Slice_Test(){#ifdef INTRA_THRESHOLD return (m_Intra_MB_Counter * 100 / m_MB_Counter > INTRA_PERCENTAGE_THRESHOLD);#else return false;#endif}////////////////////////////////////////////////////////////////////////////////// InitializeMBData//// One-time (after allocation) initialization of the per MB data,// specifically edge flags which are set to match picture edges,// the MB offsets, and block index.//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::InitializeMBData(){ Ipp32u uMB = 0; Ipp32u uMBCol = 0; Ipp32u uMBRow = 0; Ipp8u uEdgeType = 0; Ipp32u uLumaOffset = 0; Ipp32u uChromaOffset = 0; Ipp32u uChromaBlockIndex = 0; Ipp32u uBlockIndex = 0; // Initialize the MB slices first, so that the edge calculations // below come out correctly. Make_MBSlices(); for (uMBRow = 0; uMBRow < uHeightInMBs; uMBRow++) { for (uMBCol = 0; uMBCol < uWidthInMBs; uMBCol++, uMB++) { uEdgeType = (Ipp8u)Make_MBEdgeType(uMB); m_pCurrentFrame->pMBData[uMB].uEdgeType = uEdgeType; m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset = uLumaOffset; m_pCurrentFrame->pMBOffsets[uMB].uChromaOffset = uChromaOffset; m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex = uBlockIndex; m_pCurrentFrame->pMBOffsets[uMB].uFirstChromaBlockIndex = uChromaBlockIndex; uLumaOffset += 16; uChromaOffset += 8; uBlockIndex += 4; uChromaBlockIndex += 2; } uLumaOffset += m_pCurrentFrame->uPitch*16 - uWidthInMBs*16; uChromaOffset += m_pCurrentFrame->uPitch*8 - uWidthInMBs*8; uChromaBlockIndex += (uWidthIn4x4Blocks>>1); uBlockIndex += uWidthIn4x4Blocks*4 - uWidthIn4x4Blocks; } Set_MVLimits();} // InitializeMBData/////////////////////////////////////////////////////////////////////////// Make_MBSlices - "Slices" the frame by writing a Slice// number into the uSlice member of the per MB data structure.// Right now, this method implements a simple scheme where a number// of fixed length Slices are present in a single JVT Slice Group,// and the last slice contains any "remainder" MBs (and thus may be larger).//// Other slicing schemes can be implemented by parameterizing this// method to produce different values of uSlice for each MB.// If doing something other than simple raster ordered slices, then// don't forget to change the Picture Header to properly encode the// chosen slicing method as appropriate "Slice Groups".// Right now, only a single Slice Group is used, so there is no// mb_allocation_map_type coded./////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Make_MBSlices(){ Ipp32u uMB = 0; Ipp16u uSlice = 0; Ipp32u uSliceMBCnt = 0; for (uMB = 0; uMB < uHeightInMBs*uWidthInMBs; uMB++) { m_pCurrentFrame->pMBData[uMB].uSlice = uSlice; uSliceMBCnt++; if ((uSliceMBCnt == m_pCurrentFrame->uSliceLength) && (uSlice < m_pCurrentFrame->uNumSlices-1)) { uSlice++; uSliceMBCnt = 0; } }} // Make_MBSlices//// MBEdgeType is defined as follows:// bit 0 or the least significant bit is left// bit 1 is right// bit 2 is top// bit 3 is bottom// BUT - to indicate ENABLED the bit is zero//// Also the 4 edge bits in 0:3 are duplicated in the upper nibble 4:7// The lower 4 edge bits possibly modified as the frame is compressed// The upper 4 edge bits are left intact.//// Make_MBEdgeType returns an 8 bit value in a Ipp32u//Ipp32u H264VideoEncoder::Make_MBEdgeType( Ipp32u MBIndex ){ Ipp32u MBEdgeType; MBEdgeType = 0x0F; // init to no edge type (center of frame) if ((MBIndex % uWidthInMBs) == 0) { MBEdgeType &= MBEdgeTypeIsLeftEdge; MBEdgeType &= MBEdgeTypeIsUpperLeftCorner; } // If this MB is in a different slice group from the previous MB else if (m_pCurrentFrame->pMBData[MBIndex].uSlice != m_pCurrentFrame->pMBData[MBIndex-1].uSlice) { MBEdgeType &= MBEdgeTypeIsLeftEdge; } if (MBIndex < uWidthInMBs) { MBEdgeType &= MBEdgeTypeIsTopEdge; MBEdgeType &= MBEdgeTypeIsUpperLeftCorner; MBEdgeType &= MBEdgeTypeIsRightEdge; } // If this MB is in a different slice group from the MB above else if (m_pCurrentFrame->pMBData[MBIndex].uSlice != m_pCurrentFrame->pMBData[MBIndex-uWidthInMBs].uSlice) { MBEdgeType &= MBEdgeTypeIsTopEdge; } if (((MBIndex + 1) % uWidthInMBs) == 0) { MBEdgeType &= MBEdgeTypeIsRightEdge; } // If this MB is in a different slice group from the next MB // one row above and this isn't a top edge... else if ((MBIndex >= uWidthInMBs) && (m_pCurrentFrame->pMBData[MBIndex].uSlice != m_pCurrentFrame->pMBData[MBIndex-uWidthInMBs+1].uSlice)) { MBEdgeType &= MBEdgeTypeIsRightEdge; } // If this MB is in a different slice group from the above-left MB // And this MB is not on a top or left edge, then this is an UpperLeftCorner if ((MBIndex >= uWidthInMBs) && (MBIndex % uWidthInMBs) && (m_pCurrentFrame->pMBData[MBIndex].uSlice != m_pCurrentFrame->pMBData[MBIndex-uWidthInMBs-1].uSlice)) { MBEdgeType &= MBEdgeTypeIsUpperLeftCorner; } MBEdgeType |= ((MBEdgeType & 0x0F) << 4); return MBEdgeType;} // Make_MBEdgeType////////////////////////////////////////////////////////////////////////////////// Set_MVLimits//// Initialize the MVLimits field of the MB offsets struct for all MBs. The field// contains the maximum (picture edge limited) search range in each// direction for each MB.//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Set_MVLimits(){ Ipp32u row, col; Ipp8u left, right, up, down; Ipp32u search_range_in_MBs = 2; T_EncodeMBOffsets *pMBOffsets = m_pCurrentFrame->pMBOffsets; Ipp8u bSearchBeyondEdges = true; if (bSearchBeyondEdges) { for ( row = 0; row < uHeightInMBs; row++ ) { for (col = 0; col < uWidthInMBs; col++) { if (col < search_range_in_MBs) left = (Ipp8u)((col+1)<<4); else left = (Ipp8u)(search_range_in_MBs<<4); if (row < search_range_in_MBs) up = (Ipp8u)((row+1)<<4); else up = (Ipp8u)(search_range_in_MBs<<4); if (col >= uWidthInMBs - search_range_in_MBs) right = (Ipp8u)((uWidthInMBs - col)<<4); else right = (Ipp8u)(search_range_in_MBs<<4); if (row >= uHeightInMBs - search_range_in_MBs) down = (Ipp8u)((uHeightInMBs - row)<<4); else down = (Ipp8u)(search_range_in_MBs<<4); // We don't want any MVs exceeding +/- 31 pels, so clip for that too... // This is because MVs are internally stored as Ipp8s = +/- 127 (for subpelfactor = 4) left = (Ipp8u)MIN( 31, left ); right = (Ipp8u)MIN( 31, right ); up = (Ipp8u)MIN( 31, up ); down = (Ipp8u)MIN( 31, down ); pMBOffsets->uMVLimits = (down<<24) | (up<<16) | (right<<8) | left; pMBOffsets++; } } } else { for ( row = 0; row < uHeightInMBs; row++ ) { for (col = 0; col < uWidthInMBs; col++) { // No special cases due to interpolation filters here because // reference planes are expanded enough to allow the possible // subpel interpolation references just beyond edges. left = (Ipp8u)MIN( search_range_in_MBs, col ); right = (Ipp8u)MIN( search_range_in_MBs, uWidthInMBs - col - 1 ); up = (Ipp8u)MIN( search_range_in_MBs, row); down = (Ipp8u)MIN( search_range_in_MBs, uHeightInMBs - row - 1); // convert from range in MBs to range in pels, save pMBOffsets->uMVLimits = (down<<(24+4)) | (up<<(16+4)) | (right<<(8+4)) | left << 4; pMBOffsets++; } } }} // Set_MVLimits// This routine returns pointer to the beginning of the// slice database array.SliceData * H264VideoEncoder::Get_SliceDataBase_Pointer(){ return(&(m_pCurrentFrame->pSliceDataBase[0]));}// This routine returns pointer to the beginning of the// macroblock info array.T_EncodeMBData *H264VideoEncoder::Get_MBInfoArray_Pointer(){ return&(m_pCurrentFrame->pMBData[0]);}void H264VideoEncoder::ScanSignificant_CABAC(Ipp16s coeff[], int ctxBlockCat,int numcoeff,Ipp32s *dec_single_scan, T_Block_CABAC_Data* c_data){ Ipp8u start_scan, end_scan, j; int i; switch(numcoeff) { case 16:start_scan = 0;end_scan=15;break; case 15:start_scan = 1;end_scan=15;break; case 4:start_scan = 0;end_scan=3;break; default: VM_ASSERT(false); start_scan = 0; end_scan = 0; break; } c_data->uLastCoeff = end_scan; //dec_single_scan[end_scan]; By Burakov seems to be an error. c_data->uFirstCoeff = start_scan;//dec_single_scan[start_scan]; By Burakov seems to be an error. for (i=end_scan;i>=start_scan;i--) { int coef=coeff[dec_single_scan[i]]; if (coef) { end_scan = (Ipp8u)i; break; } } c_data->uLastSignificant = end_scan; for (i=start_scan;i<=end_scan;i++) { int coef=coeff[dec_single_scan[i]]; if (coef) { start_scan = (Ipp8u)i; break; } } c_data->uFirstSignificant = start_scan; for (i=c_data->uFirstSignificant,j=0;i<=c_data->uLastSignificant;i++) { int coef=coeff[dec_single_scan[i]]; if (coef) { int sign = coef < 0; c_data->uSignificantMap[j] = (Ipp8u)i; c_data->uSignificantLevels[j] = (Ipp16u)(labs(coef)-1); c_data->uSignificantSigns[j] = (Ipp8u)sign; j++; } } c_data->uNumSigCoeffs = j; c_data->CtxBlockCat = ctxBlockCat;}void H264VideoEncoder::SetPictureQuant(){ // If this is an INTER frame switch (m_PicType) { case PREDPIC: m_SliceHeader.slice_qp_delta = m_info.rate_controls.quant - m_PicParamSet.pic_init_qp; break; case BPREDPIC: if (m_info.B_frame_rate_controls.method == H264_RCM_QUANT) { m_SliceHeader.slice_qp_delta = m_info.B_frame_rate_controls.quant - m_PicParamSet.pic_init_qp; } else { m_SliceHeader.slice_qp_delta = m_info.rate_controls.quant - m_PicParamSet.pic_init_qp; } break; case INTRAPIC: if (m_info.key_frame_controls.rate_controls.method == H264_RCM_QUANT) { m_SliceHeader.slice_qp_delta = m_info.key_frame_controls.rate_controls.quant - m_PicParamSet.pic_init_qp; } else { m_SliceHeader.slice_qp_delta = m_info.rate_controls.quant - m_PicParamSet.pic_init_qp; } break; default: break; }}} //namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -