更多音视频知识请点击:点击获取更多音视频知识
Sequence Paramater Set(SPS)(序列参数集)
(1). profile_idc:
标识当前H.264码流的profile。我们知道,H.264中定义了三种常用的档次profile:
- 基准档次:baseline profile;
- 主要档次:main profile;
- 扩展档次:extended profile;
在H.264的SPS中,第一个字节表示profile_idc,根据profile_idc的值可以确定码流符合哪一种档次。判断规律为:
- profile_idc = 66 → baseline profile;
- profile_idc = 77 → main profile;
- profile_idc = 88 → extended profile;
在新版的标准中,还包括了High、High 10、High 4:2:2、High 4:4:4、High 10 Intra、High 4:2:2 Intra、High 4:4:4 Intra、CAVLC 4:4:4 Intra等,每一种都由不同的profile_idc表示。
另外,constraint_set0_flag ~ constraint_set5_flag是在编码的档次方面对码流增加的其他一些额外限制性条件。
在我们实验码流中,profile_idc = 0x42 = 66,因此码流的档次为baseline profile。
(2). level_idc
标识当前码流的Level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。
当前码流中,level_idc = 0x1e = 30,因此码流的级别为3。
(3). seq_parameter_set_id
表示当前的序列参数集的id。通过该id值,图像参数集pps可以引用其代表的sps中的参数。
(4). log2_max_frame_num_minus4
用于计算MaxFrameNum的值。计算公式为MaxFrameNum = 2^(log2_max_frame_num_minus4 + 4)。MaxFrameNum是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。
(5). pic_order_cnt_type
表示解码picture order count(POC)的方法。POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法。该语法元素的取值为0、1或2。
(6). log2_max_pic_order_cnt_lsb_minus4
用于计算MaxPicOrderCntLsb的值,该值表示POC的上限。计算方法为MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4)。
(7). max_num_ref_frames
用于表示参考帧的最大数目。
(8). gaps_in_frame_num_value_allowed_flag
标识位,说明frame_num中是否允许不连续的值。
(9). pic_width_in_mbs_minus1
本句法元素加 1 后指明图像宽度,以宏块为单位:
PicWidthInMbs = pic_width_in_mbs_minus1 + 1
通过这个句法元素解码器可以计算得到亮度分量以像素为单位的图像宽度:
PicWidthInSamplesL = PicWidthInMbs * 16
从而也可以得到色度分量以像素为单位的图像宽度:
PicWidthInSamplesC = PicWidthInMbs * 8
以上变量 PicWidthInSamplesL、PicWidthInSamplesC 分别表示图像的亮度、色度分量以像素为单位的宽。
H.264 将图像的大小在序列参数集中定义,意味着可以在通信过程中随着序列参数集动态地改变图像的大小,在后文中可以看到,甚至可以将传送的图像剪裁后输出。
(10). pic_height_in_map_units_minus1
本句法元素加 1 后指明图像高度:
PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1
PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits
图像的高度的计算要比宽度的计算复杂,因为一个图像可以是帧也可以是场,从这个句法元素可以在帧模式和场模式下分别计算出出亮度、色度的高。值得注意的是,这里以 map_unit 为单位,map_unit的含义由后文叙述。
(11). frame_mbs_only_flag
标识位,说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:
FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits
(12). mb_adaptive_frame_field_flag
标识位,说明是否采用了宏块级的帧场自适应编码。当该标识位为0时,不存在帧编码和场编码之间的切换;当标识位为1时,宏块可能在帧编码和场编码模式之间进行选择。
(13). direct_8x8_inference_flag
标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。
(14). frame_cropping_flag
标识位,说明是否需要对输出的图像帧进行裁剪。
(15). vui_parameters_present_flag
标识位,说明SPS中是否存在VUI信息。
H264编码profile & level控制
H.264有四种画质级别,分别是baseline, extended, main, high:
- Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;
- Extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;(用的少)
- Main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced), 也支持CAVLC 和CABAC 的支持;
- High profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;
H.264 Baseline profile、Extended profile和Main profile都是针对8位样本数据、4:2:0格式(YUV)的视频序列。在相同配置情况下,High profile(HP)可以比Main profile(MP)降低10%的码率。 根据应用领域的不同:
- Baseline profile多应用于实时通信领域;
- Main profile多应用于流媒体领域;
- High profile则多应用于广电和存储领域。
profile主要参数
下图清楚的给出不同的profile&level的性能区别。
Level 主要参数
ffmpeg如何控制profile&level
举3个例子:
ffmpeg -i input.mp4 -profile:v baseline -level 3.0 output_baseline_30.h264
ffmpeg -i input.mp4 -profile:v main -level 4.2 output_main_42.h264
ffmpeg -i input.mp4 -profile:v high -level 5.1 output_high_51.h264
转码后用mediainfo进行分析
-
output_baseline_30.h264 baseline对应profile_idc = 66,level对应level_idc=30。
-
output_main_42.h264 baseline对应profile_idc = 77,level对应level_idc=42。
-
output_high_51.h264 baseline对应profile_idc = 100,level对应level_idc=51。
如果ffmpeg编译时加了external的libx264,那就这么写:
ffmpeg -i input.mp4 -c:v libx264 -x264-params "profile=high:level=3.0" output.mp4
通常情况下压缩比例来说,baseline< main < high,对于带宽比较局限的在线视频,可能会选择high,但有些时候,做个小视频,希望所有的设备基本都能解码(有些低端设备或早期的设备只能解码 baseline),那就牺牲文件大小吧,用baseline!