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

📄 umc_h264_ermb.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            // update flags if block quantized to empty
            if (curr_slice->m_use_transform_for_intra_decision) {
                if (!bCoded) {
                    uCBPLuma &= ~CBP4x4Mask[uBlock];
                }
                // TODO: ????? What should we copy here ????? SB
                // Why in both cases (CODED/NOT CODED the same is copied????
#ifdef H264_RD_OPT
#else
                Copy4x4(pPredBuf + 256, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
#endif
            } else {
                if (!bCoded){
                    uCBPLuma &= ~CBP4x4Mask[uBlock];

                    // update reconstruct frame for the empty block
                    Copy4x4(pPredBuf, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
                } else if(!transform_bypass) {
                    // inverse transform for reconstruct AND...
                    // add inverse transformed coefficients to original predictor
                    // to obtain reconstructed block, store in reconstruct frame
                    // buffer
                    ippiDequantTransformResidualAndAdd_H264(pPredBuf,
                                                            pTransformResult,
                                                            NULL,
                                                            pReconBuf,
                                                            16,
                                                            pitchPix,
                                                            uMBQP,
                                                            ((iNumCoeffs < -1) || (iNumCoeffs > 0)),
                                                            m_PicParamSet.bit_depth_luma);

                }
            }
        }   // block not declared empty

        // proceed to the next block
        uOffset += m_EncBlockOffsetInc[is_cur_mb_field][uBlock];
    }  // for uBlock in luma plane
    }
#if defined TRACE_INTRA
    if(uMB == TRACE_INTRA) {
        printMatr(m_pReconstructFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][is_cur_mb_field], pitchPixels, 16, 16, 0, "RecPlane");
    }
#endif // TRACE_INTRA

    // update coded block flags
    cur_mb.LocalMacroblockInfo->cbp_luma = uCBPLuma;

    // for each block of the MB initialize the AI mode (for INTER MB)
    // or motion vectors (for INTRA MB) to values which will be
    // correct predictors of that type. MV and AI mode prediction
    // depend upon this instead of checking MB type.

    return 1;
}   // CEncAndRec4x4IntraMB

////////////////////////////////////////////////////////////////////////////////
// CEncAndRec16x16IntraMB
//
// Encode and Reconstruct all blocks in one 16x16 Intra macroblock
//
////////////////////////////////////////////////////////////////////////////////

