依次介绍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;
}