语法解析
u(n)
n代表读取的bit数
含义:读取n位无符号整数
ue(v)
v代表可变长的含义
含义:一直向后读取,直到读取到1结束,记录0的个数leadingZeroBits,然后向后读取leadingZeroBits位,作为一个无符号整数value
最后返回值为(1 << leadingZeroBits - 1 + value)
例子:
原始序列(二进制) 0 0 1 0 1
读取leadingZeroBits为2
向后再读2位,value为1
最后返回值 1 << 2 - 1 + 1 = 4
语法结构
注意点
为了防止NAL Unit内部出现与起始码 0x000001 或 0x00000001 相同的字节序列,H.265规定,在生成NAL Unit负载时,如果出现 0x000003 这样的序列(即两个连续的0x00字节后跟着一个0x01, 0x02 或 0x03),就必须在第三个字节前插入一个 0x03。
具体规则:
0x000000 -> 0x00000300
0x000001 -> 0x00000301
0x000002 -> 0x00000302
0x000003 -> 0x00000303
H265
SPS语法结构


示例
JS读取哥伦布指数的代码
// 实现代码
class BitReader {
constructor(data) {
this.data = data;
this.bitPosition = 0;
this.bytePosition = 0;
this.currentByte = 0;
}
skipSplitByte() {
if(this.bytePosition < 3){
return;
}
if(this.data[this.bytePosition - 2] === 0x00 && this.data[this.bytePosition - 1] === 0x00 && this.data[this.bytePosition] === 0x03){
this.bytePosition++;
this.bitPosition = 0;
}
}
readU(n) {
let value = 0;
for (let i = 0; i < n; i++) {
if (this.bitPosition === 0) {
this.skipSplitByte();
this.currentByte = this.data[this.bytePosition++] || 0;
}
value = (value << 1) | ((this.currentByte >> (7 - this.bitPosition)) & 1);
this.bitPosition = (this.bitPosition + 1) % 8;
}
return value;
}
readUE() {
let leadingZeroBits = 0;
while (this.readU(1) === 0) {
leadingZeroBits++;
}
if (leadingZeroBits === 0) {
return 0;
}
const value = this.readU(leadingZeroBits);
return (1 << leadingZeroBits) - 1 + value;
}
readSE() {
const value = this.readUE();
if (value === 0) {
return 0;
}
return (value % 2 === 1) ? (value + 1) / 2 : -(value / 2);
}
getPosition() {
console.log("bytePosition:", this.bytePosition, 'bitPosition:', this.bitPosition);
return this.bytePosition - (this.bitPosition > 0 ? 1 : 0);
}
isEnd() {
return this.bytePosition >= this.data.length && this.bitPosition === 0;
}
}
评论已关闭