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

📄 umc_vc1_enc_brc_gop.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    m_currGOPSize = 0;

    m_I_GOPSize = m_P_GOPSize = 0;

    m_CurrINum = m_CurrPNum = 0;
    m_currFrameInGOP = 0;
    m_SizeAbberation = 0;

    //Frames parameters
    m_currSize = 0;

    m_needISize = (Ipp32s)(m_GOPSize/(1 + m_IP_size*m_PNum));
    m_needPSize = (Ipp32s)(m_IP_size*m_needISize);

    m_currISize = m_needISize;
    m_currPSize = m_needPSize;

    //Flags
    m_recoding     = 0;
    m_poorRefFrame = 0;
    m_GOPHalfFlag  = 1;
    m_failPQuant   = 0;
    m_failGOP      = 0;

    //Picture params
    m_picType = VC1_I_FRAME;
};

UMC::Status VC1BRC_IP::CheckFrameCompression(Ipp32u picType, Ipp32u currSize, UMC::Status HRDSts)
{
    UMC::Status UMCSts = UMC::UMC_OK;
    Ipp32s Sts = 0;
    Ipp32f ratio = 0;

    if(m_recoding)
        m_poorRefFrame &= 0x2;

    if(currSize < 0)
        return UMC::UMC_ERR_INVALID_PARAMS;

    m_currSize = currSize;

    switch (picType)
    {
        case(VC1_I_FRAME):
#ifdef VC1_GOP_DEBUG
     printf("I ");
#endif
            m_currISize = currSize;
            ratio = ((Ipp32f)m_currISize/(Ipp32f)m_needISize);
            if(ratio < VC1_POOR_REF_FRAME)
                m_poorRefFrame = 1;
            else
                m_poorRefFrame = 0;
            break;
        case(VC1_P_FRAME):
#ifdef VC1_GOP_DEBUG
     printf("P ");
#endif
            m_currPSize = currSize;
            ratio = ((Ipp32f)m_currPSize/(Ipp32f)m_needPSize);
            if(ratio < VC1_POOR_REF_FRAME)
                m_poorRefFrame = 1;
            else
                m_poorRefFrame = 0;

            break;
    }

#ifdef VC1_BRC_DEBUG
     printf("current ratio = %f\n", ratio);
#endif
#ifdef VC1_GOP_DEBUG
     printf("current ratio = %f   %d  %d %d\n", ratio, m_CurQuant.PQIndex, m_CurQuant.HalfPQ, currSize);
#endif

    if(m_failGOP)
        HRDSts = UMC::UMC_ERR_NOT_ENOUGH_BUFFER;

    switch(m_encMode)
    {
    case VC1_BRC_HIGHT_QUALITY_MODE:
        CheckFrame_QualityMode(picType, ratio, HRDSts);
        break;
    case VC1_BRC_CONST_QUANT_MODE:
        break;
    default:
        break;
    }
    m_recoding++;

#ifdef VC1_BRC_DEBUG
    printf("coded size %d\n", currSize);
#endif

    return UMCSts;
};
void VC1BRC_IP::CompleteFrame(Ipp32u picType)
{
    UMC::Status UMCSts = UMC::UMC_OK;
    Ipp32f ratioI = 0;
    Ipp32f ratioP = 0;
    Ipp32s prefINeedSize = m_needISize;
    Ipp32s prefPNeedSize = m_needPSize;

#ifdef BRC_TEST
     if(BRCFileSizeTest.RES_File)
        fprintf(BRCFileSizeTest.RES_File, "%d,",m_currSize);
#endif

    if(m_encMode == VC1_BRC_CONST_QUANT_MODE)
        return;

    m_currFrameInGOP++;
    m_currGOPSize += m_currSize;

    switch (picType)
    {
    case VC1_I_FRAME:
        m_I_GOPSize += m_currSize;
        m_CurrINum++;
        m_AverageIQuant = m_CurQuant.PQIndex;
        break;
    case VC1_P_FRAME:
        m_P_GOPSize += m_currSize;
        m_CurrPNum++;
        m_AveragePQuant +=  (m_CurQuant.PQIndex*2 + m_CurQuant.HalfPQ);
        break;
    }

    if(m_GOPHalfFlag
        && ((m_currGOPSize > m_GOPSize/2) || m_currFrameInGOP == m_GOPLength/2)
        || (m_currFrameInGOP == 1) || m_failPQuant)
    {

        Ipp32s PBSize = m_nextGOPSize - m_currGOPSize;

        if(m_currFrameInGOP != 1)
        {
            m_GOPHalfFlag = 0;
        }

        if(((PBSize) > m_IdealFrameSize) && ( m_currFrameInGOP != m_GOPLength))
        {
            m_needPSize = (Ipp32s)(PBSize/((m_PNum - m_CurrPNum)));
        }
        else
        {
            m_failGOP = 1;
            if(m_needPSize > m_IdealFrameSize/2)
                m_needPSize = (Ipp32s)(m_needPSize*0.75);
        }

        ratioP = ((Ipp32f)prefPNeedSize/(Ipp32f)m_needPSize);
        if(m_needPSize < (m_IdealFrameSize>>2))
            ratioP = 1;

        QuantForNewGOP(VC1_P_FRAME, ratioP);
    }


    if(m_currFrameInGOP == m_GOPLength)
    {
#ifdef VC1_GOP_DEBUG
    printf("\nGOP ratio = %f\n", ((Ipp32f)m_currGOPSize/(Ipp32f)m_nextGOPSize));
    printf("\nIdeal     = %f\n", ((Ipp32f)m_currGOPSize/(Ipp32f)m_GOPSize));

    printf("\n\n IQuant = %d    PQuant = %d\n\n", m_AverageIQuant, m_AveragePQuant/(m_PNum*2) + 1);

    printf("-----------------------------------NEW GOP");
    printf("------------------------------------------\n\n\n");
#endif

    m_SizeAbberation += m_GOPSize - m_currGOPSize;

    //check overflow m_SizeAbberation
    if(m_SizeAbberation > 4*m_GOPSize)
        m_SizeAbberation = 4*m_GOPSize;

    if(m_SizeAbberation < (- 4*m_GOPSize))
        m_SizeAbberation = -(4*m_GOPSize);

    m_INum = 1;
    m_PNum = (m_GOPLength - 1)/(m_BFrLength+1);

    m_GOPSize = m_IdealFrameSize * m_GOPLength;

    m_nextGOPSize = m_GOPSize + m_SizeAbberation;

    //check m_needISize
    if(m_nextGOPSize > m_GOPSize + (m_GOPSize>>1))
       m_nextGOPSize = m_GOPSize + (m_GOPSize>>1);

    if(m_nextGOPSize < (m_GOPSize>>1))
        m_nextGOPSize = (m_GOPSize>>1);


#ifdef VC1_GOP_DEBUG
            printf("nextGOPSize = %d\n", m_nextGOPSize);
            printf("m_SizeAbberation = %d\n", m_SizeAbberation);
#endif

 //---------------------------
        {
            m_AveragePQuant /= (m_PNum*2);
            m_AveragePQuant++;
            Ipp32f P_average_size =  (Ipp32f)(m_P_GOPSize/m_PNum);
            Ipp32f PRatio = (P_average_size*m_AveragePQuant)/(m_I_GOPSize*m_AverageIQuant);
            m_IP_size = (m_IP_size + PRatio)/2;

            if(m_IP_size > 1)
                m_IP_size = 1;

#ifdef VC1_GOP_DEBUG
        printf("\n\n I:P = %f\n\n", m_IP_size);
#endif
        }

//---------------------------
        m_needISize = (Ipp32s)(m_nextGOPSize/(1 + m_IP_size*m_PNum));

        ratioI = ((Ipp32f)prefINeedSize/(Ipp32f)m_needISize);

        QuantForNewGOP(VC1_I_FRAME, ratioI);

        m_currFrameInGOP = 0;
        m_poorRefFrame = 0;
        m_currGOPSize = 0;
        m_GOPHalfFlag = 1;

        m_I_GOPSize = 0;
        m_P_GOPSize = 0;

        m_CurrINum = 0;
        m_CurrPNum = 0;

        m_failGOP = 0;
        m_AveragePQuant = 0;
        m_AverageIQuant = 0;
    }

    m_recoding = 0;
    m_failPQuant = 0;

#ifdef VC1_BRC_DEBUG
    printf("\n\n\n");
#endif
};


