1080P画面大小却是1920*1088的两个原因

问题

在解码播放1080P网络视频流或视频文件,得到的画面大小却是宽为1920像素,高为1088像素!

原因一

是部分软件在实现网络摄像头,H.264协议码流中,计算画面宽高的方式有误,正确应该如下:

英文文档说明

在SPS帧中有关于画面像素宽高的计算方式,在h264标准中,关于SPS(序列参数集Sequence Parameter Set)数据语法的定义在7.3.2.1.1节:
1080P画面大小却是1920*1088的两个原因_第1张图片
1080P画面大小却是1920*1088的两个原因_第2张图片
对宽高的计算方式,英文文档说明如下:
1080P画面大小却是1920*1088的两个原因_第3张图片
1080P画面大小却是1920*1088的两个原因_第4张图片

中文解释

宽高从SPS字段计算的公式如下:

# 公式一
Width = (pic_width_in_mbs_minus1+1)16;
Height = (pic_height_in_map_units_minus1+1)16;

但以上是针对宽高是16的整数倍的情况,当不是16整数倍时,frame_cropping_flag值为1,frame_mbs_only_flag为1,公式如下(也可统一使用如下公式):

# 公式二
width = (sps->pic_width_in_mbs_minus1+1) * 16;
height = (2 - sps->frame_mbs_only_flag)* (sps->pic_height_in_map_units_minus1 +1) * 16);
if(sps->frame_cropping_flag)
{
     
unsigned int crop_unit_x;
unsigned int crop_unit_y;
if (0 == sps->chroma_format_idc) // monochrome
{
     
crop_unit_x = 1;
crop_unit_y = 2 - sps->frame_mbs_only_flag;
}
else if (1 == sps->chroma_format_idc) // 4:2:0
{
     
crop_unit_x = 2;
crop_unit_y = 2 * (2 - sps->frame_mbs_only_flag);
}
else if (2 == sps->chroma_format_idc) // 4:2:2
{
     
crop_unit_x = 2;
crop_unit_y = 2 - sps->frame_mbs_only_flag;
}
else // 3 == sps.chroma_format_idc // 4:4:4
{
     
crop_unit_x = 1;
crop_unit_y = 2 - sps->frame_mbs_only_flag;
}
width -= crop_unit_x * (sps->frame_crop_left_offset + sps->frame_crop_right_offset);
height -= crop_unit_y * (sps->frame_crop_top_offset + sps->frame_crop_bottom_offset);
}

比如一个1080P视频的SPS信息如下:

pic_width_in_mbs_minus1 : 119
pic_height_in_map_units_minus1 : 67
frame_mbs_only_flag : 1
mb_adaptive_frame_field_flag : 0
direct_8x8_inference_flag : 1
frame_cropping_flag : 1
frame_crop_left_offset : 0
frame_crop_right_offset : 0
frame_crop_top_offset : 0
frame_crop_bottom_offset : 4

根据第二个公式计算得到宽高应该为:

width = (119+1) * 16 - 0*2 - 0*2 = 1920
height = (2-1) * (67+1)*16 - 0*2 - 4*2 = 1088 - 8 = 1080

原因二

视频文件或视频六可能采用了ATSC(美国的数字电视国家标准),Wiki上该标准对于MPEG-2有如下说明:

The 1080-line formats are encoded with 1920 × 1088 pixel luma matrices and 960 × 540 chroma matrices, but the last 8 lines are discarded by the MPEG-2 decoding and display process.

直译意思是:1080行格式使用1920×1088像素luma矩阵和960×540色度矩阵进行编码,但最后8行被MPEG-2解码和显示过程丢弃。

参考来源

从H264/H265码流中获取宽、高及帧率
一步一步解析H.264码流的NALU(SPS,PSS,IDR)获取宽高和帧率
H264标准英文原版附中文翻译

你可能感兴趣的:(H264,H264,FFMPEG,1080P,mpeg2)