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

📄 umc_vc1_enc_brc_gop.cpp

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

                 m_Quant.IQuant = (m_Quant.IQuant + curQuant + 1)/2;
                 //m_Quant.LimIQuant = (m_Quant.LimIQuant + m_Quant.IQuant - 1)/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 - 1)/2;

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

void VC1BRC_IP::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)
            {//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, m_Quant.LimPQuant);

        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;
}
////////////////////////////////////////////
//          VC1BRC_IPB
////////////////////////////////////////////
VC1BRC_IPB::VC1BRC_IPB() : m_I_GOPSize(0),    m_P_GOPSize(0),      m_B_GOPSize(0),
                           m_needISize(0),    m_needPSize(0),      m_needBSize(0),
                           m_INum(0),         m_PNum(0),           m_BNum(0),
                           m_CurrINum(0),     m_CurrPNum(0),       m_CurrBNum(0),
                           m_frameInGOP(0),   m_currFrameInGOP(0),
                           m_poorRefFrame(0), m_GOPHalfFlag(0),
                           m_currISize(0),    m_currPSize(0),      m_currBSize(0),
                           m_GOPSize(0),      m_currGOPSize(0),    m_nextGOPSize(0),
                           m_IP_size((Ipp32f)(VC1_P_SIZE)), m_IB_size((Ipp32f)(VC1_B_SIZE)),
                           m_failPQuant(0), m_failBQuant(0), m_failGOP(0),
                           m_AveragePQuant(0),m_AverageIQuant(0),  m_AverageBQuant(0)

{
};

VC1BRC_IPB::~VC1BRC_IPB()
{
};

UMC::Status VC1BRC_IPB::Init(Ipp32u yuvFSize,  Ipp32u bitrate,  Ipp64f framerate,
                           Ipp32u mode,        Ipp32u GOPLength,Ipp32u BFrLength,
                           Ipp32u doubleQuant)
 {
    UMC::Status VC1Sts = UMC::UMC_OK;

    m_bitrate   = bitrate;
    m_framerate = framerate;
    m_GOPLength = GOPLength;
    m_BFrLength = BFrLength;

    m_INum = 1;
    m_PNum = (GOPLength - 1)/BFrLength;
    m_BNum = m_PNum*BFrLength;

    m_IdealFrameSize = (Ipp32u)(bitrate/framerate/8);
    m_frameInGOP = m_INum + m_PNum + m_BNum;
    m_GOPSize      = m_IdealFrameSize * m_frameInGOP;
    m_nextGOPSize    = m_GOPSize;

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

    m_currISize = m_needISize;
    m_currPSize = m_needPSize;
    m_currBSize = m_needBSize;

    if(!doubleQuant)
    {
        Ipp32s AverageCompression = (Ipp32s)((yuvFSize)/m_needISize)/3;

        VC1_QUANT_CLIP(AverageCompression, 0);
        m_CurQuant.PQIndex = m_Quant.IQuant = AverageCompression;

        AverageCompression = (Ipp32s)((yuvFSize)/m_needPSize)/5;
        VC1_QUANT_CLIP(AverageCompression, 0);

        m_Quant.PQuant =  AverageCompression;

        if(m_Quant.PQuant > 2)
            m_Quant.PQuant -= 2;

        AverageCompression = (Ipp32s)((yuvFSize)/m_needBSize)/6;
        VC1_QUANT_CLIP(AverageCompression, 0);

        m_Quant.BQuant = AverageCompression;

        if(m_Quant.BQuant > 2)
            m_Quant.BQuant -= 2;
    }
    else
    {
        if(doubleQuant > (VC1_MAX_QUANT*2))
            return UMC::UMC_ERR_ALLOC;

        m_encMode = VC1_BRC_CONST_QUANT_MODE;
        m_CurQuant.PQIndex = m_Quant.IQuant = m_Quant.PQuant = m_Quant.BQuant = (doubleQuant>>1);
        m_CurQuant.HalfPQ  = m_Quant.IHalf = m_Quant.PHalf = m_Quant.BHalf = doubleQuant&0x1;
    }

    switch(m_encMode)
    {
    case VC1_BRC_HIGHT_QUALITY_MODE:
    case VC1_BRC_CONST_QUANT_MODE:
        m_ratio_min       = (Ipp32f)(0.6);
        m_buffer_overflow = (Ipp32f)(1.1);
        break;
    default:
        m_ratio_min       = (Ipp32f)(0.6);
        m_buffer_overflow = (Ipp32f)(1.1);
        break;
    }

    return VC1Sts;
 };

void VC1BRC_IPB::Close()
{
    Reset();
}

