码流的宽高和裁剪信息
为什么解析裁剪信息要乘以2,有的又不需要?
用elecard打开码流:信息在sps pps 里;
其中不同的YUV排布方式对应不同的宽高计算方式:
#define X264_CSP_MASK 0x00ff /* */ #define X264_CSP_NONE 0x0000 /* Invalid mode */ #define X264_CSP_I400 0x0001 /* monochrome 4:0:0 */ #define X264_CSP_I420 0x0002 /* yuv 4:2:0 planar */ #define X264_CSP_YV12 0x0003 /* yvu 4:2:0 planar */ #define X264_CSP_NV12 0x0004 /* yuv 4:2:0, with one y plane and one packed u+v */ #define X264_CSP_NV21 0x0005 /* yuv 4:2:0, with one y plane and one packed v+u */ #define X264_CSP_I422 0x0006 /* yuv 4:2:2 planar */ #define X264_CSP_YV16 0x0007 /* yvu 4:2:2 planar */ #define X264_CSP_NV16 0x0008 /* yuv 4:2:2, with one y plane and one packed u+v */ #define X264_CSP_YUYV 0x0009 /* yuyv 4:2:2 packed */ #define X264_CSP_UYVY 0x000a /* uyvy 4:2:2 packed */ #define X264_CSP_V210 0x000b /* 10-bit yuv 4:2:2 packed in 32 */ #define X264_CSP_I444 0x000c /* yuv 4:4:4 planar */ #define X264_CSP_YV24 0x000d /* yvu 4:4:4 planar */ #define X264_CSP_BGR 0x000e /* packed bgr 24bits */ #define X264_CSP_BGRA 0x000f /* packed bgr 32bits */ #define X264_CSP_RGB 0x0010 /* packed rgb 24bits */ #define X264_CSP_MAX 0x0011 /* end of list */ #define X264_CSP_VFLIP 0x1000 /* the csp is vertically flipped */ #define X264_CSP_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */
1、H264
计算宽高根据标识不同有两种(都是从SPS字段中取值)
第一种:
Width = (pic_width_in_mbs_minus1+1)*16;
Height = (pic_height_in_map_units_minus1+1)*16;
第二种:
条件, frame_cropping_flag 值为1,frame_mbs_only_flag 为1,公式如下:
(也可以认为统一使用下面的公式)
width = ((pic_width_in_mbs_minus1 +1)16) - frame_crop_left_offset2 - frame_crop_right_offset2;
height= ((2 - frame_mbs_only_flag) (pic_height_in_map_units_minus1 +1) * 16)
- (frame_crop_top_offset * 2) - (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);
}
2、H265
H.265类似,但SPS的字段不同了。公式如下:
width = sps->pic_width_in_luma_samples;
height = sps->pic_height_in_luma_samples;
当窗口有裁剪时(conformance_window_flag为1),计算如下:
sub_width_c = ((1==chroma_format_idc)||(2 == chroma_format_idc))&&(0==separate_colour_plane_flag)?2:1;
sub_height_c = (1==chroma_format_idc)&& (0 == separate_colour_plane_flag)?2:1;
width -= (sub_width_c*conf_win_right_offset + sub_width_c*conf_win_left_offset);
height -= (sub_height_c*conf_win_bottom_offset + sub_height_c*conf_win_top_offset);
3、帧率
H264和H265帧率计算公式相同,如下:
max_framerate = (float)(sps->vui.vui_time_scale) / (float)(sps->vui.vui_num_units_in_tick);
使用x264编码YUV序列,设置为25fps时,time_scale为50,num_units_in_tick为1,计算得50fps,与实际不符。
而x265用同样的参数编码,计算得到的帧率是正常的
通过RTSP里面获取到SPS,PPS内容,可以参考我的代码:
从RTSP的SDP传输内容中获取SPS及PPS
转载https://blog.csdn.net/subfate/article/details/48576445