mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-28 13:04:07 +08:00
替换SPS解析器实现以改进H264和H265视频参数提取
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
#include "H264.h"
|
||||
#include "H264Rtmp.h"
|
||||
#include "H264Rtp.h"
|
||||
#include "SPSParser.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Util/base64.h"
|
||||
#include "Common/Parser.h"
|
||||
@@ -22,28 +21,194 @@
|
||||
#include "mpeg4-avc.h"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
static bool getAVCInfo(const char *sps, size_t sps_len, int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
||||
if (sps_len < 4) {
|
||||
// ---- 内部比特流工具 ----
|
||||
namespace {
|
||||
|
||||
// 去除 RBSP 防竞争字节 (0x00 0x00 0x03 -> 0x00 0x00)
|
||||
static std::vector<uint8_t> rbsp_from_nalu(const uint8_t *data, size_t size) {
|
||||
std::vector<uint8_t> out;
|
||||
out.reserve(size);
|
||||
for (size_t i = 0; i < size; ) {
|
||||
if (i + 2 < size && data[i] == 0x00 && data[i+1] == 0x00 && data[i+2] == 0x03) {
|
||||
out.push_back(0x00);
|
||||
out.push_back(0x00);
|
||||
i += 3;
|
||||
} else {
|
||||
out.push_back(data[i++]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct BitStream {
|
||||
const uint8_t *buf;
|
||||
size_t size; // bytes
|
||||
size_t pos; // bit position
|
||||
|
||||
BitStream(const uint8_t *b, size_t s) : buf(b), size(s), pos(0) {}
|
||||
|
||||
bool eof() const { return pos >= size * 8; }
|
||||
|
||||
size_t bits_left() const { return size * 8 - pos; }
|
||||
|
||||
uint32_t read_bits(int n) {
|
||||
if (n < 0 || n > 32 || (size_t)n > bits_left()) {
|
||||
throw std::runtime_error("eof");
|
||||
}
|
||||
uint32_t val = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
val = (val << 1) | ((buf[pos / 8] >> (7 - pos % 8)) & 1);
|
||||
pos++;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void skip_bits(int n) {
|
||||
if (n < 0 || (size_t)n > bits_left()) {
|
||||
throw std::runtime_error("eof");
|
||||
}
|
||||
pos += n;
|
||||
}
|
||||
|
||||
uint32_t read_ue() { // Exp-Golomb unsigned
|
||||
int zeros = 0;
|
||||
while (!eof() && read_bits(1) == 0) zeros++;
|
||||
if (zeros == 0) return 0;
|
||||
if (zeros >= 32) throw std::runtime_error("exp-golomb overflow");
|
||||
return (1u << zeros) - 1 + read_bits(zeros);
|
||||
}
|
||||
|
||||
int32_t read_se() { // Exp-Golomb signed
|
||||
uint32_t v = read_ue();
|
||||
return (v & 1) ? (int32_t)((v + 1) >> 1) : -(int32_t)(v >> 1);
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ---- H264 SPS 解析 ----
|
||||
static bool getAVCInfo(const char *sps_raw, size_t sps_len, int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
||||
if (sps_len < 4) return false;
|
||||
// sps_raw[0] 是 NAL header,从第 1 字节开始是 RBSP
|
||||
auto rbsp = rbsp_from_nalu((const uint8_t *)sps_raw + 1, sps_len - 1);
|
||||
if (rbsp.size() < 3) return false;
|
||||
|
||||
try {
|
||||
BitStream bs(rbsp.data(), rbsp.size());
|
||||
|
||||
uint8_t profile_idc = (uint8_t)bs.read_bits(8); // profile_idc
|
||||
bs.skip_bits(8); // constraint flags + reserved
|
||||
bs.skip_bits(8); // level_idc
|
||||
bs.read_ue(); // seq_parameter_set_id
|
||||
|
||||
uint32_t chroma_format_idc = 1;
|
||||
if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
|
||||
profile_idc == 244 || profile_idc == 44 || profile_idc == 83 ||
|
||||
profile_idc == 86 || profile_idc == 118 || profile_idc == 128) {
|
||||
chroma_format_idc = bs.read_ue();
|
||||
if (chroma_format_idc > 3) {
|
||||
return false;
|
||||
}
|
||||
T_GetBitContext tGetBitBuf;
|
||||
T_SPS tH264SpsInfo;
|
||||
memset(&tGetBitBuf, 0, sizeof(tGetBitBuf));
|
||||
memset(&tH264SpsInfo, 0, sizeof(tH264SpsInfo));
|
||||
tGetBitBuf.pu8Buf = (uint8_t *)sps + 1;
|
||||
tGetBitBuf.iBufSize = (int)(sps_len - 1);
|
||||
if (0 != h264DecSeqParameterSet((void *)&tGetBitBuf, &tH264SpsInfo)) {
|
||||
return false;
|
||||
if (chroma_format_idc == 3) bs.skip_bits(1); // separate_colour_plane_flag
|
||||
bs.read_ue(); // bit_depth_luma_minus8
|
||||
bs.read_ue(); // bit_depth_chroma_minus8
|
||||
bs.skip_bits(1); // qpprime_y_zero_transform_bypass_flag
|
||||
if (bs.read_bits(1)) { // seq_scaling_matrix_present_flag
|
||||
int cnt = (chroma_format_idc != 3) ? 8 : 12;
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (bs.read_bits(1)) { // seq_scaling_list_present_flag
|
||||
int sz = (i < 6) ? 16 : 64;
|
||||
int last = 8, next = 8;
|
||||
for (int j = 0; j < sz; j++) {
|
||||
if (next != 0) next = (last + bs.read_se() + 256) % 256;
|
||||
last = (next == 0) ? last : next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs.read_ue(); // log2_max_frame_num_minus4
|
||||
uint32_t pic_order_cnt_type = bs.read_ue();
|
||||
if (pic_order_cnt_type == 0) {
|
||||
bs.read_ue(); // log2_max_pic_order_cnt_lsb_minus4
|
||||
} else if (pic_order_cnt_type == 1) {
|
||||
bs.skip_bits(1); // delta_pic_order_always_zero_flag
|
||||
bs.read_se(); // offset_for_non_ref_pic
|
||||
bs.read_se(); // offset_for_top_to_bottom_field
|
||||
uint32_t n = bs.read_ue();
|
||||
for (uint32_t i = 0; i < n; i++) bs.read_se();
|
||||
}
|
||||
bs.read_ue(); // max_num_ref_frames
|
||||
bs.skip_bits(1); // gaps_in_frame_num_value_allowed_flag
|
||||
|
||||
uint32_t pic_width_in_mbs_minus1 = bs.read_ue();
|
||||
uint32_t pic_height_in_map_units_minus1 = bs.read_ue();
|
||||
uint32_t frame_mbs_only_flag = bs.read_bits(1);
|
||||
if (!frame_mbs_only_flag) bs.skip_bits(1); // mb_adaptive_frame_field_flag
|
||||
bs.skip_bits(1); // direct_8x8_inference_flag
|
||||
|
||||
uint32_t crop_left = 0, crop_right = 0, crop_top = 0, crop_bottom = 0;
|
||||
if (bs.read_bits(1)) { // frame_cropping_flag
|
||||
crop_left = bs.read_ue();
|
||||
crop_right = bs.read_ue();
|
||||
crop_top = bs.read_ue();
|
||||
crop_bottom = bs.read_ue();
|
||||
}
|
||||
|
||||
uint32_t crop_unit_x = 1;
|
||||
uint32_t crop_unit_y = 2 - frame_mbs_only_flag;
|
||||
if (chroma_format_idc == 1) {
|
||||
crop_unit_x = 2;
|
||||
crop_unit_y = 2 * (2 - frame_mbs_only_flag);
|
||||
} else if (chroma_format_idc == 2) {
|
||||
crop_unit_x = 2;
|
||||
crop_unit_y = 2 - frame_mbs_only_flag;
|
||||
}
|
||||
|
||||
uint64_t raw_width = (uint64_t)(pic_width_in_mbs_minus1 + 1) * 16;
|
||||
uint64_t raw_height = (uint64_t)(pic_height_in_map_units_minus1 + 1) * 16 * (2 - frame_mbs_only_flag);
|
||||
uint64_t crop_w = ((uint64_t)crop_left + crop_right) * crop_unit_x;
|
||||
uint64_t crop_h = ((uint64_t)crop_top + crop_bottom) * crop_unit_y;
|
||||
if (crop_w >= raw_width || crop_h >= raw_height) return false;
|
||||
iVideoWidth = (int)(raw_width - crop_w);
|
||||
iVideoHeight = (int)(raw_height - crop_h);
|
||||
|
||||
iVideoFps = 0.0f;
|
||||
if (bs.read_bits(1)) { // vui_parameters_present_flag
|
||||
if (bs.read_bits(1)) { // aspect_ratio_info_present_flag
|
||||
uint32_t ar = bs.read_bits(8);
|
||||
if (ar == 255) bs.skip_bits(32); // sar width+height
|
||||
}
|
||||
if (bs.read_bits(1)) bs.skip_bits(1); // overscan
|
||||
if (bs.read_bits(1)) { // video_signal_type_present_flag
|
||||
bs.skip_bits(3 + 1); // video_format + video_full_range_flag
|
||||
if (bs.read_bits(1)) bs.skip_bits(24); // colour_description_present_flag
|
||||
}
|
||||
if (bs.read_bits(1)) { // chroma_loc_info_present_flag
|
||||
bs.read_ue(); bs.read_ue();
|
||||
}
|
||||
if (bs.read_bits(1)) { // timing_info_present_flag
|
||||
uint32_t num_units_in_tick = bs.read_bits(32);
|
||||
uint32_t time_scale = bs.read_bits(32);
|
||||
bs.skip_bits(1); // fixed_frame_rate_flag
|
||||
if (num_units_in_tick > 0) {
|
||||
iVideoFps = (float)time_scale / (2.0f * (float)num_units_in_tick);
|
||||
}
|
||||
}
|
||||
}
|
||||
return iVideoWidth > 0 && iVideoHeight > 0;
|
||||
} catch (...) {
|
||||
return iVideoWidth > 0 && iVideoHeight > 0;
|
||||
}
|
||||
h264GetWidthHeight(&tH264SpsInfo, &iVideoWidth, &iVideoHeight);
|
||||
h264GeFramerate(&tH264SpsInfo, &iVideoFps);
|
||||
// ErrorL << iVideoWidth << " " << iVideoHeight << " " << iVideoFps;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getAVCInfo(const string &strSps, int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
#include "H265.h"
|
||||
#include "H265Rtp.h"
|
||||
#include "H265Rtmp.h"
|
||||
#include "SPSParser.h"
|
||||
#include "Util/base64.h"
|
||||
#include "Common/Parser.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef ENABLE_MP4
|
||||
#include "mpeg4-hevc.h"
|
||||
#endif
|
||||
@@ -25,35 +27,283 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
bool getHEVCInfo(const char * vps, size_t vps_len,const char * sps,size_t sps_len,int &iVideoWidth, int &iVideoHeight, float &iVideoFps){
|
||||
T_GetBitContext tGetBitBuf;
|
||||
T_HEVCSPS tH265SpsInfo;
|
||||
T_HEVCVPS tH265VpsInfo;
|
||||
if ( vps_len > 2 ){
|
||||
memset(&tGetBitBuf,0,sizeof(tGetBitBuf));
|
||||
memset(&tH265VpsInfo,0,sizeof(tH265VpsInfo));
|
||||
tGetBitBuf.pu8Buf = (uint8_t*)vps+2;
|
||||
tGetBitBuf.iBufSize = (int)(vps_len-2);
|
||||
if(0 != h265DecVideoParameterSet((void *) &tGetBitBuf, &tH265VpsInfo)){
|
||||
// ---- 内部比特流工具(H265) ----
|
||||
namespace {
|
||||
|
||||
static std::vector<uint8_t> h265_rbsp_from_nalu(const uint8_t *data, size_t size) {
|
||||
std::vector<uint8_t> out;
|
||||
out.reserve(size);
|
||||
for (size_t i = 0; i < size; ) {
|
||||
if (i + 2 < size && data[i] == 0x00 && data[i+1] == 0x00 && data[i+2] == 0x03) {
|
||||
out.push_back(0x00);
|
||||
out.push_back(0x00);
|
||||
i += 3;
|
||||
} else {
|
||||
out.push_back(data[i++]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct H265BS {
|
||||
const uint8_t *buf;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
H265BS(const uint8_t *b, size_t s) : buf(b), size(s), pos(0) {}
|
||||
bool eof() const { return pos >= size * 8; }
|
||||
size_t bits_left() const { return size * 8 - pos; }
|
||||
uint32_t read_bits(int n) {
|
||||
if (n < 0 || n > 32 || (size_t)n > bits_left()) {
|
||||
throw std::runtime_error("eof");
|
||||
}
|
||||
uint32_t val = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
val = (val << 1) | ((buf[pos / 8] >> (7 - pos % 8)) & 1);
|
||||
pos++;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
void skip_bits(int n) {
|
||||
if (n < 0 || (size_t)n > bits_left()) {
|
||||
throw std::runtime_error("eof");
|
||||
}
|
||||
pos += n;
|
||||
}
|
||||
uint32_t read_ue() {
|
||||
int z = 0;
|
||||
while (!eof() && read_bits(1) == 0) z++;
|
||||
if (z == 0) return 0;
|
||||
if (z >= 32) throw std::runtime_error("exp-golomb overflow");
|
||||
return (1u << z) - 1 + read_bits(z);
|
||||
}
|
||||
int32_t read_se() {
|
||||
uint32_t v = read_ue();
|
||||
return (v & 1) ? (int32_t)((v + 1) >> 1) : -(int32_t)(v >> 1);
|
||||
}
|
||||
// profile_tier_level(profilePresentFlag, maxNumSubLayersMinus1)
|
||||
void skip_profile_tier_level(bool profilePresentFlag, uint32_t maxNumSubLayersMinus1) {
|
||||
if (profilePresentFlag) {
|
||||
skip_bits(2 + 1 + 5); // profile_space + tier_flag + profile_idc
|
||||
skip_bits(32); // profile_compatibility_flag[32]
|
||||
skip_bits(4); // progressive/interlaced/non_packed/frame_only
|
||||
skip_bits(44); // reserved_zero_44bits
|
||||
}
|
||||
skip_bits(8); // general_level_idc
|
||||
// sub_layer flags
|
||||
std::vector<bool> profile_present(maxNumSubLayersMinus1), level_present(maxNumSubLayersMinus1);
|
||||
for (uint32_t i = 0; i < maxNumSubLayersMinus1; i++) {
|
||||
profile_present[i] = read_bits(1) != 0;
|
||||
level_present[i] = read_bits(1) != 0;
|
||||
}
|
||||
if (maxNumSubLayersMinus1 > 0) {
|
||||
for (uint32_t i = maxNumSubLayersMinus1; i < 8; i++) skip_bits(2);
|
||||
}
|
||||
for (uint32_t i = 0; i < maxNumSubLayersMinus1; i++) {
|
||||
if (profile_present[i]) {
|
||||
skip_bits(2 + 1 + 5 + 32 + 4 + 44);
|
||||
}
|
||||
if (level_present[i]) skip_bits(8);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ---- H265 VPS 解析(只提取帧率用的 timing info) ----
|
||||
static bool parse_hevc_vps_fps(const uint8_t *data, size_t size, float &fps) {
|
||||
// data 为 NALU 原始数据(含 NAL header)
|
||||
if (size < 3) return false;
|
||||
auto rbsp = h265_rbsp_from_nalu(data, size);
|
||||
try {
|
||||
H265BS bs(rbsp.data(), rbsp.size());
|
||||
// NALU header: forbidden_zero_bit(1) + nal_unit_type(6) + nuh_layer_id(6) + nuh_temporal_id_plus1(3)
|
||||
bs.skip_bits(16);
|
||||
// vps_video_parameter_set_id(4) + vps_reserved_three_2bits(2) + vps_max_layers_minus1(6)
|
||||
bs.skip_bits(4 + 2 + 6);
|
||||
uint32_t vps_max_sub_layers_minus1 = bs.read_bits(3);
|
||||
bs.skip_bits(1); // vps_temporal_id_nesting_flag
|
||||
bs.skip_bits(16); // vps_reserved_0xffff_16bits
|
||||
bs.skip_profile_tier_level(true, vps_max_sub_layers_minus1);
|
||||
bool vps_sub_layer_ordering_info_present_flag = bs.read_bits(1) != 0;
|
||||
uint32_t start = vps_sub_layer_ordering_info_present_flag ? 0 : vps_max_sub_layers_minus1;
|
||||
for (uint32_t i = start; i <= vps_max_sub_layers_minus1; i++) {
|
||||
bs.read_ue(); // vps_max_dec_pic_buffering_minus1
|
||||
bs.read_ue(); // vps_max_num_reorder_pics
|
||||
bs.read_ue(); // vps_max_latency_increase_plus1
|
||||
}
|
||||
uint32_t vps_max_layer_id = bs.read_bits(6);
|
||||
uint32_t vps_num_layer_sets_minus1 = bs.read_ue();
|
||||
for (uint32_t i = 1; i <= vps_num_layer_sets_minus1; i++) {
|
||||
for (uint32_t j = 0; j <= vps_max_layer_id; j++) bs.skip_bits(1);
|
||||
}
|
||||
if (bs.read_bits(1)) { // vps_timing_info_present_flag
|
||||
uint32_t vps_num_units_in_tick = bs.read_bits(32);
|
||||
uint32_t vps_time_scale = bs.read_bits(32);
|
||||
if (vps_num_units_in_tick > 0) {
|
||||
fps = (float)vps_time_scale / (float)vps_num_units_in_tick;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( sps_len > 2 ){
|
||||
memset(&tGetBitBuf,0,sizeof(tGetBitBuf));
|
||||
memset(&tH265SpsInfo,0,sizeof(tH265SpsInfo));
|
||||
tGetBitBuf.pu8Buf = (uint8_t*)sps+2;
|
||||
tGetBitBuf.iBufSize = (int)(sps_len-2);
|
||||
if(0 != h265DecSeqParameterSet((void *) &tGetBitBuf, &tH265SpsInfo)){
|
||||
// ---- H265 SPS 解析(宽高 + 备用帧率) ----
|
||||
static bool parse_hevc_sps(const uint8_t *data, size_t size,
|
||||
int &width, int &height, float &fps) {
|
||||
if (size < 3) return false;
|
||||
auto rbsp = h265_rbsp_from_nalu(data, size);
|
||||
try {
|
||||
H265BS bs(rbsp.data(), rbsp.size());
|
||||
bs.skip_bits(16); // NALU header
|
||||
bs.skip_bits(4); // sps_video_parameter_set_id
|
||||
uint32_t sps_max_sub_layers_minus1 = bs.read_bits(3);
|
||||
bs.skip_bits(1); // sps_temporal_id_nesting_flag
|
||||
bs.skip_profile_tier_level(true, sps_max_sub_layers_minus1);
|
||||
bs.read_ue(); // sps_seq_parameter_set_id
|
||||
uint32_t chroma_format_idc = bs.read_ue();
|
||||
if (chroma_format_idc > 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (chroma_format_idc == 3) bs.skip_bits(1); // separate_colour_plane_flag
|
||||
uint32_t pic_width = bs.read_ue();
|
||||
uint32_t pic_height = bs.read_ue();
|
||||
|
||||
if (bs.read_bits(1)) { // conformance_window_flag
|
||||
uint32_t sub_width_c = (chroma_format_idc == 1 || chroma_format_idc == 2) ? 2 : 1;
|
||||
uint32_t sub_height_c = (chroma_format_idc == 1) ? 2 : 1;
|
||||
uint32_t crop_left = bs.read_ue() * sub_width_c;
|
||||
uint32_t crop_right = bs.read_ue() * sub_width_c;
|
||||
uint32_t crop_top = bs.read_ue() * sub_height_c;
|
||||
uint32_t crop_bottom = bs.read_ue() * sub_height_c;
|
||||
if (crop_left + crop_right > pic_width || crop_top + crop_bottom > pic_height) {
|
||||
return false;
|
||||
h265GetWidthHeight(&tH265SpsInfo, &iVideoWidth, &iVideoHeight);
|
||||
iVideoFps = 0;
|
||||
h265GeFramerate(&tH265VpsInfo, &tH265SpsInfo, &iVideoFps);
|
||||
return true;
|
||||
}
|
||||
pic_width -= crop_left + crop_right;
|
||||
pic_height -= crop_top + crop_bottom;
|
||||
}
|
||||
|
||||
width = (int)pic_width;
|
||||
height = (int)pic_height;
|
||||
|
||||
bs.read_ue(); // bit_depth_luma_minus8
|
||||
bs.read_ue(); // bit_depth_chroma_minus8
|
||||
uint32_t log2_max_pic_order_cnt_lsb_minus4 = bs.read_ue();
|
||||
|
||||
bool sps_sub_layer_ordering_info_present_flag = bs.read_bits(1) != 0;
|
||||
uint32_t start = sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1;
|
||||
for (uint32_t i = start; i <= sps_max_sub_layers_minus1; i++) {
|
||||
bs.read_ue(); bs.read_ue(); bs.read_ue();
|
||||
}
|
||||
bs.read_ue(); // log2_min_luma_coding_block_size_minus3
|
||||
bs.read_ue(); // log2_diff_max_min_luma_coding_block_size
|
||||
bs.read_ue(); // log2_min_luma_transform_block_size_minus2
|
||||
bs.read_ue(); // log2_diff_max_min_luma_transform_block_size
|
||||
bs.read_ue(); // max_transform_hierarchy_depth_inter
|
||||
bs.read_ue(); // max_transform_hierarchy_depth_intra
|
||||
|
||||
if (bs.read_bits(1)) { // scaling_list_enabled_flag
|
||||
if (bs.read_bits(1)) { // sps_scaling_list_data_present_flag
|
||||
for (int sizeId = 0; sizeId < 4; sizeId++) {
|
||||
for (int matrixId = 0; matrixId < (sizeId == 3 ? 2 : 6); matrixId++) {
|
||||
if (!bs.read_bits(1)) { // scaling_list_pred_mode_flag
|
||||
bs.read_ue(); // scaling_list_pred_matrix_id_delta
|
||||
} else {
|
||||
int coefNum = (std::min)(64, 1 << (4 + (sizeId << 1)));
|
||||
if (sizeId > 1) bs.read_se(); // scaling_list_dc_coef_minus8
|
||||
for (int i = 0; i < coefNum; i++) bs.read_se();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs.skip_bits(2); // amp_enabled_flag + sample_adaptive_offset_enabled_flag
|
||||
if (bs.read_bits(1)) { // pcm_enabled_flag
|
||||
bs.skip_bits(4 + 4); // pcm_sample_bit_depth_luma/chroma_minus1
|
||||
bs.read_ue(); bs.read_ue(); // log2_min/max pcm_luma_coding_block_size
|
||||
bs.skip_bits(1); // pcm_loop_filter_disabled_flag
|
||||
}
|
||||
|
||||
uint32_t num_short_term_ref_pic_sets = bs.read_ue();
|
||||
uint32_t prev_num_delta_pocs = 0;
|
||||
for (uint32_t i = 0; i < num_short_term_ref_pic_sets; i++) {
|
||||
bool inter_ref = (i != 0) && bs.read_bits(1) != 0;
|
||||
if (inter_ref) {
|
||||
bs.skip_bits(1); // delta_rps_sign
|
||||
bs.read_ue(); // abs_delta_rps_minus1
|
||||
uint32_t n = prev_num_delta_pocs + 1;
|
||||
uint32_t cnt = 0;
|
||||
for (uint32_t j = 0; j < n; j++) {
|
||||
bool used = bs.read_bits(1) != 0;
|
||||
bool use = !used && bs.read_bits(1) != 0;
|
||||
if (used || use) cnt++;
|
||||
}
|
||||
prev_num_delta_pocs = cnt;
|
||||
} else {
|
||||
uint32_t num_neg = bs.read_ue();
|
||||
uint32_t num_pos = bs.read_ue();
|
||||
prev_num_delta_pocs = num_neg + num_pos;
|
||||
for (uint32_t j = 0; j < num_neg; j++) { bs.read_ue(); bs.skip_bits(1); }
|
||||
for (uint32_t j = 0; j < num_pos; j++) { bs.read_ue(); bs.skip_bits(1); }
|
||||
}
|
||||
}
|
||||
|
||||
if (bs.read_bits(1)) { // long_term_ref_pics_present_flag
|
||||
uint32_t n = bs.read_ue();
|
||||
uint32_t log2_max = log2_max_pic_order_cnt_lsb_minus4 + 4;
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
bs.skip_bits(log2_max); // lt_ref_pic_poc_lsb_sps
|
||||
bs.skip_bits(1); // used_by_curr_pic_lt_sps_flag
|
||||
}
|
||||
}
|
||||
|
||||
bs.skip_bits(2); // sps_temporal_mvp_enabled_flag + strong_intra_smoothing_enabled_flag
|
||||
|
||||
if (bs.read_bits(1)) { // vui_parameters_present_flag
|
||||
if (bs.read_bits(1)) { // aspect_ratio_info_present_flag
|
||||
if (bs.read_bits(8) == 255) bs.skip_bits(32);
|
||||
}
|
||||
if (bs.read_bits(1)) bs.skip_bits(1); // overscan
|
||||
if (bs.read_bits(1)) { // video_signal_type_present_flag
|
||||
bs.skip_bits(3 + 1);
|
||||
if (bs.read_bits(1)) bs.skip_bits(24);
|
||||
}
|
||||
if (bs.read_bits(1)) { bs.read_ue(); bs.read_ue(); } // chroma_loc_info
|
||||
bs.skip_bits(3); // neutral_chroma/field_seq/frame_field_info
|
||||
if (bs.read_bits(1)) { // default_display_window_flag
|
||||
bs.read_ue(); // def_disp_win_left_offset
|
||||
bs.read_ue(); // def_disp_win_right_offset
|
||||
bs.read_ue(); // def_disp_win_top_offset
|
||||
bs.read_ue(); // def_disp_win_bottom_offset
|
||||
}
|
||||
if (bs.read_bits(1)) { // vui_timing_info_present_flag
|
||||
uint32_t num_units = bs.read_bits(32);
|
||||
uint32_t time_scale = bs.read_bits(32);
|
||||
if (num_units > 0 && fps <= 0.0f) {
|
||||
fps = (float)time_scale / (float)num_units;
|
||||
}
|
||||
}
|
||||
}
|
||||
return width > 0 && height > 0;
|
||||
} catch (...) {
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool getHEVCInfo(const char *vps, size_t vps_len, const char *sps, size_t sps_len,
|
||||
int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
||||
iVideoWidth = 0; iVideoHeight = 0; iVideoFps = 0.0f;
|
||||
|
||||
// 先从 VPS 提取帧率
|
||||
if (vps_len > 2) {
|
||||
parse_hevc_vps_fps((const uint8_t *)vps, vps_len, iVideoFps);
|
||||
}
|
||||
|
||||
// 再从 SPS 提取宽高(如果 VPS 没有帧率,SPS VUI 里也可能有)
|
||||
if (sps_len <= 2) return false;
|
||||
return parse_hevc_sps((const uint8_t *)sps, sps_len, iVideoWidth, iVideoHeight, iVideoFps);
|
||||
}
|
||||
|
||||
bool getHEVCInfo(const string &strVps, const string &strSps, int &iVideoWidth, int &iVideoHeight, float &iVideoFps) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,526 +0,0 @@
|
||||
#ifndef _SPSPARSER_H_
|
||||
#define _SPSPARSER_H_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define QP_MAX_NUM (51 + 6*6) // The maximum supported qp
|
||||
|
||||
#define HEVC_MAX_SHORT_TERM_RPS_COUNT 64
|
||||
|
||||
#define T_PROFILE_HEVC_MAIN 1
|
||||
#define T_PROFILE_HEVC_MAIN_10 2
|
||||
#define T_PROFILE_HEVC_MAIN_STILL_PICTURE 3
|
||||
#define T_PROFILE_HEVC_REXT 4
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Chromaticity coordinates of the source primaries.
|
||||
*/
|
||||
enum T_AVColorPrimaries {
|
||||
AVCOL_PRI_RESERVED0 = 0,
|
||||
AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
|
||||
AVCOL_PRI_UNSPECIFIED = 2,
|
||||
AVCOL_PRI_RESERVED = 3,
|
||||
AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
|
||||
|
||||
AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
|
||||
AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
|
||||
AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above
|
||||
AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C
|
||||
AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020
|
||||
AVCOL_PRI_NB, ///< Not part of ABI
|
||||
};
|
||||
|
||||
/**
|
||||
* Color Transfer Characteristic.
|
||||
*/
|
||||
enum T_AVColorTransferCharacteristic {
|
||||
AVCOL_TRC_RESERVED0 = 0,
|
||||
AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361
|
||||
AVCOL_TRC_UNSPECIFIED = 2,
|
||||
AVCOL_TRC_RESERVED = 3,
|
||||
AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
|
||||
AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG
|
||||
AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
|
||||
AVCOL_TRC_SMPTE240M = 7,
|
||||
AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics"
|
||||
AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)"
|
||||
AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)"
|
||||
AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4
|
||||
AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut
|
||||
AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC)
|
||||
AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system
|
||||
AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system
|
||||
AVCOL_TRC_NB, ///< Not part of ABI
|
||||
};
|
||||
|
||||
/**
|
||||
* YUV tColorspace type.
|
||||
*/
|
||||
enum T_AVColorSpace {
|
||||
AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
|
||||
AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
|
||||
AVCOL_SPC_UNSPECIFIED = 2,
|
||||
AVCOL_SPC_RESERVED = 3,
|
||||
AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
|
||||
AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
|
||||
AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
|
||||
AVCOL_SPC_SMPTE240M = 7,
|
||||
AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
|
||||
AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system
|
||||
AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system
|
||||
AVCOL_SPC_NB, ///< Not part of ABI
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
// 7.4.3.1: vps_max_layers_minus1 is in [0, 62].
|
||||
HEVC_MAX_LAYERS = 63,
|
||||
// 7.4.3.1: vps_max_sub_layers_minus1 is in [0, 6].
|
||||
HEVC_MAX_SUB_LAYERS = 7,
|
||||
// 7.4.3.1: vps_num_layer_sets_minus1 is in [0, 1023].
|
||||
HEVC_MAX_LAYER_SETS = 1024,
|
||||
|
||||
// 7.4.2.1: vps_video_parameter_set_id is u(4).
|
||||
HEVC_MAX_VPS_COUNT = 16,
|
||||
// 7.4.3.2.1: sps_seq_parameter_set_id is in [0, 15].
|
||||
HEVC_MAX_SPS_COUNT = 16,
|
||||
// 7.4.3.3.1: pps_pic_parameter_set_id is in [0, 63].
|
||||
HEVC_MAX_PPS_COUNT = 64,
|
||||
|
||||
// A.4.2: MaxDpbSize is bounded above by 16.
|
||||
HEVC_MAX_DPB_SIZE = 16,
|
||||
// 7.4.3.1: vps_max_dec_pic_buffering_minus1[i] is in [0, MaxDpbSize - 1].
|
||||
HEVC_MAX_REFS = HEVC_MAX_DPB_SIZE,
|
||||
|
||||
// 7.4.3.2.1: num_short_term_ref_pic_sets is in [0, 64].
|
||||
HEVC_MAX_SHORT_TERM_REF_PIC_SETS = 64,
|
||||
// 7.4.3.2.1: num_long_term_ref_pics_sps is in [0, 32].
|
||||
HEVC_MAX_LONG_TERM_REF_PICS = 32,
|
||||
|
||||
// A.3: all profiles require that CtbLog2SizeY is in [4, 6].
|
||||
HEVC_MIN_LOG2_CTB_SIZE = 4,
|
||||
HEVC_MAX_LOG2_CTB_SIZE = 6,
|
||||
|
||||
// E.3.2: cpb_cnt_minus1[i] is in [0, 31].
|
||||
HEVC_MAX_CPB_CNT = 32,
|
||||
|
||||
// A.4.1: in table A.6 the highest level allows a MaxLumaPs of 35 651 584.
|
||||
HEVC_MAX_LUMA_PS = 35651584,
|
||||
// A.4.1: pic_width_in_luma_samples and pic_height_in_luma_samples are
|
||||
// constrained to be not greater than sqrt(MaxLumaPs * 8). Hence height/
|
||||
// width are bounded above by sqrt(8 * 35651584) = 16888.2 samples.
|
||||
HEVC_MAX_WIDTH = 16888,
|
||||
HEVC_MAX_HEIGHT = 16888,
|
||||
|
||||
// A.4.1: table A.6 allows at most 22 tile rows for any level.
|
||||
HEVC_MAX_TILE_ROWS = 22,
|
||||
// A.4.1: table A.6 allows at most 20 tile columns for any level.
|
||||
HEVC_MAX_TILE_COLUMNS = 20,
|
||||
|
||||
// 7.4.7.1: in the worst case (tiles_enabled_flag and
|
||||
// entropy_coding_sync_enabled_flag are both set), entry points can be
|
||||
// placed at the beginning of every Ctb row in every tile, giving an
|
||||
// upper bound of (num_tile_columns_minus1 + 1) * PicHeightInCtbsY - 1.
|
||||
// Only a stream with very high resolution and perverse parameters could
|
||||
// get near that, though, so set a lower limit here with the maximum
|
||||
// possible value for 4K video (at most 135 16x16 Ctb rows).
|
||||
HEVC_MAX_ENTRY_POINT_OFFSETS = HEVC_MAX_TILE_COLUMNS * 135,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* rational number numerator/denominator
|
||||
*/
|
||||
typedef struct T_AVRational{
|
||||
int num; ///< numerator
|
||||
int den; ///< denominator
|
||||
} T_AVRational;
|
||||
|
||||
|
||||
/***
|
||||
* Sequence parameter set
|
||||
* ¿É²Î¿¼H264±ê×¼µÚ7½ÚºÍ¸½Â¼D E
|
||||
/***
|
||||
* Sequence parameter set
|
||||
* H.264 sequence parameter set, version 7 and above, D E
|
||||
|
||||
* [AUTO-TRANSLATED:bd590cb8]
|
||||
*/
|
||||
#define Extended_SAR 255
|
||||
|
||||
/**
|
||||
* Sequence parameter set
|
||||
*/
|
||||
typedef struct T_SPS {
|
||||
unsigned int uiSpsId;
|
||||
int iProfileIdc;
|
||||
int iLevelIdc;
|
||||
int iChromaFormatIdc;
|
||||
int iTransformBypass; ///< qpprime_y_zero_transform_bypass_flag
|
||||
int iLog2MaxFrameNum; ///< log2_max_frame_num_minus4 + 4
|
||||
int iPocType; ///< pic_order_cnt_type
|
||||
int iLog2MaxPocLsb; ///< log2_max_pic_order_cnt_lsb_minus4
|
||||
int iDeltaPicOrderAlwaysZeroFlag;
|
||||
int iOffsetForNonRefPic;
|
||||
int iOffsetForTopToBottomField;
|
||||
int iPocCycleLength; ///< num_ref_frames_in_pic_order_cnt_cycle
|
||||
int iRefFrameCount; ///< num_ref_frames
|
||||
int iGapsInFrameNumAllowedFlag;
|
||||
int iMbWidth; ///< pic_width_in_mbs_minus1 + 1
|
||||
int iMbHeight; ///< pic_height_in_map_units_minus1 + 1
|
||||
int iFrameMbsOnlyFlag;
|
||||
int iMbAff; ///< mb_adaptive_frame_field_flag
|
||||
int iDirect8x8InferenceFlag;
|
||||
int iCrop; ///< frame_cropping_flag
|
||||
|
||||
/* those 4 are already in luma samples */
|
||||
unsigned int uiCropLeft; ///< frame_cropping_rect_left_offset
|
||||
unsigned int uiCropRight; ///< frame_cropping_rect_right_offset
|
||||
unsigned int uiCropTop; ///< frame_cropping_rect_top_offset
|
||||
unsigned int uiCropBottom; ///< frame_cropping_rect_bottom_offset
|
||||
int iVuiParametersPresentFlag;
|
||||
T_AVRational tSar;
|
||||
int iVideoSignalTypePresentFlag;
|
||||
int iFullRange;
|
||||
int iColourDescriptionPresentFlag;
|
||||
enum T_AVColorPrimaries tColorPrimaries;
|
||||
enum T_AVColorTransferCharacteristic tColorTrc;
|
||||
enum T_AVColorSpace tColorspace;
|
||||
int iTimingInfoPresentFlag;
|
||||
uint32_t u32NumUnitsInTick;
|
||||
uint32_t u32TimeScale;
|
||||
int iFixedFrameRateFlag;
|
||||
short asOffsetForRefFrame[256]; // FIXME dyn aloc?
|
||||
int iBitstreamRestrictionFlag;
|
||||
int iNumReorderFrames;
|
||||
int iScalingMatrixPresent;
|
||||
uint8_t aau8ScalingMatrix4[6][16];
|
||||
uint8_t aau8ScalingMatrix8[6][64];
|
||||
int iNalHrdParametersPresentFlag;
|
||||
int iVclHrdParametersPresentFlag;
|
||||
int iPicStructPresentFlag;
|
||||
int iTimeOffsetLength;
|
||||
int iCpbCnt; ///< See H.264 E.1.2
|
||||
int iInitialCpbRemovalDelayLength; ///< initial_cpb_removal_delay_length_minus1 + 1
|
||||
int iCpbRemovalDelayLength; ///< cpb_removal_delay_length_minus1 + 1
|
||||
int iDpbOutputDelayLength; ///< dpb_output_delay_length_minus1 + 1
|
||||
int iBitDepthLuma; ///< bit_depth_luma_minus8 + 8
|
||||
int iBitDepthChroma; ///< bit_depth_chroma_minus8 + 8
|
||||
int iResidualColorTransformFlag; ///< residual_colour_transform_flag
|
||||
int iConstraintSetFlags; ///< constraint_set[0-3]_flag
|
||||
int iNew; ///< flag to keep track if the decoder context needs re-init due to changed SPS
|
||||
} T_SPS;
|
||||
|
||||
/**
|
||||
* Picture parameter set
|
||||
*/
|
||||
typedef struct T_PPS {
|
||||
unsigned int uiSpsId;
|
||||
int iCabac; ///< entropy_coding_mode_flag
|
||||
int iPicOrderPresent; ///< pic_order_present_flag
|
||||
int iSliceGroupCount; ///< num_slice_groups_minus1 + 1
|
||||
int iMbSliceGroupMapType;
|
||||
unsigned int auiRefCount[2]; ///< num_ref_idx_l0/1_active_minus1 + 1
|
||||
int iWeightedPred; ///< weighted_pred_flag
|
||||
int iWeightedBipredIdc;
|
||||
int iInitQp; ///< pic_init_qp_minus26 + 26
|
||||
int iInitQs; ///< pic_init_qs_minus26 + 26
|
||||
int aiChromaQpIndexOffset[2];
|
||||
int iDeblockingFilterParametersPresent; ///< deblocking_filter_parameters_present_flag
|
||||
int iConstrainedIntraPred; ///< constrained_intra_pred_flag
|
||||
int iRedundantPicCntPresent; ///< redundant_pic_cnt_present_flag
|
||||
int iTransform8x8Mode; ///< transform_8x8_mode_flag
|
||||
uint8_t aau8ScalingMatrix4[6][16];
|
||||
uint8_t aau8ScalingMatrix8[6][64];
|
||||
uint8_t u8ChromaQpTable[2][QP_MAX_NUM+1]; ///< pre-scaled (with aiChromaQpIndexOffset) version of qp_table
|
||||
int iChromaQpDiff;
|
||||
} T_PPS;
|
||||
|
||||
|
||||
typedef struct T_HEVCWindow {
|
||||
unsigned int uiLeftOffset;
|
||||
unsigned int uiRightOffset;
|
||||
unsigned int uiTopOffset;
|
||||
unsigned int uiBottomOffset;
|
||||
} T_HEVCWindow;
|
||||
|
||||
|
||||
typedef struct T_VUI {
|
||||
T_AVRational tSar;
|
||||
|
||||
int iOverscanInfoPresentFlag;
|
||||
int iOverscanAppropriateFlag;
|
||||
|
||||
int iVideoSignalTypePresentFlag;
|
||||
int iVideoFormat;
|
||||
int iVideoFullRangeFlag;
|
||||
int iColourDescriptionPresentFlag;
|
||||
uint8_t u8ColourPrimaries;
|
||||
uint8_t u8TransferCharacteristic;
|
||||
uint8_t u8MatrixCoeffs;
|
||||
|
||||
int iChromaLocInfoPresentFlag;
|
||||
int iChromaSampleLocTypeTopField;
|
||||
int iChromaSampleLocTypeBottomField;
|
||||
int iNeutraChromaIndicationFlag;
|
||||
|
||||
int iFieldSeqFlag;
|
||||
int iFrameFieldInfoPresentFlag;
|
||||
|
||||
int iDefaultDisplayWindowFlag;
|
||||
T_HEVCWindow tDefDispWin;
|
||||
|
||||
int iVuiTimingInfoPresentFlag;
|
||||
uint32_t u32VuiNumUnitsInTick;
|
||||
uint32_t u32VuiTimeScale;
|
||||
int iVuiPocProportionalToTimingFlag;
|
||||
int iVuiNumTicksPocDiffOneMinus1;
|
||||
int iVuiHrdParametersPresentFlag;
|
||||
|
||||
int iBitstreamRestrictionFlag;
|
||||
int iTilesFixedStructureFlag;
|
||||
int iMotionVectorsOverPicBoundariesFlag;
|
||||
int iRestrictedRefPicListsFlag;
|
||||
int iMinSpatialSegmentationIdc;
|
||||
int iMaxBytesPerPicDenom;
|
||||
int iMaxBitsPerMinCuDenom;
|
||||
int iLog2MaxMvLengthHorizontal;
|
||||
int iLog2MaxMvLengthVertical;
|
||||
} T_VUI;
|
||||
|
||||
typedef struct T_PTLCommon {
|
||||
uint8_t u8ProfileSpace;
|
||||
uint8_t u8TierFlag;
|
||||
uint8_t u8ProfileIdc;
|
||||
uint8_t au8ProfileCompatibilityFlag[32];
|
||||
uint8_t u8LevelIdc;
|
||||
uint8_t u8ProgressiveSourceFlag;
|
||||
uint8_t u8InterlacedSourceFlag;
|
||||
uint8_t u8NonPackedConstraintFlag;
|
||||
uint8_t u8FrameOnlyConstraintFlag;
|
||||
} T_PTLCommon;
|
||||
|
||||
typedef struct T_PTL {
|
||||
T_PTLCommon tGeneralPtl;
|
||||
T_PTLCommon atSubLayerPtl[HEVC_MAX_SUB_LAYERS];
|
||||
|
||||
uint8_t au8SubLayerProfilePresentFlag[HEVC_MAX_SUB_LAYERS];
|
||||
uint8_t au8SubLayerLevelPresentFlag[HEVC_MAX_SUB_LAYERS];
|
||||
} T_PTL;
|
||||
|
||||
typedef struct T_ScalingList {
|
||||
/* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
|
||||
* and size ID 3 only has 2 arrays, not 6. */
|
||||
uint8_t aaau8Sl[4][6][64];
|
||||
uint8_t aau8SlDc[2][6];
|
||||
} T_ScalingList;
|
||||
|
||||
typedef struct T_ShortTermRPS {
|
||||
unsigned int uiNumNegativePics;
|
||||
int iNumDeltaPocs;
|
||||
int iRpsIdxNumDeltaPocs;
|
||||
int32_t au32DeltaPoc[32];
|
||||
uint8_t au8Used[32];
|
||||
} T_ShortTermRPS;
|
||||
|
||||
|
||||
typedef struct T_HEVCVPS {
|
||||
uint8_t u8VpsTemporalIdNestingFlag;
|
||||
int iVpsMaxLayers;
|
||||
int iVpsMaxSubLayers; ///< vps_max_temporal_layers_minus1 + 1
|
||||
|
||||
T_PTL tPtl;
|
||||
int iVpsSubLayerOrderingInfoPresentFlag;
|
||||
unsigned int uiVpsMaxDecPicBuffering[HEVC_MAX_SUB_LAYERS];
|
||||
unsigned int auiVpsNumReorderPics[HEVC_MAX_SUB_LAYERS];
|
||||
unsigned int auiVpsMaxLatencyIncrease[HEVC_MAX_SUB_LAYERS];
|
||||
int iVpsMaxLayerId;
|
||||
int iVpsNumLayerSets; ///< vps_num_layer_sets_minus1 + 1
|
||||
uint8_t u8VpsTimingInfoPresentFlag;
|
||||
uint32_t u32VpsNumUnitsInTick;
|
||||
uint32_t u32VpsTimeScale;
|
||||
uint8_t u8VpsPocProportionalToTimingFlag;
|
||||
int iVpsNumTicksPocDiffOne; ///< vps_num_ticks_poc_diff_one_minus1 + 1
|
||||
int iVpsNumHrdParameters;
|
||||
|
||||
} T_HEVCVPS;
|
||||
|
||||
typedef struct T_HEVCSPS {
|
||||
unsigned int uiVpsId;
|
||||
int iChromaFormatIdc;
|
||||
uint8_t u8SeparateColourPlaneFlag;
|
||||
|
||||
///< output (i.e. cropped) values
|
||||
int iIutputWidth, iOutputHeight;
|
||||
T_HEVCWindow tOutputWindow;
|
||||
|
||||
T_HEVCWindow tPicConfWin;
|
||||
|
||||
int iBitDepth;
|
||||
int iBitDepthChroma;
|
||||
int iPixelShift;
|
||||
|
||||
unsigned int uiLog2MaxPocLsb;
|
||||
int iPcmEnabledFlag;
|
||||
|
||||
int iMaxSubLayers;
|
||||
struct {
|
||||
int iMaxDecPicBuffering;
|
||||
int iNumReorderPics;
|
||||
int iMaxLatencyIncrease;
|
||||
} stTemporalLayer[HEVC_MAX_SUB_LAYERS];
|
||||
uint8_t u8temporalIdNestingFlag;
|
||||
|
||||
T_VUI tVui;
|
||||
T_PTL tPtl;
|
||||
|
||||
uint8_t u8ScalingListEnableFlag;
|
||||
T_ScalingList tScalingList;
|
||||
|
||||
unsigned int uiNbStRps;
|
||||
T_ShortTermRPS atStRps[HEVC_MAX_SHORT_TERM_RPS_COUNT];
|
||||
|
||||
uint8_t u8AmpEnabledFlag;
|
||||
uint8_t u8SaoEnabled;
|
||||
|
||||
uint8_t u8LongTermRefPicsPresentFlag;
|
||||
uint16_t au16LtRefPicPocLsbSps[32];
|
||||
uint8_t au8UsedByCurrPicLtSpsFlag[32];
|
||||
uint8_t u8NumLongTermRefPicsSps;
|
||||
|
||||
struct {
|
||||
uint8_t u8BitDepth;
|
||||
uint8_t u8BitDepthChroma;
|
||||
unsigned int uiLog2MinPcmCbSize;
|
||||
unsigned int uiLog2MaxPcmCbSize;
|
||||
uint8_t u8LoopFilterDisableFlag;
|
||||
} pcm;
|
||||
uint8_t u8SpsTemporalMvpEnabledFlag;
|
||||
uint8_t u8SpsStrongIntraMmoothingEnableFlag;
|
||||
|
||||
unsigned int uiLog2MinCbSize;
|
||||
unsigned int uiLog2DiffMaxMinCodingBlockSize;
|
||||
unsigned int uiLog2MinTbSize;
|
||||
unsigned int uiLog2MaxTrafoSize;
|
||||
unsigned int uiLog2CtbSize;
|
||||
unsigned int uiLog2MinPuSize;
|
||||
|
||||
int iMaxTransformHierarchyDepthInter;
|
||||
int iMaxTransformHierarchyDepthIntra;
|
||||
|
||||
int iTransformSkipRotationEnabledFlag;
|
||||
int iTransformSkipContextEnabledFlag;
|
||||
int iImplicitRdpcmEnabledFlag;
|
||||
int iExplicitRdpcmEnabledFlag;
|
||||
int iIntraSmoothingDisabledFlag;
|
||||
int iHighPrecisionOffsetsEnabledFlag;
|
||||
int iPersistentRiceAdaptationEnabledFlag;
|
||||
|
||||
///< coded frame dimension in various units
|
||||
int iWidth;
|
||||
int iHeight;
|
||||
int iCtbWidth;
|
||||
int iCtbHeight;
|
||||
int iCtbSize;
|
||||
int iMinCbWidth;
|
||||
int iMinCbHeight;
|
||||
int iMinTbWidth;
|
||||
int iMinTbHeight;
|
||||
int iMinPuWidth;
|
||||
int iMinPuHeight;
|
||||
int iTbMask;
|
||||
|
||||
int aiHshift[3];
|
||||
int aiVshift[3];
|
||||
|
||||
int iQpBdOffset;
|
||||
|
||||
int iVuiPresent;
|
||||
}T_HEVCSPS;
|
||||
|
||||
typedef struct {
|
||||
int pps_pic_parameter_set_id;
|
||||
int pps_seq_parameter_set_id;
|
||||
int dependent_slice_segments_enabled_flag;
|
||||
int output_flag_present_flag;
|
||||
int num_extra_slice_header_bits;
|
||||
int sign_data_hiding_enabled_flag;
|
||||
int cabac_init_present_flag;
|
||||
int num_ref_idx_l0_default_active_minus1;
|
||||
int num_ref_idx_l1_default_active_minus1;
|
||||
int init_qp_minus26;
|
||||
int constrained_intra_pred_flag;
|
||||
int transform_skip_enabled_flag;
|
||||
int cu_qp_delta_enabled_flag;
|
||||
int diff_cu_qp_delta_depth;
|
||||
int pps_cb_qp_offset;
|
||||
int pps_cr_qp_offset;
|
||||
int pps_slice_chroma_qp_offsets_present_flag;
|
||||
int weighted_pred_flag;
|
||||
int weighted_bipred_flag;
|
||||
int transquant_bypass_enabled_flag;
|
||||
int tiles_enabled_flag;
|
||||
int entropy_coding_sync_enabled_flag;
|
||||
int uniform_spacing_flag;
|
||||
int loop_filter_across_tiles_enabled_flag;
|
||||
int pps_loop_filter_across_slices_enabled_flag;
|
||||
int deblocking_filter_control_present_flag;
|
||||
int deblocking_filter_override_enabled_flag;
|
||||
int pps_deblocking_filter_disabled_flag;
|
||||
int pps_beta_offset_div2;
|
||||
int pps_tc_offset_div2;
|
||||
int pps_scaling_list_data_present_flag;
|
||||
int lists_modification_present_flag;
|
||||
int log2_parallel_merge_level_minus2;
|
||||
int slice_segment_header_extension_present_flag;
|
||||
int pps_extension_present_flag;
|
||||
int pps_range_extension_flag;
|
||||
int pps_multilayer_extension_flag;
|
||||
int pps_3d_extension_flag;
|
||||
int pps_scc_extension_flag;
|
||||
int pps_extension_4bits;
|
||||
|
||||
// PPS range extension fields
|
||||
int log2_max_transform_skip_block_size_minus2;
|
||||
int cross_component_prediction_enabled_flag;
|
||||
int chroma_qp_offset_list_enabled_flag;
|
||||
int diff_cu_chroma_qp_offset_depth;
|
||||
int chroma_qp_offset_list_len_minus1;
|
||||
int cb_qp_offset_list[6];
|
||||
int cr_qp_offset_list[6];
|
||||
int log2_sao_offset_scale_luma;
|
||||
int log2_sao_offset_scale_chroma;
|
||||
|
||||
// 可以根据需要添加更多字段 [AUTO-TRANSLATED:57b9a7c1]
|
||||
// You can add more fields as needed
|
||||
} T_HEVC_PPS;
|
||||
|
||||
typedef struct T_GetBitContext{
|
||||
uint8_t *pu8Buf; // buf
|
||||
int iBufSize; // buf size
|
||||
int iBitPos; // bit position
|
||||
int iTotalBit; // bit number
|
||||
int iCurBitPos; // current bit position
|
||||
}T_GetBitContext;
|
||||
|
||||
int h265ParsePps(T_GetBitContext *ptGetBitContext, T_HEVC_PPS *ptPps);
|
||||
int h264DecSeqParameterSet(void *pvBuf, T_SPS *ptSps);
|
||||
int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *ptSps );
|
||||
int h265DecVideoParameterSet( void *pvBufSrc, T_HEVCVPS *ptVps );
|
||||
|
||||
|
||||
void h264GetWidthHeight(T_SPS *ptSps, int *piWidth, int *piHeight);
|
||||
void h265GetWidthHeight(T_HEVCSPS *ptSps, int *piWidth, int *piHeight);
|
||||
|
||||
void h264GeFramerate(T_SPS *ptSps, float *pfFramerate);
|
||||
void h265GeFramerate(T_HEVCVPS *ptVps, T_HEVCSPS *ptSps,float *pfFramerate);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_SPS_PPS_H_
|
||||
Reference in New Issue
Block a user