void VC1BRC_IPB::Reset()
{
    m_CurrINum = m_CurrPNum = m_CurrBNum = 0;

    m_SizeAbberation = 0;

    //Frames parameters
    m_currSize = 0;

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

    //Picture params
    m_picType = VC1_I_FRAME;

    m_GOPSize      = m_IdealFrameSize * m_frameInGOP;
    m_nextGOPSize    = m_GOPSize;

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

    m_currISize = m_needISize;
    m_currPSize = m_needPSize;
    m_currBSize = m_needBSize;
};

UMC::Status VC1BRC_IPB::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 = ((m_poorRefFrame<<1) + 1)&0x3;
            else
                m_poorRefFrame = (m_poorRefFrame<<1)&0x3;
            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 = ((m_poorRefFrame<<1) + 1)&0x3;
            else
                m_poorRefFrame = (m_poorRefFrame<<1)&0x3;

            break;
        case(VC1_B_FRAME):
#ifdef VC1_GOP_DEBUG
     printf("B ");
#endif
            m_currBSize = currSize;
            ratio = ((Ipp32f)m_currBSize/(Ipp32f)m_needBSize);
            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_IPB::CompleteFrame(Ipp32u picType)
{
    UMC::Status UMCSts = UMC::UMC_OK;
    Ipp32f ratioI = 0;
    Ipp32f ratioP = 0;
    Ipp32f ratioB = 0;
    Ipp32s prefINeedSize = m_needISize;
    Ipp32s prefPNeedSize = m_needPSize;
    Ipp32s prefBNeedSize = m_needBSize;

#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;
    case VC1_B_FRAME:
        m_B_GOPSize += m_currSize;
        m_CurrBNum++;
        m_AverageBQuant +=  (m_CurQuant.PQIndex*2 + m_CurQuant.HalfPQ);
        break;
    }

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

        Ipp32s PBSize = m_nextGOPSize - m_currGOPSize;

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

        if((PBSize > m_IdealFrameSize)  && (m_currFrameInGOP != m_frameInGOP))
        {

            m_needPSize = (Ipp32s)(PBSize/((m_PNum - m_CurrPNum)
                + (m_IB_size/m_IP_size)*(m_BNum - m_CurrBNum)));

            m_needBSize = (Ipp32s)(m_needPSize*(m_IB_size/m_IP_size));
        }
        else
        {
            m_failGOP = 1;
            if(m_needPSize > m_IdealFrameSize/2)
                m_needPSize = (Ipp32s)(m_needPSize*0.75);
            if(m_needBSize > m_IdealFrameSize/2)
                m_needBSize = (Ipp32s)(m_needBSize*0.75);
        }


        //printf("prefPNeedSize = %d, m_needPSize = %d, m_IdealFrameSize = %d\n", prefPNeedSize, m_needPSize, m_IdealFrameSize);
        //printf("prefBNeedSize = %d, m_needBSize = %d, m_IdealFrameSize = %d\n", prefBNeedSize, m_needBSize, m_IdealFrameSize);
        ratioP = ((Ipp32f)prefPNeedSize/(Ipp32f)m_needPSize);
        ratioB = ((Ipp32f)prefBNeedSize/(Ipp32f)m_needBSize);

        if(m_needPSize < (m_IdealFrameSize>>2))
            ratioP = 1;
        if(m_needBSize < (m_IdealFrameSize>>2))
            ratioB = 1;

        QuantForNewGOP(VC1_P_FRAME, ratioP);
        QuantForNewGOP(VC1_B_FRAME, ratioB);
    }


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

    printf("\n\n IQuant = %d    PQuant = %d    BQuant = %d\n\n",
        m_AverageIQuant, m_AveragePQuant/(m_PNum*2) + 1, m_AverageBQuant/(m_BNum*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_AveragePQuant /= (m_PNum*2);
        m_AveragePQuant++;

        m_AverageBQuant /= (m_BNum*2);
        m_AverageBQuant++;
///---------------------------
        m_INum = 1;
        m_PNum = (m_GOPLength - 1)/(m_BFrLength+1);
        m_BNum = m_GOPLength - m_INum - m_PNum;
        m_frameInGOP = m_INum + m_PNum + m_BNum;

        m_GOPSize      = m_IdealFrameSize * m_frameInGOP;

        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

///---------------------------
        {
            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;


            Ipp32f B_average_size =  (Ipp32f)(m_B_GOPSize/m_BNum);
            Ipp32f BIRatio = (B_average_size*m_AverageBQuant)/(m_I_GOPSize*m_AverageIQuant);
            Ipp32f BPRatio = (B_average_size*m_AverageBQuant)/(m_P_GOPSize*m_AveragePQuant);
            m_IB_size = (m_IB_size + BIRatio + BPRatio)/3;

            if(m_IB_size > 1)
                m_IB_size = 1;

⌨️ 快捷键说明

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