void VC1BRC_IP::CheckFrame_QualityMode(Ipp32u picType, Ipp32f ratio, UMC::Status UMCSts)
{
    Ipp32s curQuant = 0;
    Ipp32s Sts = VC1_BRC_OK;
    bool HalfQP = 0;

    //new quant calculation
    curQuant = (Ipp32s)(ratio * m_CurQuant.PQIndex + 0.5);
    VC1_QUANT_CLIP(curQuant, 0);

    //check compression
    if((ratio <= m_buffer_overflow) && (ratio >= VC1_GOOD_COMPRESSION))
        Sts = VC1_BRC_OK;       //good frame
    else if(ratio > m_buffer_overflow)
        Sts |= VC1_BRC_NOT_ENOUGH_BUFFER; //could be critical situation, if HRD buffer small
    else  if(ratio <= m_ratio_min)
    {
        //very small frame
        Sts |= VC1_BRC_ERR_SMALL_FRAME;

        if(m_CurQuant.PQIndex > 1)
            HalfQP = 1;
    }
    else if(ratio >= VC1_MIN_RATIO_HALF)
    {
        if((m_CurQuant.PQIndex > 1) && ((Ipp32u)curQuant > m_CurQuant.PQIndex))
            HalfQP = 1;
        Sts |= VC1_BRC_SMALL_FRAME;
    }
    else
         Sts |= VC1_BRC_SMALL_FRAME;

    //check HRD status
    if(UMCSts ==  UMC::UMC_ERR_NOT_ENOUGH_BUFFER)
    {
        Sts |= VC1_BRC_NOT_ENOUGH_BUFFER;
        HalfQP = 0;
    }

    if(Sts != VC1_BRC_OK)
    switch (picType)
    {
        case(VC1_I_FRAME):
            {
#ifdef VC1_BRC_DEBUG
            printf("m_LimIQuant %d\n", m_Quant.LimIQuant);
#endif
            m_Quant.IQuant = (m_Quant.IQuant + curQuant)/2;

            if(Sts & VC1_BRC_NOT_ENOUGH_BUFFER)
            {
                if(ratio > VC1_RATIO_ILIM)
                {
                   m_Quant.IQuant++;
                   m_Quant.LimIQuant = m_CurQuant.PQIndex + 2;
                }
                else
                {
                    if(m_CurQuant.PQIndex > 9)
                        m_Quant.LimIQuant = m_CurQuant.PQIndex + 1;
                    else if(m_Quant.IQuant <= m_CurQuant.PQIndex)
                        HalfQP = 1;
                }
            }
            else if(Sts & VC1_BRC_ERR_SMALL_FRAME)
            {
                m_Quant.LimIQuant--;

                if(m_Quant.IQuant >= m_CurQuant.PQIndex)
                    m_Quant.IQuant--;

                if((ratio > VC1_MIN_RATIO_HALF) &&  (m_CurQuant.PQIndex > 1))
                    HalfQP = 1;

            }
            else if(Sts & VC1_BRC_SMALL_FRAME)
            {
                m_Quant.LimIQuant--;

               if((m_Quant.IQuant < m_CurQuant.PQIndex) && m_Quant.IQuant &&  (m_CurQuant.PQIndex > 1))
                    HalfQP = 1;

            }

            VC1_QUANT_CLIP(m_Quant.LimIQuant,0);
            VC1_QUANT_CLIP(m_Quant.IQuant, m_Quant.LimIQuant);

            m_Quant.IHalf = HalfQP;
            }
            break;
        case(VC1_P_FRAME):
            {
#ifdef VC1_BRC_DEBUG
            printf("m_LimPQuant %d\n", m_Quant.LimPQuant);
#endif

            if(Sts & VC1_BRC_NOT_ENOUGH_BUFFER)
            {
                if(ratio > VC1_RATIO_ILIM)
                {
                    m_failPQuant   = (m_Quant.PQuant + curQuant + 1)/2 - m_Quant.PQuant;

                    m_Quant.PQuant++;
                    m_Quant.LimPQuant = m_CurQuant.PQIndex + 1;
                }
                else
                {
                    m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;

                    if(m_Quant.PQuant <= m_CurQuant.PQIndex)
                            if(m_CurQuant.PQIndex > 9)
                            {
                                    if(m_Quant.PQuant <= m_CurQuant.PQIndex)
                                        m_Quant.PQuant++;
                            }
                            else
                            {
                                if(!m_CurQuant.HalfPQ)
                                    HalfQP = 1;
                                else
                                {
                                    HalfQP = 0;
                                    if(m_Quant.PQuant <= m_CurQuant.PQIndex)
                                        m_Quant.PQuant++;
                                }
                            }
                }
            }
            else if(Sts & VC1_BRC_ERR_SMALL_FRAME)
            {
                m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;

                m_Quant.LimPQuant--;

                if(m_CurQuant.PQIndex > 9)
                {
                        if(m_Quant.PQuant >= m_CurQuant.PQIndex)
                            m_Quant.PQuant--;
                }
                else
                {
                    if(m_CurQuant.HalfPQ)
                        HalfQP = 0;
                    else
                    {
                        if(m_Quant.PQuant >= m_CurQuant.PQIndex)
                            m_Quant.PQuant--;
                    }
                }
            }
            else if(Sts & VC1_BRC_SMALL_FRAME)
            {
                m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;

                m_Quant.LimPQuant--;

                if(m_CurQuant.HalfPQ)
                    HalfQP = 0;
                else
                {
                    if(m_Quant.PQuant >= m_CurQuant.PQIndex)
                    {
                        m_Quant.PQuant--;
                        if((m_CurQuant.PQIndex != VC1_MIN_QUANT) && (ratio > VC1_MIN_RATIO_HALF))
                                HalfQP = 1;
                    }
                }
            }

            VC1_QUANT_CLIP(m_Quant.LimPQuant,0);
            VC1_QUANT_CLIP(m_Quant.PQuant, m_Quant.LimPQuant);

            m_Quant.PHalf = HalfQP;
            }
            break;
    }
 };

 void VC1BRC_IP::QuantForNewGOP(Ipp32u picType, Ipp32f ratio)
 {
     Ipp32s curQuant = 0;

     if(ratio == 1)
        return;

     switch (picType)
     {
         case(VC1_I_FRAME):
             {
                 //new quant calculation
                 curQuant = (Ipp32s)(ratio * m_Quant.IQuant + 0.5);
                 VC1_QUANT_CLIP(curQuant, 0);

                 if(curQuant != m_Quant.IQuant)

⌨️ 快捷键说明

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