⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_ermb.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
////               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 "umc_h264_video_encoder.h"#include "umc_h264_tables.h"#include "umc_h264_bme.h"#include "ippdefs.h"Ipp32s dec_single_scan[2][16] = {    {0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15},    {0,4,1,8,12,5,9,13,2,6,10,14,3,7,11,15}};Ipp32s dec_single_scan_p[4] = {0,1,2,3};Ipp16s enc_single_scan[2][16] = {    {0,1,5,6,2,4,7,12,3,8,11,13,9,10,14,15},    {0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15}};////////////////////////////////////////////////////////////////////////////////// CEncAndRec4x4IntraMB//// Encode and Reconstruct all blocks in one Intra macroblock with 4x4 prediction//using namespace UMC_H264_ENCODER;////////////////////////////////////////////////////////////////////////////////namespace UMC{Ipp32u H264VideoEncoder::CEncAndRec4x4IntraMB(Ipp32u uMB){    Ipp32u  uBlock;     // block number, 0 to 23    Ipp32u  uIndex;     // block-dependent, into AI and MV arrays    Ipp32u  uOffset;        // to upper left corner of block from start of plane    Ipp32u  uMBQP;          // QP of current MB    Ipp32u  uMBType;        // current MB type    Ipp8u   uMBEdgeType;    // current MB edge type    Ipp32u  uCBP4x4;        // coded flags for all 4x4 blocks    Ipp32u  uIntraSAD;      // intra MB SAD    Ipp16s* pMassDiffBuf;   // difference block pointer    Ipp16s* pTempDiffBuf;   // difference block pointer    Ipp16s* pDCBuf;     // chroma & luma dc coeffs pointer    Ipp8u*  pPredBuf;       // prediction block pointer    Ipp16s* pDiffBuf;       // difference block pointer    Ipp16s* pQBuf;          // quantized block pointer//  Ipp16s* pDQBuf;     // dequantized block pointer    Ipp8u*  pSrcPlane;      // start of plane to encode    Ipp8u*  pRecPlane;      // start of reconstructed plane    Ipp32u  uPitch;     // buffer pitch    Ipp32s  iMBCost;        // recode MB cost counter    Ipp32s  iBlkCost[2];    // coef removal counter for left/right 8x8 luma blocks    Ipp8u   bCoded; // coded block flag    T_4x4IntraModeSelParams ModeSelParams;  // for 4x4 intra block function    T_NumCoeffs  iNumCoeffs;    // Number of nonzero coeffs after quant (negative if DC is nonzero)    Ipp8u        uLastCoeff;    // Number of nonzero coeffs after quant (negative if DC is nonzero)    Ipp32u   RLE_Offset;    // Index into BlockRLE array    //Ipp32u  rc;#ifdef _INTRA_MODE_SWITCH_    Ipp32u   SaveIntraPred[4];#endif    uPitch      = m_pCurrentFrame->uPitch;    uCBP4x4     = m_pCurrentFrame->pMBData[uMB].uCBP4x4;    uMBQP       = m_pCurrentFrame->pMBData[uMB].uMBQP;    uMBType     = m_pCurrentFrame->pMBData[uMB].uMBType;    uMBEdgeType = m_pCurrentFrame->pMBData[uMB].uEdgeType;    pPredBuf    = m_pCurrentFrame->pMBEncodeBuffer; // 16-byte aligned work buffer    pDiffBuf    = (Ipp16s*) (pPredBuf + 512);    pQBuf       = (Ipp16s*) (pDiffBuf + 16);//  pDQBuf      = (Ipp16s*) (pQBuf + 16);    pDCBuf      = (Ipp16s*) (pQBuf + 16);   // Used for both luma and chroma DC blocks    pMassDiffBuf= (Ipp16s*) (pDCBuf+ 16);//  uIntraSAD   = rd_quant_intra[uMBQP] * 24;   // 'handicap' using reconstructed data    uIntraSAD   = 0;    iMBCost     = 0;    iBlkCost[0] = 0;    iBlkCost[1] = 0;#ifdef _INTRA_MODE_SWITCH_    // Four 32 bit values (16 pels) are saved from the prediction buffer so that they can be restored    // in the event that this MB gets recoded as 16x16 Intra.  The Pred buffer currently contains the    // best 16x16 Intra mode prediciton, and this function only changes the upper 4x4 block    SaveIntraPred[0] = *((Ipp32u*)pPredBuf);    SaveIntraPred[1] = *((Ipp32u*)(pPredBuf+16));    SaveIntraPred[2] = *((Ipp32u*)(pPredBuf+32));    SaveIntraPred[3] = *((Ipp32u*)(pPredBuf+48));#endif    //--------------------------------------------------------------------------    // encode Y plane blocks (0-15)    //--------------------------------------------------------------------------    // initialize pointers and offset    pSrcPlane = m_pCurrentFrame->m_pYPlane;    pRecPlane = m_pReconstructFrame->m_pYPlane;    uOffset = m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift;    // get AI/MV array index for first block of the MB    uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex;    // MB level init for 4x4 intra mode select    Intra4x4InitBlockParams(&ModeSelParams, uMB);    // loop over all 4x4 blocks in Y plane for the MB    for (uBlock = 0; uBlock < 16; )    {        pPredBuf = m_pCurrentFrame->pMBEncodeBuffer + xoff[uBlock] + yoff[uBlock]*16;        m_pCurrentFrame->pYNumCoeffs[uIndex] = 0;        // These will be updated if the block is coded        if (m_PicParamSet.entropy_coding_mode)        {            m_pCurrentFrame->Block_CABAC[uBlock].uNumSigCoeffs = 0;        }        else        {            m_pCurrentFrame->Block_RLE[uBlock].uNumCoeffs = 0;            m_pCurrentFrame->Block_RLE[uBlock].uTrailing_Ones = 0;            m_pCurrentFrame->Block_RLE[uBlock].uTrailing_One_Signs = 0;            m_pCurrentFrame->Block_RLE[uBlock].uTotalZeros = 16;        }        // find advanced intra prediction block, store in PredBuf        // Select best AI mode for the block, using reconstructed        // predictor pels. This function also stores the block        // predictor pels at pPredBuf.        uIntraSAD += AIModeSelectOneBlock(            &ModeSelParams,            pSrcPlane + uOffset,            pRecPlane + uOffset,            uBlock,            &m_pCurrentFrame->pAIMode[uIndex],            pPredBuf);        // check if block is coded        bCoded = ((uCBP4x4 & CBP4x4Mask[uBlock])?(1):(0));        if (!bCoded)        {            // update reconstruct frame for the empty block            Copy4x4(                pPredBuf,               // predictor block                uPitch,                pRecPlane + uOffset);   // reconstruct frame        }        else        {   // block not declared empty, encode            // compute difference of predictor and source pels            // note: asm version does not use pDiffBuf            //       output is being passed in the mmx registers            Diff4x4(                pPredBuf,               // predictor pels                pSrcPlane + uOffset,    // source pels                uPitch,                 // source pitch                pDiffBuf);              // result buffer            // forward transform, in place in iDiffBuf            // note: asm version does not use pDiffBuf            //       input and output are being passed in the mmx reg.s            // quantization and dequantization            // note: asm version does not use pDiffBuf and pDQBuf            //       these values are being passed in the mmx registers                ippiTransformQuantResidual_H264_16s_C1I (pDiffBuf,uMBQP,&iNumCoeffs,(m_SliceHeader.slice_type == INTRASLICE),                    enc_single_scan[m_PicParamSet.picture_structure != FRAME_PICTURE],&uLastCoeff);            // if everything quantized to zero, skip RLE            if (!iNumCoeffs)            {                // the block is empty so it is not coded                bCoded = 0;            }            else            {                // Preserve the absolute number of coeffs.                m_pCurrentFrame->pYNumCoeffs[uIndex] = (T_NumCoeffs)ABS(iNumCoeffs);                if (m_PicParamSet.entropy_coding_mode)                {                    int ctxIdxBlockCat = BLOCK_LUMA_LEVELS;                    ScanSignificant_CABAC(pDiffBuf,ctxIdxBlockCat,16,                        dec_single_scan[m_PicParamSet.picture_structure != FRAME_PICTURE],                        &m_pCurrentFrame->Block_CABAC[uBlock]);                    bCoded = m_pCurrentFrame->Block_CABAC[uBlock].uNumSigCoeffs;                }                else                {                // record RLE info                    ippiEncodeCoeffsCAVLC_H264_16s (                                                        pDiffBuf,                                                        0,                                                        dec_single_scan[m_PicParamSet.picture_structure != FRAME_PICTURE],                                                        uLastCoeff,                                                        &m_pCurrentFrame->Block_RLE[uBlock].uTrailing_Ones,                                                        &m_pCurrentFrame->Block_RLE[uBlock].uTrailing_One_Signs,                                                        &m_pCurrentFrame->Block_RLE[uBlock].uNumCoeffs,                                                        &m_pCurrentFrame->Block_RLE[uBlock].uTotalZeros,                                                        m_pCurrentFrame->Block_RLE[uBlock].iLevels,                                                        m_pCurrentFrame->Block_RLE[uBlock].uRuns);                    m_pCurrentFrame->pYNumCoeffs[uIndex] = bCoded = m_pCurrentFrame->Block_RLE[uBlock].uNumCoeffs;                }                //bCoded = RLE(                //          pDiffBuf,       // quantized coeffs in scan order                //          16,         // number of coeffs                //          &m_pCurrentFrame->Block_RLE[uBlock] // where to put RLE data                //          );            }            // update flags if block quantized to empty            if (!bCoded)            {                uCBP4x4 &= ~CBP4x4Mask[uBlock];                // update reconstruct frame for the empty block                Copy4x4(                    pPredBuf,               // predictor block                    uPitch,                    pRecPlane + uOffset);   // reconstruct frame            }            else            {                // inverse transform for reconstruct AND...                // add inverse transformed coefficients to original predictor                // to obtain reconstructed block, store in reconstruct frame                // buffer                ippiDequantTransformResidualAndAdd_H264_16s_C1I (                    pPredBuf,                    pDiffBuf,                    NULL,                    pRecPlane + uOffset,                    16,                    uPitch,                    uMBQP,                    ((iNumCoeffs < -1) || (iNumCoeffs > 0)));            }        }   // block not declared empty        // proceed to the next block        uIndex += m_EncBlockIndexInc[uBlock];        uOffset += m_EncBlockOffsetInc[uBlock];        uBlock ++;    }  // for uBlock in luma plane    // Check if this block should be coded with a different mode    if (m_SliceHeader.slice_type  != INTRASLICE)    {        if (uIntraSAD >= m_uMBInterSAD)        {            // INTER is better, recode the MB as INTER            m_pCurrentFrame->pMBData[uMB].uMBType = m_uInterMBType;            m_pCurrentFrame->pMBData[uMB].uCBP4x4 = m_uInterCBP4x4;            m_Intra_MB_Counter --;            // Fixup the Intra 4x4 mode buffer            uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex;            for (uBlock = 0; uBlock < 16; uBlock++) {                m_pCurrentFrame->pAIMode[uIndex] = (T_AIMode) 2;                uIndex += m_EncBlockIndexInc[uBlock];            }            return 0;  // Bail and recode as Inter...        }    }#ifdef _INTRA_MODE_SWITCH_    // Always consider recoding as Intra 16x16, regardless of slice type.    if (uIntraSAD >= m_uMBIntra16x16SAD)    {        // INTER is better, recode the MB as INTER        m_pCurrentFrame->pMBData[uMB].uMBType = (Ipp8u) MBTYPE_INTRA_16x16;        m_pCurrentFrame->pMBData[uMB].uCBP4x4 = 0xffffff;        // Fixup the Intra 4x4 mode buffer        uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex;        for (uBlock = 0; uBlock < 16; uBlock++) {            m_pCurrentFrame->pAIMode[uIndex] = (T_AIMode) 2;            uIndex += m_EncBlockIndexInc[uBlock];        }        // Restore the four 32 bit values (16 pels) that were saved from the prediction buffer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -