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

📄 umc_vc1_enc_hrd.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/* /////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2007 Intel Corporation. All Rights Reserved.
//
//
//          VC-1 (VC1) encoder, hypothetical reference decoder
//
*/
#include "umc_defs.h"

#if defined (UMC_ENABLE_VC1_VIDEO_ENCODER)

#include "umc_vc1_enc_hrd.h"
#include "umc_vc1_enc_debug.h"
#include "umc_vc1_enc_sequence_adv.h"
#include "umc_vc1_enc_sequence_sm.h"

#include "assert.h"

namespace UMC_VC1_ENCODER
{
extern Ipp32u bMax_LevelLimits[3][5] =
{
     {   /* Simple Profile */
        20,     /* Low    Level */
        77,     /* Medium Level */
        0,      /* Hight Level */
        0,
        0
    },
    {   /* Main Profile */
        306,        /* Low    Level */
        611,        /* Medium Level */
        2442,       /* Hight Level */
        0,
        0
    },
    {   /* Advanced Profile */
        250,        /*L0 level*/
        1250,       /*L1 level*/
        2500,       /*L2 level*/
        5500,       /*L3 level*/
        16500       /*L4 level*/
    }
};


Ipp32u rMax_LevelLimits[3][5] =
{
     {   /* Simple Profile */
        96000,      /* Low    Level */
        384000,     /* Medium Level */
        0,          /* Hight Level */
        0,
        0
    },
    {   /* Main Profile */
        2000000,        /* Low    Level */
        10000000,        /* Medium Level */
        20000000,       /* Hight Level */
        0,
        0
    },
    {   /* Advanced Profile */
        2000000,        /*L0 level*/
        10000000,       /*L1 level*/
        20000000,       /*L2 level*/
        45000000,       /*L3 level*/
        135000000       /*L4 level*/
    }
};

Ipp32u MBfLimits[3][5] =
{
     {   /* Simple Profile */
        99,      /* Low    Level */
        396,     /* Medium Level */
        0,       /* Hight Level */
        0,
        0
    },
    {   /* Main Profile */
        396,         /* Low    Level */
        1620,        /* Medium Level */
        8192,        /* Hight Level */
        0,
        0
    },
    {   /* Advanced Profile */
        396,        /*L0 level*/
        1620,       /*L1 level*/
        3680,       /*L2 level*/
        8192,       /*L3 level*/
        16384       /*L4 level*/
    }
};


VC1HRDecoder::VC1HRDecoder():m_IdealFrameSize(0), m_recoding(0)
{
#ifdef VC1_HRD_DEBUG
    printf("\t\tHRD constructor\n");
#endif
    memset(&m_LBuckets,0,sizeof(VC1_enc_LeakyBucketInfo));
    memset(&hrd_data, 0, sizeof(VC1_hrd_OutData));
};

VC1HRDecoder::~VC1HRDecoder()
{
};

void VC1HRDecoder::Reset()
{
#ifdef VC1_HRD_DEBUG
    printf("\t\tHRD ResetHRDecoder\n");
#endif

    m_LBuckets.vc1_decFullness     = m_LBuckets.vc1_decInitFull;
    m_LBuckets.vc1_dec_delay       = m_LBuckets.vc1_decInitFull;
    m_LBuckets.vc1_decPrevFullness = m_LBuckets.vc1_decInitFull;
    m_LBuckets.vc1_enc_delay       = 0;
    m_LBuckets.vc1_Prev_enc_delay  = 0;


    //memset(&m_LBuckets,0,sizeof(VC1_enc_LeakyBucketInfo));

    //memset(&hrd_data, 0, sizeof(VC1_hrd_OutData));

    m_recoding = 0;
};

UMC::Status VC1HRDecoder::InitBuffer(Ipp32s profile,   Ipp32s level,
                                     Ipp32s bufferSize,Ipp32s initFull,
                                     Ipp32s bitRate,   Ipp64f frameRate)
{
    Ipp32s maxBufSize = 0;
    Ipp32s i = 0; //level
    Ipp32s j = 0; //profile
    m_IdealFrameSize = (Ipp32u)(bitRate/frameRate);  //in bits

    if(profile == VC1_ENC_PROFILE_A)
    {
        j = 2;
        if(level == VC1_ENC_LEVEL_4) i = 4;
        else if(level == VC1_ENC_LEVEL_3) i = 3;
        else if(level == VC1_ENC_LEVEL_2) i = 2;
        else if(level == VC1_ENC_LEVEL_1) i = 1;

    }
    else if (profile == VC1_ENC_PROFILE_M)
    {
        j = 1;
        if(level == VC1_ENC_LEVEL_H)      i = 2;
        else if(level == VC1_ENC_LEVEL_M) i = 1;
    }
    else
    {
        j = 0;
        if(level == VC1_ENC_LEVEL_H)         i = 2;
        else  if(level == VC1_ENC_LEVEL_M)   i = 1;
    }


    if((bufferSize < (m_IdealFrameSize<<1)) && (bufferSize!=0))
    {
        assert(0);
        return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;
    }


    assert(j<4);
    assert(i<5);

    maxBufSize = bMax_LevelLimits[j][i]*16384;
    assert(maxBufSize != 0);

    if(bufferSize <= 0)
        bufferSize = maxBufSize;

    if(bufferSize > maxBufSize)
        bufferSize = maxBufSize;

    if(initFull > bufferSize)
        initFull = (bufferSize*4)/5;

    if(initFull <=0)
        initFull = bufferSize;

    assert(bufferSize!=0);

    m_LBuckets.vc1_decBufferSize = bufferSize;
    m_LBuckets.vc1_decFullness   = initFull;
    m_LBuckets.vc1_decInitFull   = initFull;
    m_LBuckets.vc1_BitRate       = bitRate;
    m_LBuckets.vc1_FrameRate     = frameRate;
    m_LBuckets.vc1_decPrevFullness  = initFull;

    m_LBuckets.vc1_dec_delay     = initFull;

    //hrd params
    hrd_data.hrd_buffer        = bufferSize;

    SetHRDFullness();
    SetHRDRate(0);


#ifdef VC1_HRD_DEBUG
    printf("bufferSize = ,%d\n", bufferSize);
    printf("initFull   = ,%d\n", initFull);
#endif

    return UMC::UMC_OK;
};

Ipp32s VC1HRDecoder::CheckBuffer(Ipp32s frameSize)
{
    Ipp32s Sts = VC1_HRD_OK;
    Ipp32s bufFullness = 0;
    Ipp32s decFullness = 0;
    Ipp32s encDelay    = m_LBuckets.vc1_enc_delay;
    frameSize = frameSize * 8;
    m_recoding++;

#ifdef VC1_HRD_DEBUG
    printf("CheckBuffer,");
#endif

    if(frameSize > m_LBuckets.vc1_decBufferSize)
    {
        return VC1_HRD_ERR_BIG_FRAME;
    }

    decFullness = m_LBuckets.vc1_decFullness /*+ m_IdealFrameSize */+ encDelay;

    if(frameSize > decFullness)
    {
       Sts |= VC1_HRD_ERR_DEC_NOT_ENOUGH_DATA;
       encDelay = decFullness - frameSize;
       decFullness = 0;
    }
    else
    {
        decFullness = decFullness - frameSize;

       if(decFullness < m_LBuckets.vc1_decBufferSize)
       {
            encDelay = 0;
       }
       else
       {
           encDelay = decFullness- m_LBuckets.vc1_decBufferSize;
           decFullness = m_LBuckets.vc1_decBufferSize;
           Sts |= VC1_HRD_ERR_DEC_NOT_ENOUGH_BUFFER;
       }
    }

    bufFullness = decFullness + encDelay + m_IdealFrameSize;

    if(bufFullness <= m_LBuckets.vc1_decBufferSize)
    {
        encDelay = 0;
        if(bufFullness < 0)
        {
            Sts |= VC1_HRD_ERR_ENC_NOT_ENOUGH_DATA;
            encDelay = bufFullness;
            bufFullness = 0;
        }
    }
    else
    {
        encDelay = bufFullness - m_LBuckets.vc1_decBufferSize;
        bufFullness = m_LBuckets.vc1_decBufferSize;
        Sts |= VC1_HRD_ERR_ENC_NOT_ENOUGH_BUFFER;
    }



#ifdef VC1_HRD_DEBUG
   printf("+ = ,%d,", m_IdealFrameSize);
   printf("- = ,%d,", frameSize);
   printf("decFullness = ,%d,", bufFullness);
   printf("encDelay    = ,%d,", encDelay);
#endif

    return Sts;
}

Ipp32s VC1HRDecoder::ReleaseData (Ipp32s frameSize)
{
#ifdef VC1_HRD_DEBUG
    printf("SetNewData,");
#endif

    Ipp32s Sts = VC1_HRD_OK;

    m_LBuckets.vc1_decPrevFullness = m_LBuckets.vc1_decFullness;
    m_LBuckets.vc1_Prev_enc_delay  = m_LBuckets.vc1_enc_delay;

    SetHRDFullness();

    Sts = RemoveFrame(frameSize);
    Sts = AddNewData();

    SetHRDRate(frameSize);

    m_recoding = 0;

#ifdef VC1_HRD_DEBUG
    printf("+ = ,%d,", m_IdealFrameSize);
    printf("- = ,%d,", frameSize*8);
    printf("decFullness = ,%d,",  m_LBuckets.vc1_decFullness);
    printf("encDelay    = ,%d\n", m_LBuckets.vc1_enc_delay);
#endif
    return Sts;
}

Ipp32s VC1HRDecoder::RemoveFrame(Ipp32s frameSize)
{
    Ipp32s Sts = VC1_HRD_OK;
    Ipp32s bufFullness = 0;
    frameSize = frameSize * 8;

    //real fullness
    bufFullness = m_LBuckets.vc1_decFullness + m_LBuckets.vc1_enc_delay;

    if(frameSize > m_LBuckets.vc1_decBufferSize)
    {
#ifdef VC1_HRD_DEBUG
     printf("VC1_HRD_ERR_BIG_FRAME\n");
#endif
     return VC1_HRD_ERR_BIG_FRAME;
   }

    if(frameSize > bufFullness)
    {
        Sts = VC1_HRD_ERR_DEC_NOT_ENOUGH_DATA;
        m_LBuckets.vc1_enc_delay = bufFullness - frameSize;
        m_LBuckets.vc1_decFullness = 0;
    }
    else
    {
       m_LBuckets.vc1_decFullness = bufFullness - frameSize;

       if(m_LBuckets.vc1_decFullness < m_LBuckets.vc1_decBufferSize)
            m_LBuckets.vc1_enc_delay = 0;
       else
       {
           m_LBuckets.vc1_enc_delay = m_LBuckets.vc1_decFullness - m_LBuckets.vc1_decBufferSize;
           m_LBuckets.vc1_decFullness = m_LBuckets.vc1_decBufferSize;
           Sts = VC1_HRD_ERR_DEC_NOT_ENOUGH_BUFFER;
       }
    }

    if(m_LBuckets.vc1_enc_delay > m_LBuckets.vc1_decBufferSize)
        m_LBuckets.vc1_enc_delay = m_LBuckets.vc1_decBufferSize;
    if(m_LBuckets.vc1_enc_delay < - m_LBuckets.vc1_decBufferSize)
        m_LBuckets.vc1_enc_delay = - m_LBuckets.vc1_decBufferSize;

    return Sts;
}

Ipp32s VC1HRDecoder::AddNewData()
{
    Ipp32s Sts = VC1_HRD_OK;
    Ipp32s bufFullness = 0;

    bufFullness = m_LBuckets.vc1_decFullness + m_IdealFrameSize +  m_LBuckets.vc1_enc_delay;

    if(bufFullness <= m_LBuckets.vc1_decBufferSize)
    {
        if(bufFullness >= 0)
        {
            m_LBuckets.vc1_decFullness = bufFullness;
            m_LBuckets.vc1_enc_delay = 0;
        }
        else
        {
            m_LBuckets.vc1_decFullness = 0;
            m_LBuckets.vc1_enc_delay = bufFullness;
            Sts = VC1_HRD_ERR_ENC_NOT_ENOUGH_DATA;
        }
    }
    else
    {
        //bits, whitch not could be written to buffer
        m_LBuckets.vc1_enc_delay = bufFullness - m_LBuckets.vc1_decBufferSize;

        m_LBuckets.vc1_decFullness = m_LBuckets.vc1_decBufferSize;
        Sts = VC1_HRD_ERR_ENC_NOT_ENOUGH_BUFFER;
    }

    if(m_LBuckets.vc1_enc_delay > m_LBuckets.vc1_decBufferSize)
        m_LBuckets.vc1_enc_delay = m_LBuckets.vc1_decBufferSize;
    if(m_LBuckets.vc1_enc_delay < - m_LBuckets.vc1_decBufferSize)
        m_LBuckets.vc1_enc_delay = - m_LBuckets.vc1_decBufferSize;

    return Sts;
}

void VC1HRDecoder::GetHRDParams(VC1_hrd_OutData* hrdParams)
{
    memset(hrdParams, 0, sizeof(VC1_hrd_OutData));
    hrdParams->hrd_buffer   = hrd_data.hrd_buffer;
    hrdParams->hrd_fullness = hrd_data.hrd_fullness;
    hrdParams->hrd_max_rate = hrd_data.hrd_max_rate;
}

void VC1HRDecoder::SetHRDRate(Ipp32s frameSize)
{
    Ipp32s enc_delay =  m_LBuckets.vc1_decFullness - m_LBuckets.vc1_decInitFull
        + m_LBuckets.vc1_enc_delay;

    Ipp32s prev_enc_delay  = m_LBuckets.vc1_decPrevFullness - m_LBuckets.vc1_decInitFull
        + m_LBuckets.vc1_Prev_enc_delay;

    enc_delay = enc_delay - prev_enc_delay;

    Ipp64f enc_delayTime = enc_delay/m_LBuckets.vc1_BitRate;

    //should be change for interlaced and field frames
   Ipp64f T = 1/m_LBuckets.vc1_FrameRate*m_recoding;

   if((T + enc_delayTime == 0) || (m_recoding == 0))
   {
       hrd_data.hrd_max_rate = m_LBuckets.vc1_BitRate;
       return;
   }

   Ipp64f rate = (frameSize*8)/(T + enc_delayTime);

   if(rate > hrd_data.hrd_max_rate)
       hrd_data.hrd_max_rate = (Ipp32s)rate;

#ifdef VC1_HRD_DEBUG
    printf("max_rate = ,%d\n", hrd_data.hrd_max_rate);
#endif
}

void VC1HRDecoder::SetHRDFullness()
{
    Ipp32s fullness = 0;
    Ipp32s temp = 0;
    Ipp32u r    = 0;

    if( m_LBuckets.vc1_decFullness < m_LBuckets.vc1_decBufferSize)
        fullness = m_LBuckets.vc1_decFullness;
    else
        fullness = m_LBuckets.vc1_decBufferSize;

    if(fullness < 0)
        fullness = 0;

    //ROUNDUP fullness/m_LBuckets.vc1_decBufferSize
    temp = fullness/m_LBuckets.vc1_decBufferSize;
    r = ((Ipp32u)(temp * m_LBuckets.vc1_decBufferSize - fullness))>>31;
    temp += r;

    hrd_data.hrd_fullness =256*temp - 1;

#ifdef VC1_HRD_DEBUG
    printf("fullness = ,%d\n", hrd_data.hrd_fullness);
#endif
}

void VC1HRDecoder::SetBitRate(Ipp32s bitRate)
{
    m_LBuckets.vc1_BitRate = bitRate;

    //in bits
    m_IdealFrameSize = (Ipp32u)(m_LBuckets.vc1_BitRate/m_LBuckets.vc1_FrameRate);
}

void VC1HRDecoder::SetFrameRate(Ipp32s frameRate)
{
     m_LBuckets.vc1_FrameRate = frameRate;

     //in bits
     m_IdealFrameSize = (Ipp32u)(m_LBuckets.vc1_BitRate/m_LBuckets.vc1_FrameRate);
}
}
#endif // defined (UMC_ENABLE_VC1_VIDEO_ENCODER)

⌨️ 快捷键说明

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