ffmpeg解码h264代码分析-slice解析(一)
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;
更多推荐
所有评论(0)