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

📄 umc_h264_core_enc.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////               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 <stddef.h>#include "ippdefs.h"#include "umc_h264_video_encoder.h"#include "umc_h264_tables.h"// Table to obtain edge info for a 4x4 block of a MB. The table entry when// OR'd with the edge info for the MB, results in edge info for the block.////  H264 4x4 Block ordering in a 16x16 Macroblock and edge assignments////  ULC = Upper Left Corner, U = Upper Edge//  L = Left Edge, R = Right Edge////               luma (Y)                chroma (U)          chroma (V)////        +-U--+-U--+-U--+-U--+         +-U--+-U--+         +-U--+-U--+//        |    |    |    |    |         |    |    |         |    |    |// ULC--> L 0  | 1  | 4  | 5  R  ULC--> L 16 | 17 R  ULC--> L 20 | 21 R//        |    |    |    |    |         |    |    |         |    |    |//        +----+----+----+----+         +----+----+         +----+----+//        |    |    |    |    |         |    |    |         |    |    |//        L 2  | 3  | 6  | 7  R         L 18 | 19 R         L 22 | 23 R//        |    |    |    |    |         |    |    |         |    |    |//        +----+----+----+----+         +----+----+         +----+----+//        |    |    |    |    |//        L 8  | 9  | 12 | 13 R//        |    |    |    |    |//        +----+----+----+----+//        |    |    |    |    |//        L 10 | 11 | 14 | 15 R//        |    |    |    |    |//        +----+----+----+----+////  This table provides easy look-up by block number to determine//  which edges is does NOT border on.using namespace UMC_H264_ENCODER;namespace UMC{const Ipp8u EdgePelCountTable [52] ={    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,    0,0,0,0,1,1,1,1,    1,1,2,2,2,2,2,2,    3,3,3,3,3,3,4,4};const Ipp8u uEncNotEdge[24] = {    // luma:    MBEdgeTypeIsNotRightEdge,   // 0    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 1    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 2    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 3    MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 4    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 5    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 6    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotLeftEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 7    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 8    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 9    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 10    MBEdgeTypeIsNotTopEdge | MBEdgeTypeIsNotLeftEdge |    MBEdgeTypeIsNotRightEdge |MBEdgeTypeIsNotUpperLeftCorner, // 11    MBEdgeTypeIsNotRightEdge | MBEdgeTypeIsNotTopEdge |    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 12    MBEdgeTypeIsNotLeftEdge |    MBEdgeTypeIsNotTopEdge| MBEdgeTypeIsNotUpperLeftCorner, // 13    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotRightEdge |    MBEdgeTypeIsNotTopEdge| MBEdgeTypeIsNotUpperLeftCorner, // 14    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotTopEdge |    MBEdgeTypeIsNotUpperLeftCorner,     // 15    // chroma:    MBEdgeTypeIsNotRightEdge, // 16    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 17    MBEdgeTypeIsNotRightEdge | MBEdgeTypeIsNotTopEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 18    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotTopEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 19    MBEdgeTypeIsNotRightEdge, // 20    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotUpperLeftCorner, // 21    MBEdgeTypeIsNotRightEdge | MBEdgeTypeIsNotTopEdge |    MBEdgeTypeIsNotUpperLeftCorner, // 22    MBEdgeTypeIsNotLeftEdge | MBEdgeTypeIsNotTopEdge |    MBEdgeTypeIsNotUpperLeftCorner  // 23};//////////////////////////////////// Compress one sliceStatusH264VideoEncoder::Compress_Slice(    const Ipp16u slice_num    // Compression settings){    Ipp32u uNumMBs;    Ipp32u uMB;    Ipp32u uFirstMB;    Ipp32u uAIMBSAD;            // MB prediction SAD for INTRA 4x4 mode    Ipp32u uAIMBSAD_16x16;      // MB prediction SAD for INTRA 16x16 mode    Ipp32u uBestIntraSAD;    Ipp8u uMBQP;    Ipp32u uMinIntraSAD;    MB_Type uBestIntraMBType;    Ipp8u   uUsePCM = 0;    Ipp8u *pStartBits;    Ipp32u uStartBitOffset;    Ipp8u *pEndBits;    Ipp32u uEndBitOffset;    Ipp32u uCoeffBits;    Ipp8u *pCoeffStartBits;    Ipp32u uCoeffStartBitOffset;    Ipp8u *pCoeffEndBits;    Ipp32u uCoeffEndBitOffset;    Ipp32u uRecompressMB;    Ipp8u uLastQP;    Ipp32u uSaved_Skip_Run;    Ipp8u MBHasEdges;    Ipp8u bSeenFirstMB = false;    Status status = UMC_OK;    // If this assert fails, then something has changed that will affect the    // size of the m_pSliceDataBase array, among other things    // TODO VSI: Update these and the loop below to cover the MBs in one slice.    uNumMBs = uHeightInMBs * uWidthInMBs;    uFirstMB = 0;    int y_line_shift = m_pCurrentFrame->y_line_shift;    int pitchY = m_pCurrentFrame->uPitch;//  m_m_info = m_info;    // loop over all MBs in the picture    for (uMB = uFirstMB; uMB < uFirstMB + uNumMBs; uMB++)    {        // Is this MB in the current slice?  If not, move on...        if (m_pCurrentFrame->pMBData[uMB].uSlice != slice_num) {            continue;        } else if (!bSeenFirstMB) {            // Reset xpos and ypos in framedata struct            // This is necessary because the same slice may be recoded multiple times.            m_pCurrentFrame->uMBypos = (uMB / uWidthInMBs);  // Don't multiply by 16 until after next calculation            m_pCurrentFrame->uMBxpos = (uMB - m_pCurrentFrame->uMBypos * uWidthInMBs) * 16;            m_pCurrentFrame->uMBypos *= 16;            // reset intra MB counter per slice            m_Intra_MB_Counter = 0;            m_MB_Counter = 0;            m_SliceHeader.slice_type = m_info.current_slice_type;            // Fill in the first mb in slice field in the slice header.            m_SliceHeader.first_mb_in_slice = uMB;            // Fill in the current deblocking filter parameters.            m_SliceHeader.slice_alpha_c0_offset =                    m_pCurrentFrame->pSliceDataBase[slice_num].slice_alpha_c0_offset =                    m_info.slice_parms.slice_alpha_c0_offset;            m_SliceHeader.slice_beta_offset =                    m_pCurrentFrame->pSliceDataBase[slice_num].slice_beta_offset =                    m_info.slice_parms.slice_beta_offset;            m_SliceHeader.disable_deblocking_filter_idc =                    m_pCurrentFrame->pSliceDataBase[slice_num].disable_deblocking_filter_idc =                    m_info.slice_parms.disable_deblocking_filter_idc;            m_SliceHeader.cabac_init_idc = m_info.cabac_init_idc;            // Write a slice header            m_pbitstream->PutSliceHeader(m_SliceHeader,                                         m_PicParamSet,                                         m_SeqParamSet,                                         m_PicClass);            bSeenFirstMB = true;            // Fill in the correct value for m_uLastXmittedQP, used to correctly code            // the per MB QP Delta            m_uLastXmittedQP = m_PicParamSet.pic_init_qp + m_SliceHeader.slice_qp_delta;            if (m_info.entropy_coding_mode)            {                //m_pbitstream->InitializeEncodingEngine_CABAC();                if (m_SliceHeader.slice_type==INTRASLICE)                    m_pbitstream->InitializeContextVariablesIntra_CABAC(m_PicParamSet.pic_init_qp+m_SliceHeader.slice_qp_delta);                else                    m_pbitstream->InitializeContextVariablesInter_CABAC(m_PicParamSet.pic_init_qp+m_SliceHeader.slice_qp_delta,m_info.cabac_init_idc);            }            // Initialize the MB skip run counter            m_uSkipRun = 0;        }        m_MB_Counter++;        m_pbitstream->GetState(&pStartBits, &uStartBitOffset);        uLastQP = m_uLastXmittedQP;        uSaved_Skip_Run = m_uSkipRun;   // To restore it if we recompress        uUsePCM = 0;    // Don't use the PCM mode initially.        do {    // this is to recompress MBs that are too big.            uMBQP = m_pCurrentFrame->pMBData[uMB].uMBQP;            // init all blocks in the MB to empty            m_pCurrentFrame->pMBData[uMB].uCBP4x4 = 0;            m_pCurrentFrame->pMBData[uMB].uChromaType = 0;            // Use edge detection to determine if the MB is a flat region            ippiEdgesDetect16x16_8u_C1R(m_pCurrentFrame->m_pYPlane + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + y_line_shift,                pitchY,uMBQP/2,EdgePelCountTable[uMBQP],&MBHasEdges);                //MBEdgeDetect(m_pCurrentFrame->m_pYPlane                //      + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset,                //      m_pCurrentFrame->uPitch, uMBQP);            if (m_SliceHeader.slice_type != INTRASLICE)            {                // find the best INTER mode and vectors for all blocks in MB                // results to MBDataCurrent and MVCurrent                CMEOneMB(uMB, &m_uMBInterSAD);                // MB type classification                // Only need to change anything if INTRA is chosen, as the ME                // function filled in MB info for best INTER mode and cbp's.                // save INTER results for possible later switch back to INTER                m_uInterCBP4x4 = m_pCurrentFrame->pMBData[uMB].uCBP4x4;                m_uInterMBType = m_pCurrentFrame->pMBData[uMB].uMBType;                uMinIntraSAD = rd_quant_intra_min[uMBQP];                // For non-Intra pictures, if the macroblock has edges and                // m_uMBInterSAD is above a minimum threshold, we will check                // both 4x4 and 16x16 intra SADs. Otherwise, we just check the                // 16x16 intra SAD.                if (MBHasEdges && (m_uMBInterSAD >= uMinIntraSAD))                {                    // Estimate 4x4 intra mode SAD for the MB using original pels                    // as predictors. Also selects a mode for each block as a                    // byproduct, storing in AIMode for the MB, but it is not used                    // as the mode selction will be repeated later using (correct)                    // reconstructed pels as predictors if 4x4 intra mode is chosen.                    AdvancedIntraModeSelectOneMacroblock(uMB, &uAIMBSAD);                    // Compute 16x16 intra mode SAD for the MB, producing luma                    // predictor blocks (at pMBEncodeBuffer) and selected mode                    // (in AIMode, all blocks) to be used in the encode loop if                    // 16x16 intra mode is chosen.                    Intra16x16SelectAndPredict(uMB, &uAIMBSAD_16x16,                                        m_pCurrentFrame->pMBEncodeBuffer);                    // choose better intra (4x4 or 16x16)                    if (uAIMBSAD_16x16 < uAIMBSAD )                    {                        uBestIntraSAD = uAIMBSAD_16x16;                        uBestIntraMBType = MBTYPE_INTRA_16x16;                    }                    else                    {                        uBestIntraSAD = uAIMBSAD;                        uBestIntraMBType = MBTYPE_INTRA;                    }                }                else // either macroblock has no edges or interSAD below threshold                {                    // Compute 16x16 intra mode SAD for the MB, producing luma                    // predictor blocks (at pMBEncodeBuffer) and selected mode                    // (in AIMode, all blocks) to be used in the encode loop if                    // 16x16 intra mode is chosen.                    Intra16x16SelectAndPredict(uMB, &uAIMBSAD_16x16,                                        m_pCurrentFrame->pMBEncodeBuffer);                    uBestIntraSAD = uAIMBSAD_16x16;                    uBestIntraMBType = MBTYPE_INTRA_16x16;                }                if (uBestIntraSAD < m_uMBInterSAD) {                    m_pCurrentFrame->pMBData[uMB].uMBType = uBestIntraMBType;                    m_pCurrentFrame->pMBData[uMB].uCBP4x4 = 0xffffff;                    m_Intra_MB_Counter++;                }            }   // not intra slice            else            {                // intra slice, type is INTRA, no empty blocks yet                // For Intra pictures, if the macroblock has edges we check                // both 4x4 and 16x16 intra SADs. Otherwise, we just check the                // 16x16 intra SAD.                if (MBHasEdges)                {                    // Estimate 4x4 intra mode SAD for the MB using original pels                    // as predictors. Also selects a mode for each block as a                    // byproduct, storing in AIMode for the MB, but it is not used                    // as the mode selction will be repeated later using (correct)                    // reconstructed pels as predictors if 4x4 intra mode is chosen.                    AdvancedIntraModeSelectOneMacroblock(uMB, &uAIMBSAD);                    // Compute 16x16 intra mode SAD for the MB, producing luma                    // predictor blocks (at pMBEncodeBuffer) and selected mode                    // (in AIMode, all blocks) to be used in the encode loop if                    // 16x16 intra mode is chosen.                    Intra16x16SelectAndPredict(uMB, &uAIMBSAD_16x16,                                    m_pCurrentFrame->pMBEncodeBuffer);                    // choose better intra (4x4 or 16x16)                    if (uAIMBSAD_16x16 < uAIMBSAD)                    {                        uBestIntraMBType = MBTYPE_INTRA_16x16;                    }                    else                    {                        uBestIntraMBType = MBTYPE_INTRA;                    }                }                else                {                    // Compute 16x16 intra mode SAD for the MB, producing luma                    // predictor blocks (at pMBEncodeBuffer) and selected mode                    // (in AIMode, all blocks) to be used in the encode loop if                    // 16x16 intra mode is chosen.                    Intra16x16SelectAndPredict(uMB, &uAIMBSAD_16x16,                                    m_pCurrentFrame->pMBEncodeBuffer);                    uBestIntraMBType = MBTYPE_INTRA_16x16;                }                m_pCurrentFrame->pMBData[uMB].uMBType = uBestIntraMBType;                m_pCurrentFrame->pMBData[uMB].uCBP4x4 = 0xffffff;                m_uMBInterSAD = 0xffffffff;     // very large SAD                m_Intra_MB_Counter++;            }#ifdef _INTRA_MODE_SWITCH_                m_uMBIntra16x16SAD = uAIMBSAD_16x16;    // Save for mode possible switch later#endif            // Code the macroblock, all planes            // coefficients -> pRLEBuffer            if (m_rate_control)            {                m_pCurrentFrame->pMBData[uMB].uMBQP = uMBQP =                    (Ipp8u)m_rate_control->MacroblockRateControl(uMB,                        m_pCurrentFrame->pMBData[uMB].uMBType,m_pbitstream->GetBitsEncoded(),                        m_uMBInterSAD);            }            m_pCurrentFrame->pMBData[uMB].cbp_bits = 0;            CEncAndRecMB(uMB);//          if (m_PicParamSet.entropy_coding_mode)//              PutCABAC_MBHeader(uMB);//          else                PutVLC_MBHeader(uMB);            Ipp32u uHdrBits;            m_pbitstream->GetState(&pEndBits, &uEndBitOffset);            uHdrBits = (Ipp32u) (pEndBits - pStartBits)*8;            if (uEndBitOffset >= uStartBitOffset)                uHdrBits += uEndBitOffset - uStartBitOffset;            else                uHdrBits -= uStartBitOffset - uEndBitOffset;            pCoeffStartBits = pEndBits;            uCoeffStartBitOffset = uEndBitOffset;            Ipp32u uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex;            // if 16x16 intra MB, code the double transform DC coeffs            if (m_pCurrentFrame->pMBData[uMB].uMBType == MBTYPE_INTRA_16x16)            {            //if (m_info.entropy_coding_mode)            //  status = PutCABAC_MBCoefficients_DC(uMB, Y_DC_RLE);            //else                status = PutVLC_MBCoefficients_DC(uMB, Y_DC_RLE);

⌨️ 快捷键说明

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