template <class PixType, class CoeffsType>
Ipp32u H264CoreEncoder<PixType, CoeffsType>::CEncAndRec16x16IntraMB(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
    Ipp32u  uBlock;     // block number, 0 to 23
    Ipp32u  uOffset;        // to upper left corner of block from start of plane
    Ipp32u  uMBQP;          // QP of current MB
    Ipp32u  uMB;
    Ipp32u  uCBPLuma;        // coded flags for all 4x4 blocks
    Ipp32u  uCBPChroma;        // coded flags for all chroma blocks
    Ipp32u  uIntraSAD;      // intra MB SAD
    CoeffsType* pDCBuf;     // chroma & luma dc coeffs pointer
    PixType*  pPredBuf;       // prediction block pointer
    PixType*  pReconBuf;       // prediction block pointer
    Ipp16s* pDiffBuf;       // difference block pointer
    Ipp16s* pTempDiffBuf;       // difference block pointer
    CoeffsType *pTransformResult; // for transform results.
    Ipp16s* pMassDiffBuf;   // difference block pointer
    CoeffsType* pQBuf;          // quantized block pointer
    PixType*  pSrcPlane;      // start of plane to encode
    Ipp32s  pitchPixels;     // buffer pitch in pixels
    Ipp8u   bCoded; // coded block flag
    Ipp32s  iNumCoeffs; // Number of nonzero coeffs after quant (negative if DC is nonzero)
    Ipp32s  iLastCoeff; // Number of nonzero coeffs after quant (negative if DC is nonzero)
    Ipp32u  RLE_Offset;    // Index into BlockRLE array
    H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
    Ipp32s is_cur_mb_field = curr_slice->m_is_cur_mb_field;
    EnumSliceType slice_type = curr_slice->m_slice_type;

    pitchPixels = cur_mb.mbPitchPixels;
    uCBPLuma    = cur_mb.LocalMacroblockInfo->cbp_luma;
    uCBPChroma  = cur_mb.LocalMacroblockInfo->cbp_chroma;
    uMBQP       = getLumaQP(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
    pDiffBuf    = (Ipp16s*) (curr_slice->m_pMBEncodeBuffer + 512);
    pTransformResult = (CoeffsType*)(pDiffBuf + 16);
    pQBuf       = (CoeffsType*) (pTransformResult + 16);
    pDCBuf      = (CoeffsType*) (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;
    uMB = cur_mb.uMB;

    bool transform_bypass = m_SeqParamSet.qpprime_y_zero_transform_bypass_flag && uMBQP == 0;
    //--------------------------------------------------------------------------
    // encode Y plane blocks (0-15)
    //--------------------------------------------------------------------------

    // initialize pointers and offset
    pSrcPlane = m_pCurrentFrame->m_pYPlane;
    uOffset = m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][is_cur_mb_field];
    RLE_Offset = Y_DC_RLE;  // Used in 16x16 Intra mode only
    pPredBuf    = cur_mb.mb16x16.prediction; // 16-byte aligned work buffer
    Ipp32s pitchPix;
#ifdef H264_RD_OPT
    pReconBuf    = cur_mb.mb16x16.reconstruct; // 16-byte aligned work buffer
    pitchPix = 16;
#else
    pReconBuf    = m_pReconstructFrame->m_pYPlane; // 16-byte aligned work buffer
    pitchPix = pitchPixels;
#endif

    // for INTRA 16x16 MBs computation of luma prediction was done as
    // a byproduct of sad calculation prior to this function being
    // called; the predictor blocks are already at pPredBuf.

    // Initialize the AC coeff flag value
    cur_mb.MacroblockCoeffsInfo->lumaAC = 0;

    // compute the 4x4 luma DC transform coeffs
    ippiSumsDiff16x16Blocks4x4(pSrcPlane + uOffset, pitchPixels, pPredBuf, 16, pDCBuf, pMassDiffBuf);

#if defined TRACE_INTRA_16X16
    if(uMB == TRACE_INTRA_16X16) {
        printf("ermb 16x16 intra: uMB = %d, tr_bypass = %d, uCBPLuma = %d\n", uMB, transform_bypass, uCBPLuma);
        printMatr(pSrcPlane + uOffset, pitchPixels, 16, 16, 0, "SrcPlane");
        printMatr(pPredBuf, 16, 16, 16, 0, "PredBuf");
        printMatr(pDCBuf, 16, 1, 16, 0, "DC");
        printMatr(pMassDiffBuf, 4, 64, 4, 0, "MassDiff");
    }
#endif // TRACE_INTRA_16X16

    if(!transform_bypass) {
        // apply second transform on the luma DC transform coeffs
        ippiTransformQuantLumaDC_H264(pDCBuf,pQBuf,uMBQP,&iNumCoeffs,1, enc_single_scan[is_cur_mb_field],&iLastCoeff);
    }else {
       for(Ipp32s i = 0; i < 4; i++) {
            for(Ipp32s j = 0; j < 4; j++) {
                Ipp32s x, y;
                x = j*16;
                y = i*64;
                pDCBuf[i*4 + j] = pMassDiffBuf[x+y];
            }
        }
        ippiCountCoeffs(pDCBuf, &iNumCoeffs, enc_single_scan[is_cur_mb_field], &iLastCoeff, 16);
    }
#if defined TRACE_INTRA_16X16
    if(uMB == TRACE_INTRA_16X16) {
        printMatr(pDCBuf, pitchPixels, 1, 16, 0, "DC modified");
    }
#endif // TRACE_INTRA_16X16

    // insert the quantized luma Ipp64f transform DC coeffs into
    // RLE buffer

    // record RLE info
    if (m_PicParamSet.entropy_coding_mode)
    {
        Ipp32s ctxIdxBlockCat = BLOCK_LUMA_DC_LEVELS;
        ScanSignificant_CABAC(pDCBuf,ctxIdxBlockCat,16,
                              dec_single_scan[is_cur_mb_field],
                              &curr_slice->Block_CABAC[RLE_Offset]);
        bCoded = curr_slice->Block_CABAC[RLE_Offset].uNumSigCoeffs;
    }
    else
    {
        ippiEncodeCoeffsCAVLC_H264(pDCBuf,
                                   0,
                                   dec_single_scan[is_cur_mb_field],
                                   iLastCoeff,
                                   &curr_slice->Block_RLE[RLE_Offset].uTrailing_Ones,
                                   &curr_slice->Block_RLE[RLE_Offset].uTrailing_One_Signs,
                                   &curr_slice->Block_RLE[RLE_Offset].uNumCoeffs,
                                   &curr_slice->Block_RLE[RLE_Offset].uTotalZeros,
                                   curr_slice->Block_RLE[RLE_Offset].iLevels,
                                   curr_slice->Block_RLE[RLE_Offset].uRuns);

        bCoded = curr_slice->Block_RLE[RLE_Offset].uNumCoeffs;
    }

    if(!transform_bypass) {
        ippiTransformDequantLumaDC_H264(pDCBuf, uMBQP);
    }

    // loop over all 4x4 blocks in Y plane for the MB
    for (uBlock = 0; uBlock < 16; uBlock++ ){
        pPredBuf = cur_mb.mb16x16.prediction + xoff[uBlock] + yoff[uBlock]*16;
#ifdef H264_RD_OPT
        pReconBuf = cur_mb.mb16x16.reconstruct + xoff[uBlock] + yoff[uBlock]*16;
#else
        pReconBuf = m_pReconstructFrame->m_pYPlane+uOffset;
#endif
        cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = 0;        // This will be updated if the block is coded
        if (m_PicParamSet.entropy_coding_mode) {
            curr_slice->Block_CABAC[uBlock].uNumSigCoeffs = 0;
        } else {
            curr_slice->Block_RLE[uBlock].uNumCoeffs = 0;
            curr_slice->Block_RLE[uBlock].uTrailing_Ones = 0;
            curr_slice->Block_RLE[uBlock].uTrailing_One_Signs = 0;
            curr_slice->Block_RLE[uBlock].uTotalZeros = 15;
        }

        // check if block is coded
        bCoded = ((uCBPLuma & CBP4x4Mask[uBlock])?(1):(0));

        if (!bCoded){
            // update reconstruct frame for the empty block
            Copy4x4(pPredBuf, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
        }else{   // block not declared empty, encode

            pTempDiffBuf = pMassDiffBuf+ xoff[uBlock]*4 + yoff[uBlock]*16;
            if(!transform_bypass) {
                ippiTransformQuantResidual_H264(pTempDiffBuf, pTransformResult, uMBQP,&iNumCoeffs,(slice_type == INTRASLICE),
                    enc_single_scan[is_cur_mb_field],&iLastCoeff);
            }else{
                for(Ipp32s i = 0; i < 16; i++){
                    pTransformResult[i] = pTempDiffBuf[i];
                }
                ippiCountCoeffs(pTransformResult, &iNumCoeffs, enc_single_scan[is_cur_mb_field], &iLastCoeff, 16);
            }

            // restore luma DC transform coeff if 16x16 intra mode
            // Also, saves the value of iNonEmpty for later use
            // TBD: Maybe this should be part of QDQ or RLE?

            cur_mb.MacroblockCoeffsInfo->lumaAC |= ((iNumCoeffs < -1) || (iNumCoeffs > 0));

            //pDQBuf[0] = pDCBuf[block_subblock_mapping[uBlock]];

            // 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.
                cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = (T_NumCoeffs)((iNumCoeffs < 0) ? -(iNumCoeffs+1) : iNumCoeffs);
                if (m_PicParamSet.entropy_coding_mode){
                    Ipp32s ctxIdxBlockCat = BLOCK_LUMA_AC_LEVELS;
                    ScanSignificant_CABAC(pTransformResult,ctxIdxBlockCat,15,
                        dec_single_scan[is_cur_mb_field],
                        &curr_slice->Block_CABAC[uBlock]);
                    bCoded = curr_slice->Block_CABAC[uBlock].uNumSigCoeffs;
                } else {
                    ippiEncodeCoeffsCAVLC_H264(pTransformResult,//pDiffBuf,
                                               1,
                                               dec_single_scan[is_cur_mb_field],
                         

⌨️ 快捷键说明

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