openh264--基础库

依次介绍bit数组

bit数组

/*
 *  Bit-stream auxiliary reading / writing
 */
typedef struct TagBitStringAux {
  uint8_t* pStartBuf;   // buffer to start position
  uint8_t* pEndBuf;     // buffer + length
  int32_t  iBits;       // count bits of overall bitstreaming input

  intX_t   iIndex;      //only for cavlc usage
  uint8_t* pCurBuf;     // current reading position
  uint32_t uiCurBits;
  int32_t  iLeftBits;   // count number of available bits left ([1, 8]),
  // need pointer to next byte start position in case 0 bit left then 8 instead
} SBitStringAux, *PBitStringAux;

#define WRITE_BE_32(ptr, val) do { \
        (ptr)[0] = (val) >> 24; \
        (ptr)[1] = (val) >> 16; \
        (ptr)[2] = (val) >>  8; \
        (ptr)[3] = (val) >>  0; \
    } while (0)

InitBits 初始化,准备一块内存。

static inline int32_t InitBits (SBitStringAux* pBs, const uint8_t* kpBuf, const int32_t kiSize) {
  uint8_t* ptr = (uint8_t*)kpBuf;

  pBs->pStartBuf = ptr;  //开始指针
  pBs->pCurBuf   = ptr;  //当前指针
  pBs->pEndBuf   = ptr + kiSize;  //结束指针
  pBs->iLeftBits = 32;   //可存储32个字节
  pBs->uiCurBits = 0;  //当前数值

  return kiSize;
}

BsWriteBits 写入iLen长的值kuiValue

static inline int32_t BsWriteBits (PBitStringAux pBitString, int32_t iLen, const uint32_t kuiValue) {
  if (iLen < pBitString->iLeftBits) {
    pBitString->uiCurBits = (pBitString->uiCurBits << iLen) | kuiValue;   //直接写入
    pBitString->iLeftBits -= iLen;
  } else {
    iLen -= pBitString->iLeftBits;
    pBitString->uiCurBits = (pBitString->uiCurBits << pBitString->iLeftBits) | (kuiValue >> iLen);

    //剩余空间不足,只能先写iLeftBits个值到uiCurBits ,接着把32个bit放到pCurBuf中,然后再写未写入的值。
    WRITE_BE_32 (pBitString->pCurBuf, pBitString->uiCurBits);
    pBitString->pCurBuf += 4;
    pBitString->uiCurBits = kuiValue & ((1 << iLen) - 1);
    pBitString->iLeftBits = 32 - iLen;

   接着写剩下的值到uiCurBits 。

  }
  return 0;
}

BsWriteOneBit:写入一个Bit。

static inline int32_t BsWriteOneBit (PBitStringAux pBitString, const uint32_t kuiValue) {
  BsWriteBits (pBitString, 1, kuiValue);
  return 0;
}

BsFlush:对32位剩下的BIT填0,凑够32位,然后写入pCurBuf,uiCurBits改为0, iLeftBits改为32。

static inline int32_t BsFlush (PBitStringAux pBitString) {
  WRITE_BE_32 (pBitString->pCurBuf, pBitString->uiCurBits << pBitString->iLeftBits);
  pBitString->pCurBuf += 4 - pBitString->iLeftBits / 8;
  pBitString->iLeftBits = 32;
  pBitString->uiCurBits = 0;
  return 0;
}

K=0的UE编码,对于 k =0时:CodeNum=3。编码如下:
二进制表示为11,去掉k=0位后加1得100;
所以M=2;所以编码后结果为[MZeros][1][Info] = [MZeros][1 Info] = 00100

/*
 *  Write unsigned exp golomb codes
 */

static inline int32_t BsWriteUE (PBitStringAux pBitString, const uint32_t kuiValue) {
  uint32_t iTmpValue = kuiValue + 1;
  if (256 > kuiValue) {
    BsWriteBits (pBitString, g_kuiGolombUELength[kuiValue], kuiValue + 1);
  } else {
    uint32_t n = 0;
    if (iTmpValue & 0xffff0000) {
      iTmpValue >>= 16;
      n += 16;
    }
    if (iTmpValue & 0xff00) {
      iTmpValue >>= 8;
      n += 8;
    }

    //n += (g_kuiGolombUELength[iTmpValue] >> 1);

    n += (g_kuiGolombUELength[iTmpValue - 1] >> 1);
    BsWriteBits (pBitString, (n << 1) + 1, kuiValue + 1);
  }
  return 0;
}

K=0的SE编码

/*
 *  Write signed exp golomb codes
 */
static inline int32_t BsWriteSE (PBitStringAux pBitString, const int32_t kiValue) {
  uint32_t iTmpValue;
  if (0 == kiValue) {
    BsWriteOneBit (pBitString, 1);
  } else if (0 < kiValue) {
    iTmpValue = (kiValue << 1) - 1;
    BsWriteUE (pBitString, iTmpValue);
  } else {
    iTmpValue = ((-kiValue) << 1);
    BsWriteUE (pBitString, iTmpValue);
  }
  return 0;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山西茄子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值