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

📄 umc_h264_gen_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//                                fprintf(stderr," B: costP1=%d costP2=%d prevCost=%d | Intra %d %d\n", costP1, costP2, prevCostPP, eFrameSeq[i-1]->numIntraMBs, eFrameSeq[i-1]->numMBs);
                                if( costP1 > prevCostPP*2 || eFrameSeq[i-1]->numIntraMBs > ((180*eFrameSeq[i-1]->numMBs)>>9)){
                                    eFrameSeq[i-1]->m_PicCodType = PREDPIC; //Set previous to P frame and break GOP
                                    if( m_Analyse & ANALYSE_SCENECUT && eFrameSeq[i-1]->numIntraMBs > ((505*eFrameSeq[i-1]->numMBs)>>9) ){
                                        eFrameSeq[i-1]->m_PicCodType = INTRAPIC;
                                        //Convert to P
                                        for( k = 1 ;k<i-1; k++ ){
                                            eFrameSeq[k]->m_PicCodType = PREDPIC;
                                        }
                                        m_bMakeNextFrameIDR = true;
                                        m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1 + i - 1;
                                    }
                                    //Change last to B frame
                                    eFrameSeq[profile_frequency]->m_PicCodType = BPREDPIC;
                                    Ipp32s center = i==3 ? 0 : (i)>>1;
                                    for( k=1; k<i-1; k++ ){
                                        eFrameSeq[k]->m_RefPic = false;
                                        if( k == center && m_info.treat_B_as_reference)  eFrameSeq[k]->m_RefPic = true;
                                    }
                                    for( k = i-1, m=0; k<=profile_frequency; k++,m++ ){
                                        eFrameSeq[m] = eFrameSeq[k];
                                    }
                                    for( ;m<=profile_frequency; m++ ) eFrameSeq[m] = NULL;
                                    m_iProfileIndex = (i == profile_frequency) ? 2:i;
//                                    fprintf(stderr," B break cent: %d i: %d idx: %d\n", center, i, m_iProfileIndex);
                                    break;
                                }
                                prevCostPP = costP2;
                            }
//                            fprintf(stderr, " Bc: i=%d idx=%d\n",i,m_iProfileIndex);
                            if( i == profile_frequency+1 ){
                                eFrameSeq[0] = eFrameSeq[profile_frequency];
                                 if( m_Analyse & ANALYSE_SCENECUT && eFrameSeq[0]->numIntraMBs > ((505*eFrameSeq[0]->numMBs)>>9) ){
                                    eFrameSeq[0]->m_PicCodType = INTRAPIC;
                                    //Convert to P
                                    for( i = 1 ;i<=profile_frequency; i++ ){
                                        eFrameSeq[i]->m_PicCodType = PREDPIC;
                                    }
                                    m_bMakeNextFrameIDR = true;
                                    m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1 + (profile_frequency + 1) - 1;
                                }
                                Ipp32s center = (profile_frequency+1)>>1;
                                for( i = 1 ;i<=profile_frequency; i++ ){
                                    eFrameSeq[i]->m_RefPic = false;
                                    if( i == center && m_info.treat_B_as_reference ) eFrameSeq[center]->m_RefPic = true;
                                    eFrameSeq[i] = NULL;
                                }
                            }
                        }else{
//                            fprintf(stderr,"no b check\n");
                            //If P coded picture is better just set it and give encoder possibility to encode it
                            eFrameSeq[1]->m_PicCodType = PREDPIC;
                            //Change last to B frame
                            eFrameSeq[profile_frequency]->m_PicCodType = BPREDPIC;
                            //Move B frames array
                            for( i = 0; i<profile_frequency; i++ ){
                                 eFrameSeq[i] = eFrameSeq[i+1];
                            }
                            //Set index to beginning of type array
                            m_iProfileIndex = 0; //To be next P frame
                            eFrameSeq[profile_frequency]=NULL;
                            if( m_Analyse & ANALYSE_SCENECUT && eFrameSeq[0]->numIntraMBs > ((505*eFrameSeq[0]->numMBs)>>9) ){
                                 eFrameSeq[0]->m_PicCodType = INTRAPIC;
                                 m_bMakeNextFrameIDR = true;
                                 m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1 + 1 - 1;
                            }
                        }

