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

📄 umc_h264_core_enc.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // 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 + -