代码拉取完成,页面将自动刷新
class BaseParser {
constructor(body, curByte = 0, curIndex = 1) {
// 读取到当前字节数
this.curByte = curByte;
// 读取字节的位置
this.curIndex = curIndex;
// uint8array => h264 unit info
this.body = body;
}
/**
* leadingzerobits:1前面的0个数
* read_bits:读取1后面leadingzerobits位
* codeNum = 2^leadingzerobits − 1 + read_bits( leadingZeroBits )
* @returns code_num
*/
readUV() {
let leadingzerobits = 0,
biteVal = 0;
while (!biteVal) {
biteVal = readBit(this.body[this.curByte], this.curIndex);
if (biteVal === 0) {
leadingzerobits++;
}
if (this.curIndex === 8) {
this.curIndex = 1;
this.curByte++;
} else {
this.curIndex++;
}
}
let code_num = "";
for (let index = 0; index < leadingzerobits; index++) {
code_num += readBit(this.body[this.curByte], this.curIndex);
if (this.curIndex === 8) {
this.curIndex = 1;
this.curByte++;
} else {
this.curIndex++;
}
}
return 2 ** leadingzerobits - 1 + parseInt(code_num, 2);
}
/**
* 第一步,通过bs_read_ue(),获取codeNum的值。
* 第二步:根据codeNum的奇偶性,计算出se(v)编码前的值
* codeNum & 0x01: 如果为奇数,codeNum = (codeNum + 1)/2
* : 如果为偶数,codeNum = -(codeNum/2)
* @returns code_num
*/
readSE() {
const code_num = this.readUV(this.body);
const isOdd = code_num % 2 === 1;
return isOdd ? (code_num + 1) / 2 : -(code_num / 2);
}
/**
* 读取指定位数的数据
* @param {number} len
*/
readBits(len) {
const code_num = "";
for (let index = 0; index < len; index++) {
code_num += readBit(this.body[this.curByte], this.curIndex);
if (this.curIndex === 8) {
this.curIndex = 1;
this.curByte++;
} else {
this.curIndex++;
}
}
return parseInt(code_num, 2);
}
}
class Sps extends BaseParser {
constructor(body) {
super(body);
this.profile_idc = this.readBits(8);
for (let index = 0; index < 6; index++) {
this[`constraint_set${index}_flag`] = this.readBits(1);
}
this.reserved_zero_2bits = this.readBits(2);
this.level_idc = this.readBits(8);
this.seq_parameter_set_id = this.readUV();
this.log2_max_frame_num_minus4 = this.readUV();
this.pic_order_cnt_type = this.readUV();
if (this.pic_order_cnt_type === 0) {
this.log2_max_pic_order_cnt_lsb_minus4 = readUV();
} else if (this.pic_order_cnt_type === 1) {
this.delta_pic_order_always_zero_flag = this.readBits(1);
this.offset_for_non_ref_pic = this.readSE();
this.offset_for_top_to_bottom_field = this.readSE();
this.num_ref_frames_in_pic_order_cnt_cycle = this.readUV();
this.offset_for_ref_frame = [];
for (let index = 0; index < this.num_ref_frames_in_pic_order_cnt_cycle; index++) {
this.offset_for_ref_frame.push(this.readSE());
}
this.max_num_ref_frames = this.readUV();
this.gaps_in_frame_num_value_allowed_flag = this.readBits(1);
this.pic_width_in_mbs_minus1 = this.readUV();
this.pic_height_in_map_units_minus1 = this.readUV();
this.frame_mbs_only_flag = this.readBits(1);
if (!this.frame_mbs_only_flag) {
this.mb_adaptive_frame_field_flag = this.readBits(1);
}
this.direct_8x8_inference_flag = this.readBits(1);
this.frame_cropping_flag = this.readBits(1);
if (this.frame_cropping_flag) {
this.frame_crop_left_offset = this.readUV();
this.frame_crop_right_offset = this.readUV();
this.frame_crop_top_offset = this.readUV();
this.frame_crop_bottom_offset = this.readUV();
}
this.vui_parameters_present_flag = this.readBits(1);
}
}
}
class Pps extends BaseParser {
constructor(body) {
super(body);
this.pic_parameter_set_id = this.readUV();
this.seq_parameter_set_id = this.readUV();
this.entropy_coding_mode_flag = this.readBits(1);
this.num_slice_groups_minus1 = this.readUV();
if (this.num_slice_groups_minus1 > 0) {
this.slice_group_map_type = this.readUV();
if (this.slice_group_map_type == 0) {
this.run_length_minus1 = [];
for (let index = 0; index < this.num_slice_groups_minus1; index++) {
this.run_length_minus1.push(this.readUV());
}
} else if (this.slice_group_map_type == 2) {
this.top_left = [];
this.bottom_right = [];
for (let index = 0; index < this.num_slice_groups_minus1; index++) {
this.top_left.push(this.readUV());
this.bottom_right.push(this.readUV());
}
} else if (this.slice_group_map_type === 3 || this.slice_group_map_type === 4 || this.slice_group_map_type === 5) {
this.slice_group_change_direction_flag = this.readBits(1);
this.slice_group_change_rate_minus1 = this.readUV();
} else if (this.slice_group_map_type == 6) {
this.pic_size_in_map_units_minus1 = this.readUV();
this.slice_group_id = [];
for (let index = 0; index < this.pic_size_in_map_units_minus1; index++) {
this.slice_group_id.push(this.readUV());
}
}
}
this.num_ref_idx_10_default_active_minus1 = this.readUV();
this.num_ref_idx_11_default_active_minus1 = this.readUV();
this.weighted_pred_flag = this.readBits(1);
this.weighted_bipred_idc = this.readBits(2);
this.pic_init_qp_minus26 = this.readSE();
this.pic_init_qs_minus26 = this.readSE();
this.chroma_qp_index_offset = this.readSE();
this.deblocking_filter_control_present_flag = this.readBits(1);
this.constrained_intra_pred_flag = this.readBits(1);
this.redundant_pic_present_flag = this.readBits(1);
// if (more_rbsp_data())
}
}
/**
* 读取指定位置的值
* @param {*} val
* @param {*} index
* @param {*} direction
* @returns
*/
function readBit(val, index, direction = "ltr") {
if (direction === "rtl") {
return (val >> (index - 1)) & 0x01;
} else if (direction === "ltr") {
return (val >> (8 - index)) & 0x01;
}
}
export function SpsParser(body) {
return new Sps(body);
}
export function PpsParser(body) {
return new Pps(body);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。