sps解码
int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
H264ParamSets *ps, int ignore_truncation)
{
AVBufferRef *sps_buf;
int profile_idc, level_idc, constraint_set_flags = 0;
unsigned int sps_id;
int i, log2_max_frame_num_minus4;
SPS *sps;
int ret;
sps_buf = av_buffer_allocz(sizeof(*sps));
if (!sps_buf)
return AVERROR(ENOMEM);
sps = (SPS*)sps_buf->data;
sps->data_size = gb->buffer_end - gb->buffer;
if (sps->data_size > sizeof(sps->data)) {
av_log(avctx, AV_LOG_DEBUG, "Truncating likely oversized SPS\n");
sps->data_size = sizeof(sps->data);
}
memcpy(sps->data, gb->buffer, sps->data_size);
profile_idc = get_bits(gb, 8); //编码参数 profile类型
constraint_set_flags |= get_bits1(gb) << 0; // constraint_set0_flag
constraint_set_flags |= get_bits1(gb) << 1; // constraint_set1_flag
constraint_set_flags |= get_bits1(gb) << 2; // constraint_set2_flag
constraint_set_flags |= get_bits1(gb) << 3; // constraint_set3_flag
constraint_set_flags |= get_bits1(gb) << 4; // constraint_set4_flag
constraint_set_flags |= get_bits1(gb) << 5; // constraint_set5_flag
//固定设置参数
skip_bits(gb, 2); // reserved_zero_2bits 保留2bits
level_idc = get_bits(gb, 8); // 编码level 8bits
sps_id = get_ue_golomb_31(gb); // ue无符号哥伦布编码读取, sps_id https://blog.youkuaiyun.com/fantasy_ARM9/article/details/105635317
if (sps_id >= MAX_SPS_COUNT) { //sps最大个数 32个
av_log(avctx, AV_LOG_ERROR, "sps_id %u out of range\n", sps_id);
goto fail;
}
sps->sps_id = sps_id;
sps->time_offset_length = 24;
sps->profile_idc = profile_idc;
sps->constraint_set_flags = constraint_set_flags;
sps->level_idc = level_idc;
sps->full_range = -1;
memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
sps->scaling_matrix_present = 0;
sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED
if (sps->profile_idc == 100 || // High profile
sps->profile_idc == 110 || // High10 profile
sps->profile_idc == 122 || // High422 profile
sps->profile_idc == 244 || // High444 Predictive profile
sps->profile_idc == 44 || // Cavlc444 profile
sps->profile_idc == 83 || // Scalable Constrained High profile (SVC)
sps->profile_idc == 86 || // Scalable High Intra profile (SVC)
sps->profile_idc == 118 || // Stereo High profile (MVC)
sps->profile_idc == 128 || // Multiview High profile (MVC)
sps->profile_idc == 138 || // Multiview Depth High profile (MVCD)
sps->profile_idc == 144) { // old High444 profile
sps->chroma_format_idc = get_ue_golomb_31(gb); //色度采样格式
/*
enum chroma_format_e
{
CHROMA_400 = 0,
CHROMA_420 = 1,
CHROMA_422 = 2,
CHROMA_444 = 3,
};
*/
if (sps->chroma_format_idc > 3U) {
avpriv_request_sample(avctx, "chroma_format_idc %u",
sps->chroma_format_idc);
goto fail;
} else if (sps->chroma_format_idc == 3) {// 如果是YUV444
sps->residual_color_transform_flag = get_bits1(gb);// 等于0时,采用残余颜色转换
if (sps->residual_color_transform_flag) {
av_log(avctx, AV_LOG_ERROR, "separate color planes are not supported\n");
goto fail;
}
}
sps->bit_depth_luma = get_ue_golomb_31(gb) + 8;//亮度深度
sps->bit_depth_chroma = get_ue_golomb_31(gb) + 8;//色度深度
if (sps->bit_depth_chroma != sps->bit_depth_luma) {// 如果颜色深度和 亮度深度不等,认为时错误
avpriv_request_sample(avctx,
"Different chroma and luma bit depth");
goto fail;
}
if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 14 ||
sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 14) {
av_log(avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n",
sps->bit_depth_luma, sps->bit_depth_chroma);
goto fail;
}
sps->transform_bypass = get_bits1(gb);
/*qpprime_y_zero_transform_bypass_flag 等于 1 是指当 QP'Y 等于 0 时变换系数解码过程的变换旁路操作和图
像构建过程将会在第 8.5 节给出的去块效应滤波过程之前执行。qpprime_y_zero_transform_bypass_flag 等于 0 是指
变 换 系 数 解 码过程和图像 构 建过程在 去 块 效 应 滤 波 过程之前 执 行而不使用 变 换 旁路操 作。当
qpprime_y_zero_transform_bypass_flag 没有特别指定时,应推定其值为 0。*/
ret = decode_scaling_matrices(gb, sps, NULL, 1,
sps->scaling_matrix4, sps->scaling_matrix8);
/*seq_scaling_matrix_present_flag 等 于 1 表示存在 i=0..7 的 标 志 seq_scaling_list_present_flag[ i ] 。
seq_scaling_matrix_present_flag 等于 0 则表示不存在这些标志并且由 Flat_4x4_16 表示的序列级别的缩放比例列表
应被推断出来(对应 i=0..5),由 Flat_8x8_16 表示的序列级别的缩放比例列表应被推断出来(对应 i=6..7)。当
seq_scaling_matrix_present_flag 没有特别指定时,应推定其值为 0。*/
if (ret < 0)
goto fail;
sps->scaling_matrix_present |= ret;
} else {
sps->chroma_format_idc = 1;
sps->bit_depth_luma = 8;
sps->bit_depth_chroma = 8;
}
log2_max_frame_num_minus4 = get_ue_golomb_31(gb);// log2_max_frame_num_minus4 最大frame_num -4 log2
if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 ||
log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) {
av_log(avctx, AV_LOG_ERROR,
"log2_max_frame_num_minus4 out of range (0-12): %d\n",
log2_max_frame_num_minus4);
goto fail;
}
sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;// log2 max_frame
sps->poc_type = get_ue_golomb_31(gb); // poc类型
/*pic_order_cnt_type 是指解码图像顺序的计数方法(如 8.2.1 节所述)。pic_order_cnt_type 的取值范围是 0 到 2(包括 0 和 2)。
包含下列任何情况的一个编码视频序列中 pic_order_cnt_type 都不能等于 2: -— 一个包含非参考图像的访问单元紧跟在一个包含非参考帧的访问单元之后; -— 一个包含非参考图像的访问单元紧跟在分别包含一个由两个场一起组成一个互补的非参考场对的两个
访问单元之后; -— 一个包含非参考场的访问单元之后紧跟在一个包含另一个非参考图像的访问单元(该访问单元没有与
两个访问单元中的第一个组成一个互补的非参考场对)*/
if (sps->poc_type == 0) { // FIXME #define
unsigned t = get_ue_golomb_31(gb);
/*log2_max_pic_order_cnt_lsb_minus4 表示用于 8.2.1 节规定的图像 顺 序 数 解 码过程中的 变 量
MaxPicOrderCntLsb 的值,公式如下:
MaxPicOrderCntLsb = 2( log2_max_pic_order_cnt_lsb_minus4 + 4 )*/
if (t>12) {
av_log(avctx, AV_LOG_ERROR, "log2_max_poc_lsb (%d) is out of range\n", t);
goto fail;
}
sps->log2_max_poc_lsb = t + 4;
} else if (sps->poc_type == 1) { // FIXME #define
sps->delta_pic_order_always_zero_flag = get_bits1(gb);
/*delta_pic_order_always_zero_flag 等 于 1 表示视频 序 列 的 条 带 头 中 没 有 delta_pic_order_cnt[ 0 ] 和
delta_pic_order_cnt[ 1 ] 两个字段,它们的值都默认为 0。delta_pic_order_always_zero_flag 等于 0 表示视频序列的
条带头中包含 delta_pic_order_cnt[ 0 ]字段,并可能包括 delta_pic_order_cnt[ 1]的字段(也可以不包括)。*/
sps->offset_for_non_ref_pic = get_se_golomb_long(gb);
sps->offset_for_top_to_bottom_field = get_se_golomb_long(gb);
/*offset_for_non_ref_pic 用于计算 8.2.1 节规定的一个非参考图像的图像顺序号。offset_for_non_ref_pic 的取值
范围是 – 231 到 231 – 1(包括-231 和 231 – 1)。
offset_for_top_to_bottom_field 用于计算 8.2.1 节规定的一个 帧 的 底 场的图像 顺序号 。
offset_for_top_to_bottom_field 的取值范围是 – 231 到 231 – 1(包括–231 和 231 – 1)。
num_ref_frames_in_pic_order_cnt_cycle 用 于 8.2.1 节规定的图像 顺序号 的 解 码过程。
num_ref_frames_in_pic_order_cnt_cycle 的取值范围是 0 到 255(包括 0 和 255)。*/
if ( sps->offset_for_non_ref_pic == INT32_MIN
|| sps->offset_for_top_to_bottom_field == INT32_MIN
) {
av_log(avctx, AV_LOG_ERROR,
"offset_for_non_ref_pic or offset_for_top_to_bottom_field is out of range\n");
goto fail;
}
sps->poc_cycle_length = get_ue_golomb(gb);
/*num_ref_frames_in_pic_order_cnt_cycle 用 于 8.2.1 节规定的图像 顺序号 的 解 码过程。
num_ref_frames_in_pic_order_cnt_cycle 的取值范围是 0 到 255(包括 0 和 255)。*/
if ((unsigned)sps->poc_cycle_length >=
FF_ARRAY_ELEMS(sps->offset_for_ref_frame)) {
av_log(avctx, AV_LOG_ERROR,
"poc_cycle_length overflow %d\n", sps->poc_cycle_length);
goto fail;
}
for (i = 0; i < sps->poc_cycle_length; i++) {//参考帧偏移
sps->offset_for_ref_frame[i] = get_se_golomb_long(gb);
if (sps->offset_for_ref_frame[i] == INT32_MIN) {
av_log(avctx, AV_LOG_ERROR,
"offset_for_ref_frame is out of range\n");
goto fail;
}
}
} else if (sps->poc_type != 2) {
av_log(avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
goto fail;
}
sps->ref_frame_count = get_ue_golomb_31(gb); //参考帧个数

本文详细介绍了ffmpeg库中h264解码器如何解析序列参数集(sps),涉及关键参数如profile_idc、level_idc、sps_id、chroma_format_idc、bit_depth等的解析过程,以及解码过程中可能出现的错误检查和处理。
1723

被折叠的 条评论
为什么被折叠?



