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

📄 umc_vc1_enc_bitstream.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, bitstream functionality
//
*/
#include "umc_defs.h"

#if defined (UMC_ENABLE_VC1_VIDEO_ENCODER)

#include "umc_vc1_enc_bitstream.h"
namespace UMC_VC1_ENCODER
{
void VC1EncoderBitStreamSM::Init(UMC::MediaData* data)
{
    m_pBitStream    = (Ipp32u*) data->GetBufferPointer();
    m_iOffset       = 32;
    m_pBitStream[0] = 0;

    m_pBufferStart  = m_pBitStream;
    m_iBufferLen    = data->GetBufferSize();

    m_pBlankSegment     = 0;
    m_iBlankSegmentLen  = 0;

    m_dPTS          = data->GetTime();
}
void VC1EncoderBitStreamAdv::Init(UMC::MediaData* data)
{
    m_pBitStream    = (Ipp32u*) data->GetBufferPointer();
    m_iOffset       = 32;
    m_pBitStream[0] = 0;

    m_pBufferStart  = m_pBitStream;
    m_iBufferLen    = data->GetBufferSize();

    m_dPTS          = data->GetTime();

    ResetCodeStatus();

    m_bLast         = false;
}
void  VC1EncoderBitStreamSM::Reset()
{
    m_pBitStream        = 0;
    m_pBufferStart      = 0;
    m_iBufferLen        = 0;
    m_iOffset           = 32;
    m_dPTS              = -1;
    m_pBlankSegment     = 0;
    m_iBlankSegmentLen  = 0;
}
void  VC1EncoderBitStreamAdv::Reset()
{
    m_pBitStream        = 0;
    m_pBufferStart      = 0;
    m_iBufferLen        = 0;
    m_iOffset           = 32;
    m_dPTS              = -1;
    m_bLast             = false;
}

UMC::Status VC1EncoderBitStreamSM::DataComplete(UMC::MediaData* data)
{
    size_t  dataLen = 0;

    UMC::Status ret = AddLastBits();
    if (ret != UMC::UMC_OK) return ret;

    dataLen = (m_pBitStream - m_pBufferStart)*sizeof(Ipp32u);
    VM_ASSERT (dataLen < m_iBufferLen);

    ret = data->SetDataSize(dataLen);
    if (ret != UMC::UMC_OK) return ret;

    ret = data->SetTime(m_dPTS);
    if (ret != UMC::UMC_OK) return ret;

    Reset();

    return ret;
}
UMC::Status VC1EncoderBitStreamAdv::DataComplete(UMC::MediaData* data)
{
    size_t  dataLen = 0;

    UMC::Status ret = AddLastBits();
    if (ret != UMC::UMC_OK) return ret;

    dataLen = (m_pBitStream - m_pBufferStart)*sizeof(Ipp32u);
    VM_ASSERT (dataLen < m_iBufferLen);

    ret = data->SetDataSize(dataLen);
    if (ret != UMC::UMC_OK) return ret;

    ret = data->SetTime(m_dPTS);
    if (ret != UMC::UMC_OK) return ret;

    Reset();

    return ret;
}

UMC::Status VC1EncoderBitStreamSM::AddLastBits()
{
    UMC::Status ret = UMC::UMC_OK;
    assert (m_iOffset!=0);
    if (m_iOffset!=32 )
    {
        ret =PutBits((1<<(m_iOffset-1)),m_iOffset);
    }
    return ret;
}
UMC::Status VC1EncoderBitStreamAdv::AddLastBits()
{
    UMC::Status ret = UMC::UMC_OK;
    assert (m_iOffset!=0);
    if (!m_bLast)
    {
        ret =PutStartCode((1<<(m_iOffset-1)),m_iOffset);
    }
    m_bLast = true;
    return ret;
}
static Ipp32u mask[] = {
                   0x00000000,
                   0x00000001,0x00000003,0x00000007,0x0000000F,
                   0x0000001F,0x0000003F,0x0000007F,0x000000FF,
                   0x000001FF,0x000003FF,0x000007FF,0x00000FFF,
                   0x00001FFF,0x00003FFF,0x00007FFF,0x0000FFFF,
                   0x0001FFFF,0x0003FFFF,0x0007FFFF,0x000FFFFF,
                   0x001FFFFF,0x003FFFFF,0x007FFFFF,0x00FFFFFF,
                   0x01FFFFFF,0x03FFFFFF,0x07FFFFFF,0x0FFFFFFF,
                   0x1FFFFFFF,0x3FFFFFFF,0x7FFFFFFF,0xFFFFFFFF
};

UMC::Status VC1EncoderBitStreamSM::PutBits(Ipp32u val,Ipp32s len)
 {
    Ipp32s tmpcnt;
    Ipp32u r_tmp;

    assert(m_pBitStream!=NULL);
    assert(len<=32);

    if ((Ipp8u*)m_pBitStream + (len + m_iOffset)/8 >= (Ipp8u*)m_pBufferStart + m_iBufferLen - 1)
        return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;

    val = val & mask[len];

    tmpcnt = (m_iOffset) - (len);

    if(tmpcnt <= 0)
    {
      Ipp32u z=0;
      r_tmp = (m_pBitStream)[0] | ((val) >> (-tmpcnt));
      (m_pBitStream)[0] = BSWAP(r_tmp);
      (m_pBitStream)++;
      z = (tmpcnt<0)? (val << (32 + tmpcnt)):z;
      (m_pBitStream)[0] = z ;
      (m_iOffset) = 32 + tmpcnt;
    }
    else
    {
      (m_pBitStream)[0] |= (val) << tmpcnt;
      m_iOffset = tmpcnt;
    }
    return UMC::UMC_OK;
}
 UMC::Status VC1EncoderBitStreamSM::PutBitsHeader(Ipp32u val,Ipp32s len)
 {
    Ipp32s tmpcnt;
    Ipp32u r_tmp;

    assert(m_pBitStream!=NULL);
    assert(len<=32);

    if ((Ipp8u*)m_pBitStream + (len + m_iOffset)/8 >= (Ipp8u*)m_pBufferStart + m_iBufferLen - 1)
        return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;

    val = val & mask[len];

    tmpcnt = (m_iOffset) - (len);

    if(tmpcnt <= 0)
    {
      Ipp32u z=0;
      r_tmp = (m_pBitStream)[0] | ((val) >> (-tmpcnt));
      (m_pBitStream)[0] = BNOSWAP(r_tmp);
      (m_pBitStream)++;
      z = (tmpcnt<0)? (val << (32 + tmpcnt)):z;
      (m_pBitStream)[0] = z ;
      (m_iOffset) = 32 + tmpcnt;
    }
    else
    {
      (m_pBitStream)[0] |= (val) << tmpcnt;
      m_iOffset = tmpcnt;
    }
    return UMC::UMC_OK;
}
static Ipp32u maskUpper[] = {0x00000000, 0xFF000000, 0xFFFF0000,0xFFFFFF00};
static Ipp32u maskLower[] = {0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF,0x000000FF};
static Ipp32u maskL[] = {0x00000000, 0x000000FF, 0x0000FFFF,0x00000000};

UMC::Status VC1EncoderBitStreamAdv::PutBits(Ipp32u val,Ipp32s len)
 {
    Ipp32s tmpcnt;

    assert(m_pBitStream!=NULL);
    assert(len<=32);

    if ((Ipp8u*)m_pBitStream + (len + m_iOffset)/8 >= (Ipp8u*)m_pBufferStart + m_iBufferLen - 1)
        return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;

    val = val & mask[len];
    tmpcnt = (m_iOffset) - (len);

    while (tmpcnt <= 0)
    {
      Ipp32s i=-1;
      Ipp8u  n_bytes  = 0;
      Ipp32u r_tmp = 0;
      Ipp32u tmp = 0;

      r_tmp = (m_pBitStream)[0] | ((val) >> (-tmpcnt));
      tmp = r_tmp;

      len = len -  m_iOffset;
      i = 0;
      while ((i = CheckCode(tmp | maskUpper[i]))>=0)
      {
         n_bytes ++;
         tmp             = (tmp & maskUpper[i]) | (0x03 <<((3-i)*8))| ((tmp & maskLower[i])>>8);
      }
      m_pBitStream[0]   =  BSWAP(tmp);
      m_pBitStream ++;

      m_iOffset         =  32 - n_bytes*8;
      m_pBitStream[0]   =  (r_tmp & maskL[n_bytes])<< m_iOffset;

      val = val & mask[len];
      tmpcnt = (m_iOffset) - (len);
    }
    if (len>0)
    {
       assert (tmpcnt>=0);
      (m_pBitStream)[0] |= (val) << tmpcnt;
       m_iOffset = tmpcnt;
    }
    return UMC::UMC_OK;
}
 UMC::Status VC1EncoderBitStreamAdv::PutStartCode(Ipp32u val, Ipp32s len)
 {
   Ipp32s tmpcnt;
   Ipp32u r_tmp;

   assert(m_pBitStream!=NULL);
   assert(len<=32);

    if ((Ipp8u*)m_pBitStream + (len + m_iOffset)/8 >= (Ipp8u*)m_pBufferStart + m_iBufferLen - 1)
        return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;

    val = val & mask[len];
    tmpcnt = (m_iOffset) - (len);

    if(tmpcnt <= 0)
    {
      Ipp32u z=0;
      r_tmp = (m_pBitStream)[0] | ((val) >> (-tmpcnt));
      (m_pBitStream)[0] = BSWAP(r_tmp);
      (m_pBitStream)++;
      z = (tmpcnt<0)? (val << (32 + tmpcnt)):z;
      (m_pBitStream)[0] = z ;
      (m_iOffset) = 32 + tmpcnt;
    }
    else
    {
      (m_pBitStream)[0] |= (val) << tmpcnt;
      m_iOffset = tmpcnt;
    }
    m_bLast = false;
    ResetCodeStatus();
    return UMC::UMC_OK;
}
Ipp32s       VC1EncoderBitStreamAdv::CheckCode(Ipp32u code)
{
    Ipp32s i;

    for (i=0;i<4;i++)
    {
        Ipp8u nextByte = ((code >>((3-i)*8))&0xFF);
        if (nextByte>3)
        {
            m_uiCodeStatus = 0;
        }
        else
        {
            if (m_uiCodeStatus <2)
            {
                m_uiCodeStatus = (nextByte == 0)?  m_uiCodeStatus + 1 : 0;
            }
            else
            {
                m_uiCodeStatus = 0;
                return i;
            }
        }
    }
    return -1;
}