//                        fprintf(stderr, " POC P Index %d: %d\n", m_iProfileIndex, eFrameSeq[0]->PicOrderCnt(0,3));
                        //Check scenecut
                    }
                }else{
                    eFrameSeq[frame_index]=m_pCurrentFrame;
/*                    m_PicClass = REFERENCE_PIC;
                    m_pReconstructFrame = m_pCurrentFrame;
                    End_Picture();  //Expand Plane
*/                }
/*                fprintf(stderr, "POCs: ");
                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( m_Analyse & ANALYSE_SCENECUT ){
                                if( eFrameSeq[i+1]->numIntraMBs > ((385*eFrameSeq[i+1]->numMBs)>>9) ){
                                    Ipp32s s;
                                    eFrameSeq[i+1]->m_PicCodType = INTRAPIC;
                                    for(s=i; s>=0 && (eFrameSeq[s]->m_PicCodType != PREDPIC || eFrameSeq[s]->m_PicCodType != INTRAPIC); s-- )
                                        eFrameSeq[i]->m_PicCodType = PREDPIC;
                                    lref = i+1;
                                    i++;
                                    continue;
                                }else if( eFrameSeq[i]->numIntraMBs > ((385*eFrameSeq[i]->numMBs)>>9) ){
                                    Ipp32s s;
                                    eFrameSeq[i]->m_PicCodType = INTRAPIC;
                                    for(s=i-1; s>=0 && (eFrameSeq[s]->m_PicCodType != PREDPIC || eFrameSeq[s]->m_PicCodType != INTRAPIC); s-- )
                                        eFrameSeq[s]->m_PicCodType = PREDPIC;
                                    lref = i;
                                    continue;
                                }
                            }
*/
        } else {
            return UMC_ERR_INVALID_STREAM;
        }
    }else{
        if (m_pLastFrame && m_pLastFrame->m_PicCodType == BPREDPIC )
        {
            m_pLastFrame->m_PicCodType = PREDPIC;
            m_l1_cnt_to_start_B = 1;
        }
    }

    if (UMC_OK == ps) {

        m_pCurrentFrame = m_cpb.findOldestToEncode(&m_dpb, m_l1_cnt_to_start_B, m_info.treat_B_as_reference);

        if (m_pCurrentFrame){

            if (m_pCurrentFrame->m_bIsIDRPic) m_uFrameCounter = 0;
            m_pCurrentFrame->setFrameNum(m_uFrameCounter);

//            if( m_pCurrentFrame->m_PicCodType != BPREDPIC || m_info.treat_B_as_reference )
            if( m_pCurrentFrame->m_PicCodType != BPREDPIC || m_pCurrentFrame->m_RefPic )
                m_uFrameCounter++;  // Increment for next time through
            // perform noise reduction on the YUV12 video buffer

            m_noisepf->DoFiltering(
                m_pCurrentFrame->m_pYPlane,
                m_pCurrentFrame->m_pUPlane,
                m_pCurrentFrame->m_pVPlane,
                m_pCurrentFrame->pitchPixels(),
                m_pCurrentFrame->pitchPixels(),
                m_pCurrentFrame->uWidth,
                m_pCurrentFrame->uHeight);

            MoveFromCPBToDPB();

            notes &= ~H264_ECN_NO_FRAME;
        } else {
            cnotes |= H264_ECN_NO_FRAME;
            return UMC_ERR_NOT_ENOUGH_DATA;
        }

        EnumPicCodType ePictureType = m_pCurrentFrame->m_PicCodType;
        EnumPicClass    ePic_Class;
        // Determine the Pic_Class.  Right now this depends on ePictureType, but that could change
        // to permit disposable P frames, for example.
        switch (ePictureType)
        {
            case INTRAPIC:
                if (m_pCurrentFrame->m_bIsIDRPic || m_uFrames_Num == 0)
                {
                    // Right now, only the first INTRAPIC in a sequence is an IDR Frame
                    ePic_Class = IDR_PIC;
                    m_l1_cnt_to_start_B = m_info.num_ref_to_start_code_B_slice;
                } else {
                    ePic_Class = REFERENCE_PIC;
                }
                break;

            case PREDPIC:
                ePic_Class = REFERENCE_PIC;
                break;

            case BPREDPIC:
                ePic_Class = m_info.treat_B_as_reference && m_pCurrentFrame->m_RefPic ? REFERENCE_PIC : DISPOSABLE_PIC;
                break;

            default:
                // Unsupported Picture Type
                VM_ASSERT(false);
                ePic_Class = IDR_PIC;
                break;
        }

        // ePictureType is a reference variable.  It is updated by
        // CompressFrame if the frame is internally forced to a key frame.
        ps = CompressFrame(ePictureType, ePic_Class, dst);
        dst->SetTime( m_pCurrentFrame->pts_start, m_pCurrentFrame->pts_end);

        if (dst->GetDataSize() > 0){
            if (ePictureType == INTRAPIC){       // Tell the environment we just generated a key frame
                notes |= H264_ECN_KEY_FRAME;
            }else if (ePictureType == BPREDPIC){ // Tell the environment we just generated a B frame
                notes |= H264_ECN_B_FRAME;
            }
        }

        if (ps == UMC_OK && dst->GetDataSize() == 0 && (flags & H264_ECF_LAST_FRAME)){
            notes |= H264_ECN_NO_FRAME;
        }
    }

    if(ps == UMC_OK) {
        m_pCurrentFrame->setWasEncoded();
    }
    CleanDPB();
    if(ps==UMC_OK) m_info.numEncodedFrames++;
    return ps;
}


