从H264中SPS计算宽高

最近在处理H264流的时候发现计算的宽高并不正确。

基本计算方法

大家都知道SPS解析之后,宽高就可以通过下面的计算公式计算出来:

  • (pic_width_in_mbs_minus1 + 1) * 16
  • (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) - sps->frame_crop_left_offset*2 
- sps->frame_crop_right_offset*2;
height = ((2 - sps->frame_mbs_only_flag)* (sps->pic_height_in_map_units_minus1 +1)*16)
- (sps->frame_crop_top_offset*2) - (sps->frame_crop_bottom_offset*2);

这样计算出来的才是正确的。

终极计算方法

然后上述的计算方法还是有一些局限性,具体参见标准文档,比较靠谱的方法如下

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);
}
最近的文章

视频RTP乱序问题

问题分析最近在一个新环境下保持RTP的H264视频数据花屏,按照以往经验,最大可能性是丢包了,遂抓包分析,发现包个数足够,并没有反馈任何包的丢失,这就有意思了。 不过在看抓包过程中,不经意间发现了下面的现象 seq 51 的包跑到 seq 50 的前面了,怪不得解包的视频不正确。顺着这个线索继续看 …

技术 继续阅读
更早的文章

CentOS6支持到期后配置备份更新源

CentOS 6 的支持在上个月到期了,各个更新源都下线了,线上一堆的服务器又不能升级,偶尔安装个软件可怎么办,其实官方还保留了一个备份的源用来更新,虽然不升级了,但至少安装软件没问题。 配置备份虽然说备份已经没啥用了,但是作为良好的操作习惯,还是建议做一下。 备份目录 /etc/yum.repo. …

技术 继续阅读