get_ue_golomb_long(&nal.gb); // skip first_mb_in_slice

slice_type = get_ue_golomb_31(&nal.gb);// nalu类型后面第一个字段是 slice type, 无符号指数哥伦布编码

s->pict_type = ff_h264_golomb_to_pict_type[slice_type % 5];

if (p->sei.recovery_point.recovery_frame_cnt >= 0) { // sei set key frame

/* key frame, since recovery_frame_cnt is set */

s->key_frame = 1;

}

pps_id = get_ue_golomb(&nal.gb);// pps ID

if (pps_id >= MAX_PPS_COUNT) {

av_log(avctx, AV_LOG_ERROR,

"pps_id %u out of range\n", pps_id);

goto fail;

}

if (!p->ps.pps_list[pps_id]) {

av_log(avctx, AV_LOG_ERROR,

"non-existing PPS %u referenced\n", pps_id);

goto fail;

}

 

av_buffer_unref(&p->ps.pps_ref);

p->ps.pps = NULL;

p->ps.sps = NULL;

p->ps.pps_ref = av_buffer_ref(p->ps.pps_list[pps_id]);

if (!p->ps.pps_ref)

goto fail;

p->ps.pps = (const PPS*)p->ps.pps_ref->data;

p->ps.sps = p->ps.pps->sps;

sps = p->ps.sps;

 

// heuristic to detect non marked keyframes

if (p->ps.sps->ref_frame_count <= 1 && p->ps.pps->ref_count[0] <= 1 && s->pict_type == AV_PICTURE_TYPE_I)

s->key_frame = 1;

 

p->poc.frame_num = get_bits(&nal.gb, sps->log2_max_frame_num); // 获取 log2_max_frame_num 个bits表示 frame_num

 

s->coded_width = 16 * sps->mb_width; //从sps中获取宽度

s->coded_height = 16 * sps->mb_height; //从sps中获取高度

s->width = s->coded_width - (sps->crop_right + sps->crop_left);// 获取 实际宽度

s->height = s->coded_height - (sps->crop_top + sps->crop_bottom);// 获取实际高度

if (s->width <= 0 || s->height <= 0) {

s->width = s->coded_width;

s->height = s->coded_height;

}

 

switch (sps->bit_depth_luma) {// 亮度像素深度

case 9:

// 获取像素格式

if (sps->chroma_format_idc == 3) s->format = AV_PIX_FMT_YUV444P9;

else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P9;

else s->format = AV_PIX_FMT_YUV420P9;

break;

case 10:

//

if (sps->chroma_format_idc == 3) s->format = AV_PIX_FMT_YUV444P10;

else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P10;

else s->format = AV_PIX_FMT_YUV420P10;

break;

case 8:

if (sps->chroma_format_idc == 3) s->format = AV_PIX_FMT_YUV444P;

else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P;

else s->format = AV_PIX_FMT_YUV420P;

break;

default:

s->format = AV_PIX_FMT_NONE;// 未知像素格式

}

 

avctx->profile = ff_h264_get_profile(sps);// profile类型

avctx->level = sps->level_idc;// 编码level

 

if (sps->frame_mbs_only_flag) {// 如果不是场编码

p->picture_structure = PICT_FRAME;

} else { //如果是场编码

if (get_bits1(&nal.gb)) { // field_pic_flag

p->picture_structure = PICT_TOP_FIELD + get_bits1(&nal.gb); // bottom_field_flag

} else {

p->picture_structure = PICT_FRAME;

}

}

 

if (nal.type == H264_NAL_IDR_SLICE) //如果是idr slice

get_ue_golomb_long(&nal.gb);

/* idr_pic_id

idr_pic_id 标识一个 IDR 图像。一个 IDR 图像的所有条带中的 idr_pic_id 值应保持不变。当按解码顺序的两

个连续访问单元都是 IDR 访问单元时,第一个 IDR 访问单元的条带的 idr_pic_id 值应与第二个 IDR 访问单元的

idr_pic_id 值不同。idr_pic_id 的值应在 0 到 65535 的范围内(包括 0 和 65535)

*/

if (sps->poc_type == 0) {

p->poc.poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb); //sps获取poc lsb bit个数

/*pic_order_cnt_lsb 表示一个编码帧的顶场或一个编码场的图像顺序数对 MaxPicOrderCntLsb 取模。

pic_order_cnt_lsb 语法元素的大小是 log2_max_pic_order_cnt_lsb_minus4 + 4 个比特。pic_order_cnt_lsb

的值应该在 0 到 MaxPicOrderCntLsb – 1 的范围内(包括边界值)。*/

if (p->ps.pps->pic_order_present == 1 &&

p->picture_structure == PICT_FRAME)

p->poc.delta_poc_bottom = get_se_golomb(&nal.gb);

/*delta_pic_order_cnt_bottom 表示一个编码帧的底场和顶场的图像顺序数之间的差*/

}

 

if (sps->poc_type == 1 &&

!sps->delta_pic_order_always_zero_flag) {

p->poc.delta_poc[0] = get_se_golomb(&nal.gb);

 

if (p->ps.pps->pic_order_present == 1 &&

p->picture_structure == PICT_FRAME)//非场编码,还需要解析一个delta POC?

p->poc.delta_poc[1] = get_se_golomb(&nal.gb);

}

 

/* Decode POC of this picture.

* The prev_ values needed for decoding POC of the next picture are not set here.

* 解码出 POC 的值 ,一个GOP内为一个POC周期*/

field_poc[0] = field_poc[1] = INT_MAX;

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