 UMC::Status  VC1EncoderBitStreamSM::MakeBlankSegment(Ipp32s len)
 {
    if (m_iOffset != 32 || m_pBlankSegment)
         return UMC::UMC_ERR_NOT_IMPLEMENTED;

    if ((Ipp8u*)(m_pBitStream + len) >= (Ipp8u*)m_pBufferStart + m_iBufferLen - 1)
        return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;

    m_pBlankSegment    = m_pBitStream;
    m_iBlankSegmentLen = len;
    m_pBitStream      += len;

    m_pBitStream[0]=0;
    return UMC::UMC_OK;

 }
 UMC::Status  VC1EncoderBitStreamSM::FillBlankSegment(Ipp32u value)
 {
     if (!m_pBlankSegment || !m_iBlankSegmentLen)
         return UMC::UMC_ERR_NOT_IMPLEMENTED;

     *m_pBlankSegment = BNOSWAP(value);
     m_pBlankSegment++;
     m_iBlankSegmentLen--;

     return UMC::UMC_OK;
 }
void VC1EncoderBitStreamSM::DeleteBlankSegment()
{
    m_pBlankSegment     = 0;
    m_iBlankSegmentLen  = 0;
}
}

#endif // defined (UMC_ENABLE_VC1_VIDEO_ENCODER)

⌨️ 快捷键说明

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