// This function frees the encoder's "dimension-dependent" allocations.
template <class PixType, class CoeffsType> Status H264CoreEncoder<PixType,CoeffsType>::End_Sequence()
{
    Status ps = UMC_OK;
    if (m_bBuffersAllocated)
    {
        Deallocate_Buffers();
        m_bBuffersAllocated = false;
    }

    return ps;
}


/**********************************************************************
 *  EncoderH264 destructor.
 **********************************************************************/
template <class PixType, class CoeffsType>
H264CoreEncoder<PixType, CoeffsType>::~H264CoreEncoder()
{
    Close();
    Free_Core_Memory();

    // release the noise reduction prefilter
    if( m_noisepf != NULL ) delete m_noisepf;
    m_noisepf = NULL;
    if (m_EmptyThreshold) {
        ippsFree(m_EmptyThreshold);
        m_EmptyThreshold = NULL;
    }
    if(m_DirectBSkipMEThres) {
        ippsFree(m_DirectBSkipMEThres);
        m_DirectBSkipMEThres = NULL;
    }
    if(m_PSkipMEThres) {
        ippsFree(m_PSkipMEThres);
        m_PSkipMEThres = NULL;
    }
    if(m_BestOf5EarlyExitThres) {
        ippsFree(m_BestOf5EarlyExitThres);
        m_BestOf5EarlyExitThres = NULL;
    }
    if (m_bBuffersAllocated)
    {
        Deallocate_Buffers();
        m_bBuffersAllocated = false;
    }

    if( eFrameType != NULL ){
        delete [] eFrameType;
        eFrameType = NULL;
    }

    if( eFrameSeq != NULL ){
        delete [] eFrameSeq;
        eFrameSeq = NULL;
    }

#ifdef H264_STAT
    hstats.printStat();
#endif
}


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

template <class PixType, class CoeffsType> void H264CoreEncoder<PixType,CoeffsType>::Deallocate_Buffers()
{
    if (m_pbitstreams)
    {
        Ipp32s i;
        for(i = 0; i < m_info.num_slices*((m_info.coding_type == 1) + 1); i++) {  //TODO fix for PicAFF/AFRM
            if (m_pbitstreams[i]) {
                delete m_pbitstreams[i];
                m_pbitstreams[i] = NULL;
            }
        }
        H264_Free(m_pbitstreams);
        m_pbitstreams = NULL;
    }
    m_bScratchBufferAllocated = false;

    if (m_pAllocEncoderInst)
    {
        H264_Free(m_pAllocEncoderInst);

⌨️ 快捷键说明

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