h264-pps-parser
Version:
Parse H.264 PPS NAL units
147 lines (146 loc) • 5.74 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = void 0;
const h264_sps_parser_1 = require("h264-sps-parser");
function scaling_list(stream, sizeOfScalingList, use_default, i) {
let lastScale = 8;
let nextScale = 8;
const scalingList = [];
for (let j = 0; j < sizeOfScalingList; j++) {
if (nextScale !== 0) {
const deltaScale = stream.SignedExpGolomb();
nextScale = (lastScale + deltaScale + 256) % 256;
use_default[i] = +(j === 0 && nextScale === 0);
}
if (nextScale) {
lastScale = nextScale;
}
scalingList[j] = lastScale;
}
return scalingList;
}
function parse(nalu, spss) {
if ((nalu[0] & 0x1F) !== 8)
throw new Error("Not a PPS unit");
const stream = new h264_sps_parser_1.Bitstream(new DataView(nalu.buffer, nalu.byteOffset + 1));
const pps_id = stream.ExpGolomb();
const sps_id = stream.ExpGolomb();
const entropy_coding_mode_flag = stream.readBit();
const bottom_field_pic_order_in_frame_present_flag = stream.readBit();
const num_slice_groups = stream.ExpGolomb() + 1;
let slice_group_map_type = 0;
let slice_group_change_direction_flag = 0;
let slice_group_change_rate = 0;
let pic_size_in_map_units = 0;
const run_length = [];
const top_left = [];
const bottom_right = [];
const slice_group_id = [];
if (num_slice_groups > 1) {
slice_group_map_type = stream.ExpGolomb();
switch (slice_group_map_type) {
case 0: {
for (let i = 0; i < num_slice_groups; i++) {
run_length[i] = stream.ExpGolomb() + 1;
}
break;
}
case 2: {
for (let i = 0; i < num_slice_groups; i++) {
top_left[i] = stream.ExpGolomb();
bottom_right[i] = stream.ExpGolomb();
}
break;
}
case 3:
case 4:
case 5: {
slice_group_change_direction_flag = stream.readBit();
slice_group_change_rate = stream.ExpGolomb() + 1;
break;
}
case 6: {
pic_size_in_map_units = stream.ExpGolomb() + 1;
for (let i = 0; i < pic_size_in_map_units; i++) {
slice_group_id[i] = stream.ExpGolomb();
}
}
}
}
const num_refs_idx_10_default_active = stream.ExpGolomb();
const num_refs_idx_11_default_active = stream.ExpGolomb();
const weighted_pred_flag = stream.readBit();
const weighted_bipred_idc = (stream.readBit() << 1) | stream.readBit();
const pic_init_qp = stream.SignedExpGolomb() + 26;
const pic_init_qs = stream.SignedExpGolomb() + 26;
const chroma_qp_index_offset = stream.SignedExpGolomb();
const deblocking_filter_control_present_flag = stream.readBit();
const constrained_intra_pred_flag = stream.readBit();
const redundant_pic_cnt_present_flag = stream.readBit();
let transform_8x8_mode_flag = 0;
let pic_scaling_matrix_present_flag = 0;
let second_chroma_qp_index_offset = 0;
const pic_scaling_list_present_flag = [];
const scaling_list_4x4 = [];
const scaling_list_8x8 = [];
const use_default_scaling_matrix_4x4_flag = [];
const use_default_scaling_matrix_8x8_flag = [];
if (stream.more_rbsp_data()) {
transform_8x8_mode_flag = stream.readBit();
pic_scaling_matrix_present_flag = stream.readBit();
if (pic_scaling_matrix_present_flag) {
for (let i = 0; i < 6; i++) {
const f = stream.readBit();
pic_scaling_list_present_flag[i] = f;
if (f) {
scaling_list_4x4.push(scaling_list(stream, 16, use_default_scaling_matrix_4x4_flag, i));
}
}
if (transform_8x8_mode_flag) {
const { chroma_format_idc } = spss.get(sps_id);
const limit = chroma_format_idc === 3 ? 6 : 2;
for (let i = 0; i < limit; i++) {
const f = stream.readBit();
pic_scaling_list_present_flag[i + 6] = f;
if (f) {
scaling_list_8x8.push(scaling_list(stream, 64, use_default_scaling_matrix_8x8_flag, i));
}
}
}
}
second_chroma_qp_index_offset = stream.SignedExpGolomb();
}
return {
pps_id, sps_id,
entropy_coding_mode_flag,
bottom_field_pic_order_in_frame_present_flag,
num_slice_groups,
slice_group_map_type,
run_length,
top_left,
bottom_right,
slice_group_change_direction_flag,
slice_group_change_rate,
pic_size_in_map_units,
slice_group_id,
num_refs_idx_10_default_active,
num_refs_idx_11_default_active,
weighted_pred_flag,
weighted_bipred_idc,
pic_init_qp,
pic_init_qs,
chroma_qp_index_offset,
deblocking_filter_control_present_flag,
constrained_intra_pred_flag,
redundant_pic_cnt_present_flag,
transform_8x8_mode_flag,
pic_scaling_matrix_present_flag,
pic_scaling_list_present_flag,
scaling_list_4x4,
scaling_list_8x8,
use_default_scaling_matrix_4x4_flag,
use_default_scaling_matrix_8x8_flag,
second_chroma_qp_index_offset,
};
}
exports.parse = parse;