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

📄 umc_vc1_enc_brc_gop.cpp

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

#ifdef VC1_GOP_DEBUG
        printf("\n\n I:P = %f\n", m_IP_size);
        printf(" I:B = %f\n\n", m_IB_size);
#endif
        }
///---------------------------
        m_needISize = (Ipp32s)(m_nextGOPSize/(1 + m_IP_size*m_PNum + m_IB_size*m_BNum));

        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_B_GOPSize = 0;

        m_CurrINum = 0;
        m_CurrPNum = 0;
        m_CurrBNum = 0;
        m_failGOP = 0;

        m_AveragePQuant = 0;
        m_AverageBQuant = 0;
    }

    m_recoding = 0;
    m_failPQuant = 0;
    m_failBQuant = 0;

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


void VC1BRC_IPB::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;
        case(VC1_B_FRAME):
            {
#ifdef VC1_BRC_DEBUG
            printf("m_LimBQuant %d\n", m_Quant.LimBQuant);
#endif

            if(Sts & VC1_BRC_NOT_ENOUGH_BUFFER)
            {
                if(ratio > VC1_RATIO_ILIM)
                {
                   m_failBQuant   = (m_Quant.BQuant + curQuant + 1)/2 - m_Quant.BQuant;
                   m_Quant.BQuant++;
                   m_Quant.LimBQuant = m_CurQuant.PQIndex + 1;
                }
                else
                {
                    m_Quant.BQuant = (m_Quant.BQuant + curQuant + 1)/2;

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

                m_Quant.LimBQuant--;

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

               m_Quant.LimBQuant--;

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

            VC1_QUANT_CLIP(m_Quant.LimBQuant,0);
            VC1_QUANT_CLIP(m_Quant.BQuant, m_Quant.LimBQuant);

            m_Quant.BHalf = HalfQP;
            }
            break;
    }
 };

 void VC1BRC_IPB::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)
                    m_Quant.IHalf = 0;

                 m_Quant.IQuant = (m_Quant.IQuant + curQuant + 1)/2;

                // m_Quant.LimIQuant = (m_Quant.LimIQuant + m_Quant.IQuant)/2;

                 //VC1_QUANT_CLIP(m_Quant.LimIQuant,0);
                 VC1_QUANT_CLIP(m_Quant.IQuant, m_Quant.LimIQuant);
             }
             break;
         case(VC1_P_FRAME):
             {
                 //new quant calculation
                 curQuant = (Ipp32s)(ratio * m_Quant.PQuant - 0.5);
                 VC1_QUANT_CLIP(curQuant, 0);

                 if(curQuant != m_Quant.PQuant)
                    m_Quant.PHalf = 0;

                 m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;
                 m_Quant.LimPQuant = (m_Quant.LimPQuant + m_Quant.PQuant)/2;

                 VC1_QUANT_CLIP(m_Quant.LimPQuant,0);
                 VC1_QUANT_CLIP(m_Quant.PQuant, m_Quant.LimPQuant);
             }
             break;
         case(VC1_B_FRAME):
             {
                 //new quant calculation
                 curQuant = (Ipp32s)(ratio * m_Quant.BQuant - 0.5);
                 VC1_QUANT_CLIP(curQuant, 0);

                 if(curQuant != m_Quant.BQuant)
                    m_Quant.BHalf = 0;

                 m_Quant.BQuant = (m_Quant.BQuant + curQuant + 1)/2;
                 m_Quant.LimBQuant = (m_Quant.LimBQuant + m_Quant.BQuant)/2;

                 VC1_QUANT_CLIP(m_Quant.LimBQuant,0);
                 VC1_QUANT_CLIP(m_Quant.BQuant, m_Quant.LimBQuant);
             }
             break;
     }
 };

void VC1BRC_IPB::GetQuant(Ipp32u picType, Ipp8u* PQuant, bool* Half)
{
    m_picType = picType;

    switch (picType)
    {
    case(VC1_I_FRAME):
        m_CurQuant.PQIndex = m_Quant.IQuant;
        m_CurQuant.HalfPQ  = m_Quant.IHalf;
        break;
    case(VC1_P_FRAME):
        m_CurQuant.PQIndex = m_Quant.PQuant + m_failPQuant;
        m_CurQuant.HalfPQ  = m_Quant.PHalf;

        if(m_encMode != VC1_BRC_CONST_QUANT_MODE)
            if(m_poorRefFrame&0x1)
            {//correct quant for next B frame
                if(m_CurQuant.PQIndex > 9)
                {
                    m_CurQuant.PQIndex--;
                    m_CurQuant.HalfPQ = 1;
                    m_Quant.PQuant--;
                    m_Quant.PHalf = 0;
                }
                else
                {
                    m_CurQuant.HalfPQ = 0;
                    m_Quant.PHalf = 0;
                }

            }

        VC1_QUANT_CLIP(m_CurQuant.PQIndex,0);
        VC1_QUANT_CLIP(m_CurQuant.PQIndex, m_Quant.LimPQuant);
        break;

    case(VC1_B_FRAME):
        m_CurQuant.PQIndex = m_Quant.BQuant  + m_failBQuant;
        m_CurQuant.HalfPQ  = m_Quant.BHalf;
        if(m_encMode != VC1_BRC_CONST_QUANT_MODE)
            if(m_poorRefFrame)
            {//correct quant for next B frame
                if(m_CurQuant.PQIndex > 9)
                {
                    m_CurQuant.PQIndex--;
                    m_CurQuant.HalfPQ = 1;
                    m_Quant.BQuant--;
                    m_Quant.BHalf = 0;
                }
                else
                {
                    m_CurQuant.HalfPQ = 0;
                    m_Quant.BHalf = 0;
                }

            }

        VC1_QUANT_CLIP(m_CurQuant.PQIndex,0);
        VC1_QUANT_CLIP(m_CurQuant.PQIndex, m_Quant.LimBQuant);

        break;
        default:
            break;
    }

    if(m_CurQuant.PQIndex > 8)
        m_CurQuant.HalfPQ  = 0;

#ifdef VC1_BRC_DEBUG
    printf("cur quant %d\n", m_CurQuant.PQIndex);
    printf("half quant %d\n",  m_CurQuant.HalfPQ);
#endif

    *PQuant = m_CurQuant.PQIndex;
    *Half   = m_CurQuant.HalfPQ;
}
}
#endif // defined (UMC_ENABLE_VC1_VIDEO_ENCODER)

⌨️ 快捷键说明

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