H264编码系列之获取分辨率和帧率

更多音视频知识请点击:专注音视频开发

从码流中获取分辨率

宽高可从SPS字段计算得到,公式如下:

width =  (pic_width_in_mbs_minus1+1) * 16; 
height = (2 - frame_mbs_only_flag) *(pic_height_in_map_units_minus1 +1) * 16;

但以上是针对宽高是16的整数倍的情况,当不是16整数倍时,frame_cropping_flag值为1,则调整为(计算方法参考mkvtoolnix,这里只考虑yuv420p的情况

if (frame_cropping_flag)
{
    unsigned int crop_unit_x; 
    unsigned int crop_unit_y;
    crop_unit_x = 2; 
    crop_unit_y = 2 * (2 - frame_mbs_only_flag);

    width -= crop_unit_x * (frame_crop_left_offset +  frame_crop_right_offset);
    height -= crop_unit_y * (frame_crop_top_offset +  frame_crop_bottom_offset); 
}

比如文件318x238分辨率(宽高必须都可以整除2)


318x238分辨率
  • 第一步

width = (pic_width_in_mbs_minus1+1) * 16 = (19+1)*16 = 320;
height = (2 - frame_mbs_only_flag) *(pic_height_in_map_units_minus1 +1) * 16 = (2-1)*(14+1)*16 = 240;

  • 第二步
    因为frame_cropping_flag = 1,所以width和height都需要做调整。
crop_unit_x = 2; 
crop_unit_y = 2 * (2 - 1) = 2;

width -= 2* (0+  1) ;
height -= 2* (0+  1);
即是
width -= 2;
height -= 2;

width = 320-2 = 318;
height = 240 -2 = 238;

帧率获取

  1. sps 中的帧率
    不是所有的编码器都带有帧率信息,在nalu 中的sps里,应为耗费带宽,通过解析nalu 中的数据结构可以发现里面有个标志位:
    vui_parameters_present_flag 负责是否带帧率

  2. 帧率计算
    framerate = time_scale/2*num_units_in_tick.
    我们可以使用ffmpeg来生成码流进行测试

ffmpeg -i input.mp4 -r 15 r15.h264
ffmpeg -i input.mp4 -r 25 r25.h264
ffmpeg -i input.mp4 -r 29 r29.h264
# r15.h264
000010    timing_info_present_flag:            Yes
000010    num_units_in_tick:                   1 (0x00000001) - (32 bits)
000014    time_scale:                          30 (0x0000001E) - (32 bits)
# r25.h264
000010    timing_info_present_flag:            Yes
000010    num_units_in_tick:                   1 (0x00000001) - (32 bits)
000014    time_scale:                          50 (0x00000032) - (32 bits)
# r29.h264
000010    timing_info_present_flag:            Yes
000010    num_units_in_tick:                   1 (0x00000001) - (32 bits)
000014    time_scale:                          58 (0x0000003A) - (32 bits)

你可能感兴趣的:(H264编码系列之获取分辨率和帧率)