📄 umc_h264_aic.cpp
字号:
//// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2004 - 2005 Intel Corporation. All Rights Reserved.//#include <string.h>#include "vm_debug.h"#include "umc_h264_video_encoder.h"#include "umc_h264_gen_enc.h"#include "umc_h264_tables.h"////////////////////////////////////////////////////////////////////////////////// Intra4x4InitBlockParams//// Sets up the parameters for the 4x4 block level mode select function. Must// be called once per MB prior to calling the mode select function.//////////////////////////////////////////////////////////////////////////////////// Uncomment the following #define to remove the left MB dependency in the// code to select the 4x4 Intra mode for a given block.//#define NOINTRALEFTDEP// Enable following to test C_AIModeSelectOneMB_16x16 by comparing// results with ASM variants.//#define TEST_16x16MS_BY_COMPARE// 4x4 Prediction Details// The predictors for the 16 pels of a 4x4 block are obtained using pels// above and to the left of the block, used dependent upon prediction mode.//// Notation for comments regarding prediction and predictors.// The pels of the 4x4 block are labelled a..p. The predictor pels above// are labelled A..H, from the left I..L, and from above left M, as follows://// M A B C D E F G H// I a b c d// J e f g h// K i j k l// L m n o p// Predictor array index definitions#define P_M PredPel[0]#define P_A PredPel[1]#define P_B PredPel[2]#define P_C PredPel[3]#define P_D PredPel[4]#define P_E PredPel[5]#define P_F PredPel[6]#define P_G PredPel[7]#define P_H PredPel[8]#define P_I PredPel[9]#define P_J PredPel[10]#define P_K PredPel[11]#define P_L PredPel[12]// Predicted pixel array offset macros#define P_a pPredBuf[0]#define P_b pPredBuf[1]#define P_c pPredBuf[2]#define P_d pPredBuf[3]#define P_e pPredBuf[0+1*16]#define P_f pPredBuf[1+1*16]#define P_g pPredBuf[2+1*16]#define P_h pPredBuf[3+1*16]#define P_i pPredBuf[0+2*16]#define P_j pPredBuf[1+2*16]#define P_k pPredBuf[2+2*16]#define P_l pPredBuf[3+2*16]#define P_m pPredBuf[0+3*16]#define P_n pPredBuf[1+3*16]#define P_o pPredBuf[2+3*16]#define P_p pPredBuf[3+3*16]using namespace UMC_H264_ENCODER;namespace UMC{void H264VideoEncoder::Intra4x4InitBlockParams( T_4x4IntraModeSelParams *pModeSelParams, // params to init Ipp32u uMB){ pModeSelParams->uEdgeType = m_pCurrentFrame->pMBData[uMB].uEdgeType; pModeSelParams->uPitch = m_pCurrentFrame->m_pitch; pModeSelParams->uWidthIn4x4Blocks = uWidthIn4x4Blocks; pModeSelParams->uQP = m_pCurrentFrame->pMBData[uMB].uMBQP; uSADTable[0] = uSADTable[1] = uSADTable[2] = uSADTable[3] = uSADTable[4] = uSADTable[5] = uSADTable[6] = uSADTable[7] = uSADTable[8] = uSADTable[9] = (4 * (Ipp16u)rd_quant[pModeSelParams->uQP])>>3; uSADTable[10] = (Ipp16u)rd_quant[pModeSelParams->uQP]>>3; // uUseURPred is an array indexed by MB block (0..23) indicating whether // to use the 4 prediction pels above and to the right of the block. A // value of 1 indicates use the pels, else 0. It should contain 1 except: // (a) for blocks 7, 13, 15, 19, and 23 -- the blocks on the right edge of // the MB but not on the top edge of the MB; and // (b) for blocks 5, 17, and 21 (the top right corner blocks of the MB) // when the MB is at the right edge. // Top edge does not need to be considered because the modes using these 4 // predictor pels are not used when the block is on a top edge. // Init to 1, then zero the few as needed memset(&(pModeSelParams->uUseURPred), 1, sizeof pModeSelParams->uUseURPred); pModeSelParams->uUseURPred[3] = 0; pModeSelParams->uUseURPred[7] = 0; pModeSelParams->uUseURPred[11] = 0; pModeSelParams->uUseURPred[13] = 0; pModeSelParams->uUseURPred[15] = 0; pModeSelParams->uUseURPred[19] = 0; pModeSelParams->uUseURPred[23] = 0; if ((pModeSelParams->uEdgeType & MBEdgeTypeIsNotRightEdge) == 0) { // MB is at a right edge pModeSelParams->uUseURPred[5] = 0; pModeSelParams->uUseURPred[17] = 0; pModeSelParams->uUseURPred[21] = 0; }} // Intra4x4InitBlockParams////////////////////////////////////////////////////////////////////////////////// AdvancedIntraModeSelectOneMacroblock//// Main function to drive advanced intra mode select for one macroblock.////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::AdvancedIntraModeSelectOneMacroblock( Ipp32u uMB, // which MB Ipp32u *puAIMBSAD // return total MB SAD here){ Ipp32u uBlock; Ipp32u uAIIndex; Ipp32u uMBQP = m_pCurrentFrame->pMBData[uMB].uMBQP; Ipp8u* pBlock; T_AIMode *pMode; // pointer to selected mode for a block T_4x4IntraModeSelParams ModeSelParams; // for block function // All 9 intra modes are checked. Since we treat all 4x4 blocks before // coding/decoding the prediction may not be based on decoded pixels (except // for some of the blocks). Therefore original pixel data are used for // prediction in this assessment of intra coding. This will result in // too good prediction. // To compensate for this the SAD for intra is given a 'handicap' // depending on QP. Notice: Original data is used for prediction only // in mode selection. When real coding is performed, prediction is made // from decoded data *puAIMBSAD = rd_quant_intra[uMBQP]; // get result array index for first block of the MB uAIIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex; // init pointer to result array pMode = &m_pCurrentFrame->pAIMode[uAIIndex]; // pointer to upper left pel of first block pBlock = m_pCurrentFrame->m_pYPlane + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift; Intra4x4InitBlockParams(&ModeSelParams, uMB); // loop over all 16 4x4 blocks in the MB for (uBlock=0; uBlock<16; uBlock++) { // CPU-dependent call to block level mode select *puAIMBSAD += AIModeSelectOneBlock( &ModeSelParams, pBlock, // source block pBlock, // no reference block yet, use source for ref. uBlock, pMode, NULL); // no return of predictor pels // next block pMode += m_EncBlockIndexInc[uBlock]; pBlock += m_EncBlockOffsetInc[uBlock]; }} // AdvancedIntraModeSelectOneMacroblock////////////////////////////////////////////////////////////////////////////////// Encode MB_Type and Advanced Intra Prediction mode for each luma 4x4 block.// Also Encode the Chroma 8x8 Intra Prediction mode.////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Encode_AIC_Type(Ipp32u uMB){ bool bMBIsOnTopEdge; bool bMBIsOnLeftEdge; Ipp32s prob0; T_AIMode iLeftMode; T_AIMode iAboveMode; T_AIMode iThisMode; T_AIMode iMostProbMode; Ipp32u uBlock; Ipp32u uAIIndex, N, length; // Encode MB_Type N = CALC_4x4_INTRA_MB_TYPE(m_SliceHeader.slice_type); if (m_PicParamSet.entropy_coding_mode) { MB_Type left_n,top_n; left_n = Get_Left_Value(uMB,m_pCurrentFrame->pMBData[uMB-1].uMBType,NUMBER_OF_MBTYPES); top_n= Get_Top_Value(uMB,m_pCurrentFrame->pMBData[uMB-uWidthInMBs].uMBType,NUMBER_OF_MBTYPES); m_pbitstream->MBTypeInfo_CABAC(m_SliceHeader.slice_type,N,MBTYPE_INTRA,left_n,top_n); } else length = m_pbitstream->PutVLCCode(N); bMBIsOnTopEdge = 0 == (m_pCurrentFrame->pMBData[uMB].uEdgeType & MBEdgeTypeIsNotTopEdge); bMBIsOnLeftEdge = 0 == (m_pCurrentFrame->pMBData[uMB].uEdgeType & MBEdgeTypeIsNotLeftEdge); // get AIC type array index for first block of the MB uAIIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex; // Loop over 16 blocks. One block is coded in each iteration for (uBlock = 0; uBlock < 16; uBlock += 1) { // Use the prediction mode of the block above, the block to // the left, and current block to code type, combining in a pair // of blocks. Prediction mode of above/left blocks is 0 if they // are not present (edge) or are not INTRA. // Block one, block above type iAboveMode = -1; if ((uEncNotEdge[uBlock] & MBEdgeTypeIsNotTopEdge) || !bMBIsOnTopEdge) iAboveMode = m_pCurrentFrame->pAIMode[uAIIndex - uWidthIn4x4Blocks]; // Block one, block left type iLeftMode = -1; if ((uEncNotEdge[uBlock] & MBEdgeTypeIsNotLeftEdge) || !bMBIsOnLeftEdge) iLeftMode = m_pCurrentFrame->pAIMode[uAIIndex - 1]; // Block one AI mode iThisMode = m_pCurrentFrame->pAIMode[uAIIndex]; // The most probable mode is the Minimum of the two predictors iMostProbMode = MIN(iAboveMode, iLeftMode); if (iMostProbMode == -1) { // Unless one or both of the predictors is "outside" iMostProbMode = 2; // In this case it defaults to mode 2 (DC Prediction). } // The probability of the current mode is 0 if it equals the Most Probable Mode if (iMostProbMode == iThisMode) { prob0 = -1; } else if (iThisMode < iMostProbMode ) { // Otherwise, the mode probability increases prob0 = iThisMode; // (the opposite of intuitive notion of probability) } else { // with the order of the the remaining modes. prob0 = iThisMode-1; } if (m_PicParamSet.entropy_coding_mode) { m_pbitstream->IntraPredMode_CABAC(prob0); } else { if (prob0 >= 0) { m_pbitstream->PutBits(0, 1); // Not the most probable type, 1 bit m_pbitstream->PutBits(prob0, 3); // +3 bits to signal actual mode } else { m_pbitstream->PutBits(1, 1); // most probable type in 1 bit } } uAIIndex += m_EncBlockIndexInc[uBlock]; } // Encode Chroma Prediction Mode if (m_PicParamSet.entropy_coding_mode) { int left_p,top_p; left_p=Get_Left_Value(uMB,m_pCurrentFrame->pMBData[uMB-1].uChromaType,0); top_p=Get_Top_Value(uMB,m_pCurrentFrame->pMBData[uMB-uWidthInMBs].uChromaType,0); m_pbitstream->ChromaIntraPredMode_CABAC(m_pCurrentFrame->pMBData[uMB].uChromaType,left_p!=0,top_p!=0); } else length = m_pbitstream->PutVLCCode(m_pCurrentFrame->pMBData[uMB].uChromaType);} // Encode_AIC_Type////////////////////////////////////////////////////////////////////////////////// Intra16x16SelectAndPredict//// Main function to choose the best 16x16 intra prediction mode and// return the corresponding prediction for the MB.//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Intra16x16SelectAndPredict( Ipp32u uMB, // which MB Ipp32u *puAIMBSAD, // return total MB SAD here Ipp8u *pPredBuf // return predictor pels here){ Ipp32u uAIIndex; Ipp32u i; T_AIMode BestMode; // selected mode goes here Ipp32u uSmallestSAD; int left = m_pCurrentFrame->uMBxpos > 0; // shows whether pixels are available to the left of the MB. int top = m_pCurrentFrame->uMBypos > 0; // shows whether pixels are available above the MB. int available = (top<<1)|left; uSmallestSAD = AIModeSelectOneMB_16x16( m_pCurrentFrame->m_pYPlane + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift, m_pReconstructFrame->m_pYPlane + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift, m_pCurrentFrame->uPitch, m_pCurrentFrame->pMBData[uMB].uEdgeType, available, &BestMode, pPredBuf); // prediction pels stored here // return best SAD *puAIMBSAD = uSmallestSAD; // put selected mode in AIMode fields for the MB uAIIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex; m_pCurrentFrame->pAIMode[uAIIndex] = BestMode; // Selected mode is stored in block 0 uAIIndex += m_EncBlockIndexInc[0]; for (i=1; i<16; i++) { m_pCurrentFrame->pAIMode[uAIIndex] = 2; // These blocks get filled with 2 uAIIndex += m_EncBlockIndexInc[i]; // for 4x4 mode prediction }} // Intra16x16SelectAndPredict////////////////////////////////////////////////////////////////////////////////// Encode MB_Type and Luma/Chroma Prediction modes for Intra 16x16 MB////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Encode_AIC_Type_16x16(Ipp32u uMB){ Ipp32u length; Ipp32s N; // Encode MB_Type, Luma Prediction Mode, Luma AC coeff flag, and Chroma DC/AC (NC) flag N = CALC_16x16_INTRA_MB_TYPE(m_SliceHeader.slice_type, m_pCurrentFrame->pAIMode[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex], m_pCurrentFrame->pMBData[uMB].uChromaNC, m_pCurrentFrame->pMBData[uMB].uLumaAC); if (m_PicParamSet.entropy_coding_mode) { MB_Type left_n,top_n; left_n = Get_Left_Value(uMB,m_pCurrentFrame->pMBData[uMB-1].uMBType,NUMBER_OF_MBTYPES); top_n= Get_Top_Value(uMB,m_pCurrentFrame->pMBData[uMB-uWidthInMBs].uMBType,NUMBER_OF_MBTYPES); m_pbitstream->MBTypeInfo_CABAC(m_SliceHeader.slice_type,N,MBTYPE_INTRA_16x16,left_n,top_n); int left_p,top_p; left_p=Get_Left_Value(uMB,m_pCurrentFrame->pMBData[uMB-1].uChromaType,0); top_p=Get_Top_Value(uMB,m_pCurrentFrame->pMBData[uMB-uWidthInMBs].uChromaType,0); m_pbitstream->ChromaIntraPredMode_CABAC(m_pCurrentFrame->pMBData[uMB].uChromaType,left_p!=0,top_p!=0); } else { length = m_pbitstream->PutVLCCode(N); // Encode Chroma Prediction Mode length = m_pbitstream->PutVLCCode(m_pCurrentFrame->pMBData[uMB].uChromaType); }} // Encode_AIC_Type_16x16////////////////////////////////////////////////////////////////////////////////// Encode MB_Type and alignment bits for PCM 16x16 MB followed by the// 384 pcm_bytes for the MB////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Encode_PCM_MB(Ipp32u uMB){ Ipp32u length, row, col;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -