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

📄 umc_h264_gen_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    m_SliceHeader.MbaffFrameFlag = 0;
    m_SliceHeader.bottom_field_flag = 0;
    m_SliceHeader.direct_spatial_mv_pred_flag = 1;
    m_SliceHeader.long_term_reference_flag = 0;
    m_SliceHeader.sp_for_switch_flag = 0;
    m_SliceHeader.slice_qs_delta = 0;
    m_SliceHeader.frame_num = 0;
    m_SliceHeader.idr_pic_id = 0;
    m_SliceHeader.pic_order_cnt_lsb = 0;
    m_SliceHeader.delta_pic_order_cnt[0] = 0;
    m_SliceHeader.delta_pic_order_cnt[1] = 0;
    m_SliceHeader.redundant_pic_cnt = 0;
    m_SliceHeader.slice_group_change_cycle = 0;
    m_SliceHeader.delta_pic_order_cnt_bottom = 0;

    eFrameType[0] = PREDPIC;
    m_DirectTypeStat[0]=m_DirectTypeStat[1]=0;

    if (UMC_OK == status){ // Create noise reduction filter object
        m_noisepf = new CNoiseReductionFilter<PixType>(true,true,false);
        if (NULL == m_noisepf) status = UMC::UMC_ERR_ALLOC;
    }

    return;
}

//========================================================================
//========================================================================

template <class PixType, class CoeffsType>
Status H264CoreEncoder<PixType,CoeffsType>::Start_Sequence()
{
    Status Status = UMC_OK;

    // Set up for the 8 bit/default frame rate
    m_uTRWrapAround = TR_WRAP;
    m_uFrames_Num = 0;
    m_uFrameCounter = 0;

    SetSequenceParameters();

    if((m_EmptyThreshold = ippsMalloc_32u(52)) == NULL) {
        return(UMC::UMC_ERR_ALLOC);
    }
    if((m_DirectBSkipMEThres = ippsMalloc_32u(52)) == NULL) {
        return(UMC::UMC_ERR_ALLOC);
    }
    if((m_PSkipMEThres = ippsMalloc_32u(52)) == NULL) {
        return(UMC::UMC_ERR_ALLOC);
    }
    if((m_BestOf5EarlyExitThres = ippsMalloc_32s(52)) == NULL) {
        return(UMC::UMC_ERR_ALLOC);
    }
    ippsCopy_32s((const Ipp32s*)UMC_H264_ENCODER::EmptyThreshold, (Ipp32s*)m_EmptyThreshold, 52);
    ippsCopy_32s((const Ipp32s*)UMC_H264_ENCODER::DirectBSkipMEThres, (Ipp32s*)m_DirectBSkipMEThres, 52);
    ippsCopy_32s((const Ipp32s*)UMC_H264_ENCODER::PSkipMEThres, (Ipp32s*)m_PSkipMEThres, 52);
    ippsCopy_32s(UMC_H264_ENCODER::BestOf5EarlyExitThres, m_BestOf5EarlyExitThres, 52);

    //TODO Add QP check
    if(m_SeqParamSet.qpprime_y_zero_transform_bypass_flag) {
        // Lossless mode
        m_EmptyThreshold[0] = 0;
        m_DirectBSkipMEThres[0] = 0;
        m_PSkipMEThres[0] = 0;
        m_BestOf5EarlyExitThres[0] = 0;
    }

    m_PaddedSize.width  = (m_info.info.clip_info.width  + 15) & ~15;
    m_PaddedSize.height = (m_info.info.clip_info.height + (16<<(1 - m_SeqParamSet.frame_mbs_only_flag)) - 1) & ~((16<<(1 - m_SeqParamSet.frame_mbs_only_flag)) - 1);
    m_WidthInMBs = m_PaddedSize.width >> 4;
    m_HeightInMBs  = m_PaddedSize.height >> 4;
    m_Pitch = CalcPitchFromWidth(m_PaddedSize.width, sizeof(PixType)) / sizeof(PixType);

    // Make sure the input color conversion is supported before allocating
    // buffers.
    // Read the profile and build the input frame queue.
    // Also allocate the Core_Encoder
    if (!m_bBuffersAllocated)
    {
        Status = Allocate_Buffers();
        if (Status != UMC_OK)
        {
            goto done;
        }
        m_bBuffersAllocated = true;
    }

    /*
     * This flag is used by the encoder to signal that the
     * next frame should be encoded as an INTRA regardless of what
     * the client asks for. This may be either because an error was
     * detected in compressing the current delta, or to ensure that
     * the first frame is encoded INTRA.
     */
    m_bMakeNextFrameKey = true; // Ensure that we always start with a key frame.
    m_bMakeNextFrameIDR = false;

    if (H264_KFCM_INTERVAL == m_info.key_frame_controls.method)
    {
        m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1;
        m_uIDRFrameInterval = m_info.key_frame_controls.idr_interval + 1;
    }else{
        m_uIDRFrameInterval = m_uIntraFrameInterval = 0;
    }

    if (!m_noisepf->Start_Sequence(m_info.info.clip_info.width,m_info.info.clip_info.height)){
        Status = UMC_ERR_FAILED;
    }

done:
    memset(&m_AdaptiveMarkingInfo,0,sizeof(m_AdaptiveMarkingInfo));
    memset(&m_ReorderInfoL0,0,sizeof(m_ReorderInfoL0));
    memset(&m_ReorderInfoL1,0,sizeof(m_ReorderInfoL1));
    return Status;
}   // Start_Sequence

//
// Encode - drives the compression of a "Temporal Reference"
//
template <class PixType, class CoeffsType> Status H264CoreEncoder<PixType,CoeffsType>::Encode(
    VideoData*  src,
    MediaData*  dst,
    const H264_Encoder_Compression_Flags     flags,
    H264_Encoder_Compression_Notes          &notes)
{
    Status          ps = UMC_OK;
    m_pCurrentFrame = 0;
    m_field_index = 0;
    Ipp32s isRef=0,frame_index;

    if (!(flags & H264_ECF_LAST_FRAME)){
        Ipp32u nShortTerm, nLongTerm;
        EnumPicCodType  ePictureType;
        FrameType ft = src->GetFrameType();
        switch(ft){
            case I_PICTURE:
                ePictureType = INTRAPIC;
                break;
            case P_PICTURE:
                //Check for available frames in dpb
                m_dpb.countActiveRefs( nShortTerm, nLongTerm );
                if( (nShortTerm + nLongTerm) == 0 ) return UMC_ERR_NOT_ENOUGH_DATA; //May be it should be  UMC_ERR_INVALID_PARAMS
                ePictureType = PREDPIC;
                break;
            case B_PICTURE:
                //Check for available frames in dpb
                m_dpb.countActiveRefs( nShortTerm, nLongTerm );
                if( (nShortTerm + nLongTerm) == 0 ) return UMC_ERR_NOT_ENOUGH_DATA; //May be it should be  UMC_ERR_INVALID_PARAMS
                ePictureType = BPREDPIC;
                break;
            case NONE_PICTURE:
            default:
                frame_index = m_iProfileIndex;
                ePictureType = DetermineFrameType(m_iProfileIndex);
                if( ePictureType == BPREDPIC ){
                    switch( m_info.treat_B_as_reference ){
                        case 0:
                            isRef=0; //No B references
                            break;
                        case 1:
                            if( m_iProfileIndex-1 == ((m_info.B_frame_rate+1)>>1) )  //Only middle B is reference, better to use round to low in case of even number of B frames
                                isRef = 1;
                            else isRef = 0;
                            break;
                        case 2: //All B frames are refereces
                            isRef = 1;
                            break;
                    }
                }
                break;
        }

        m_pLastFrame = m_pCurrentFrame = m_cpb.InsertFrame(src, ePictureType, isRef,
                                                  m_info.num_slices,
                                                  m_PaddedSize
#if defined ALPHA_BLENDING_H264
                                                  , m_SeqParamSet.aux_format_idc
#endif
                                                  );

        if(m_pCurrentFrame){
            m_pCurrentFrame->m_bIsIDRPic = false;

            if (m_bMakeNextFrameIDR && ePictureType == INTRAPIC){
                m_pCurrentFrame->m_bIsIDRPic = true;
                m_PicOrderCnt_Accu += m_PicOrderCnt;
                m_PicOrderCnt = 0;
                m_bMakeNextFrameIDR = false;
            }

            switch(m_info.coding_type)
            {
            case 0:
                m_pCurrentFrame->m_PictureStructureForDec = m_pCurrentFrame->m_PictureStructureForRef = FRM_STRUCTURE;
                m_pCurrentFrame->setPicOrderCnt(m_PicOrderCnt*2, 0);
                m_pCurrentFrame->setPicOrderCnt(m_PicOrderCnt*2 + 1, 1);
                m_pCurrentFrame->m_PicOrderCounterAccumulated = 2*(m_PicOrderCnt + m_PicOrderCnt_Accu);
                m_pCurrentFrame->m_bottom_field_flag[0] = 0;
                m_pCurrentFrame->m_bottom_field_flag[1] = 0;
                break;
            case 1:
                m_pCurrentFrame->m_PictureStructureForDec = m_pCurrentFrame->m_PictureStructureForRef = FLD_STRUCTURE;
                m_pCurrentFrame->setPicOrderCnt(m_PicOrderCnt*2, 0);
                m_pCurrentFrame->setPicOrderCnt(m_PicOrderCnt*2 + 1, 1);
                m_pCurrentFrame->m_PicOrderCounterAccumulated = 2*(m_PicOrderCnt + m_PicOrderCnt_Accu);
                m_pCurrentFrame->m_bottom_field_flag[0] = 0;
                m_pCurrentFrame->m_bottom_field_flag[1] = 1;
                break;
            case 2:
                m_pCurrentFrame->m_PictureStructureForDec = m_pCurrentFrame->m_PictureStructureForRef = AFRM_STRUCTURE;
                m_pCurrentFrame->setPicOrderCnt(m_PicOrderCnt*2, 0);
                m_pCurrentFrame->setPicOrderCnt(m_PicOrderCnt*2 + 1, 1);
                m_pCurrentFrame->m_PicOrderCounterAccumulated = 2*(m_PicOrderCnt + m_PicOrderCnt_Accu);
                m_pCurrentFrame->m_bottom_field_flag[0] = 0;
                m_pCurrentFrame->m_bottom_field_flag[1] = 0;
                break;
            default:return UMC_ERR_UNSUPPORTED;
            }
            m_pCurrentFrame->InitRefPicListResetCount(0);
            m_pCurrentFrame->InitRefPicListResetCount(1);

            m_PicOrderCnt++;

            if (m_pCurrentFrame->m_bIsIDRPic)
                m_cpb.IncreaseRefPicListResetCount(m_pCurrentFrame);

//            fprintf(stderr, "idx=%d  frnm=%d  POC=%d  type=%d\n", frame_index,  m_uFrames_Num, m_pCurrentFrame->PicOrderCnt(0,3), m_pCurrentFrame->m_PicCodType);
            if( m_Analyse & ANALYSE_ME_ADAPTIVE_B ){
/*                fprintf(stderr, "POCs*** %d ****: ", m_pCurrentFrame->PicOrderCnt(0,3));
                for( Ipp32s i = 0; i<=profile_frequency; i++ )
                    if( eFrameSeq[i] )
                       fprintf(stderr," %d", eFrameSeq[i]->PicOrderCnt(0,3));
                    else
                       fprintf(stderr," %s", "NULL");
                fprintf(stderr,"\n");

                if( frame_index == 0 && (eFrameSeq[0] == NULL || eFrameSeq[1] == NULL || eFrameSeq[2] == NULL)){
                    fprintf(stderr,"ALERT3!!!");
                }
*/
                if( frame_index == 0 && eFrameSeq[0] != NULL ){
                    Ipp32s i, lref=0;
                    eFrameSeq[profile_frequency]=m_pCurrentFrame;

                    //Check consistency
/*                    Ipp32s cnull = 0;
                    if( eFrameSeq[0] == NULL ){
                        cnull = 1;
                    }
                for(Ipp32s i = 1; i<=profile_frequency; i++ ){
                            if( eFrameSeq[i] == NULL ) cnull=1;
                            if( cnull && eFrameSeq[i] != NULL ) fprintf(stderr, "ALERT1!!!\n");
                            if( eFrameSeq[i] != NULL && eFrameSeq[i-1] != NULL){
                                if( eFrameSeq[i]->PicOrderCnt(0,3) - eFrameSeq[i-1]->PicOrderCnt(0,3) != 2 )
                                    fprintf(stderr, "ALERT2!!!\n");
                            }
                        }
*/
                    //Try PP coding first
                    if( eFrameSeq[1] != NULL && eFrameSeq[2] != NULL ){
                        Ipp32s costPP1, costPP2, costBP1, costBP2, checkB=0;
                        EnumPicCodType pc = PREDPIC;
                        m_pCurrentFrame = eFrameSeq[1];
                        costPP1 = ME_EstimateFrame( pc, REFERENCE_PIC, eFrameSeq[0], NULL);

                        //If we have a lot of Intra, don't try B
//                        fprintf(stderr," Intra check: costPP1=%d intra %d  all %d\n",costPP1, eFrameSeq[1]->numIntraMBs, eFrameSeq[1]->numMBs);
                        if( eFrameSeq[1]->numIntraMBs < ((eFrameSeq[1]->numMBs)>>1) ){
                            m_pCurrentFrame = eFrameSeq[2];
                            costPP2 = ME_EstimateFrame( pc, REFERENCE_PIC, eFrameSeq[1], NULL);

                            m_pCurrentFrame = eFrameSeq[2];
                            costBP1 = ME_EstimateFrame( pc, REFERENCE_PIC, eFrameSeq[0], NULL);
                            pc = BPREDPIC;
                            m_pCurrentFrame = eFrameSeq[1];
                            costBP2 = ME_EstimateFrame( pc, DISPOSABLE_PIC, eFrameSeq[0], eFrameSeq[2]);

                             if( costPP1+costPP2 >= costBP1+costBP2 ) checkB = 1;
//                             fprintf(stderr," CostCheck: PP1=%d  PP2=%d  BP1=%d  BP2=%d  ALL: PP=%d  BP=%d\n", costPP1, costPP2, costBP1, costBP2, costPP1+costPP2, costBP1+costBP2 );
                         }

                        if( checkB ){
                            EnumPicCodType pc = PREDPIC;
                            Ipp32s prevCostPP = costBP1;
                            Ipp32s i,m,k;

                            for( i=3; i<=profile_frequency && eFrameSeq[i];i++){
                                Ipp32s costP1, costP2;
                                m_pCurrentFrame = eFrameSeq[i];
                                costP1 = ME_EstimateFrame( pc, REFERENCE_PIC, eFrameSeq[i-1], NULL);
                                //m_pCurrentFrame = eFrameSeq[i];
                                costP2 = ME_EstimateFrame( pc, REFERENCE_PIC, eFrameSeq[0], NULL);

⌨️ 快捷键说明

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