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;
}

 

 

 

 

 

發佈了246 篇原創文章 · 獲贊 80 · 訪問量 93萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章