H264编解码 分析一 SPS (编解码未懂)

前言

RTP完整流程 已经 解释了协议 所以要涉及具体的log分析
分为:
SPS \ PPS\I帧\非I帧\FU-A

SPS 序列参数集合

SPS 属于 [RTP header] + 单一NAL单元模式 ,所以RTP包结构如下

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI|  type   |                                               |
+-+-+-+-+-+-+-+-+                                               |
|                                                               |
|               Bytes 2..n of a Single NAL unit                 |
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               :...OPTIONAL RTP padding        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

先看 抓到的 dump

0000   80 60 e2 1d ff 6d 85 0f c6 0a 3f ef 67 64 00 29   .`â.ÿm..Æ.?ïgd.)
0010   ac 52 0a 01 40 16 ec 04 40 00 00 fa 40 00 2e e0   ¬R..@.ì.@..ú@..à
0020   23 c6 0c 62 a0                                    #Æ.b 

在上面12个byte是 [RTP Header] 对应的码流

80 60 e2 1d 
ff 6d 85 0f 
c6 0a 3f ef 
====>转化 二进制
1000 0000 0110 0000 1110 0010 0001 1101 v=2 p=0 x=0 CC=0 M=0 PT=96 SN=57885 
1111 1111 0110 1101 1000 0101 0000 1111 timestamp 
1100 0110 0000 1010 0011 1111 1110 1111 ssrc 

对应wireshark 解析

Real-Time Transport Protocol
    10.. .... = Version: RFC 1889 Version (2)
    ..0. .... = Padding: False
    ...0 .... = Extension: False
    .... 0000 = Contributing source identifiers count: 0 
    0... .... = Marker: False
    Payload type: DynamicRTP-Type-96 (96)
    Sequence number: 57885
    Timestamp: 4285367567
    Synchronization Source identifier: 0xc60a3fef (3322560495)

NALU 码流 .根据单一NAL单元模式 判断 前1byte 是[NALU Header]

0000   67 64 00 29 ac 52 0a 01 40 16 ec 04 40 00 00 fa   gd.)¬R..@.ì.@.0010   40 00 2e e0 23 c6 0c 62 a0                        @..à#Æ.b 
===> 转化 前一个字节
0110 0111  F=0 NRI=11 特别重要 type=7 说明是sps  

wireshark 解析

H.264
    NAL unit header or first byte of the payload
        0... .... = F bit: No bit errors or other syntax violations
        .11. .... = Nal_ref_idc (NRI): 3
        ...0 0111 = Type: NAL unit - Sequence parameter set (7)

剩下的就看下H264 NAL Unit Payload NALU的负载

NALU payload
64 00 29 ac 52 0a 01 40 16 ec 04 40 00 00 fa
40 00 2e e0 23 c6 0c 62 a0

从下面的 解析就知道意义

H264 NAL Unit Payload
        0110 0100 = Profile_idc: High profile (100)
        0... .... = Constraint_set0_flag: 0
        .0.. .... = Constraint_set1_flag: 0
        ..0. .... = Constraint_set2_flag: 0
        ...0 .... = Constraint_set3_flag: 0
        .... 0... = Constraint_set4_flag: 0
        .... .0.. = Constraint_set5_flag: 0
        .... ..00 = Reserved_zero_2bits: 0
        0010 1001 = Level_id: 41 [Level 4.1 50 Mb/s]
        1... .... = seq_parameter_set_id: 0
        .010 .... = chroma_format_id: 1
        .... 1... = bit_depth_luma_minus8: 0
        .... .1.. = bit_depth_chroma_minus8: 0
        .... ..0. = qpprime_y_zero_transform_bypass_flag: 0
        .... ...0 = seq_scaling_matrix_present_flag: 0
        010. .... = log2_max_frame_num_minus4: 1
        ...1 .... = pic_order_cnt_type: 0
        .... 0010  0... .... = log2_max_pic_order_cnt_lsb_minus4: 3
        .000 1010 = num_ref_frames: 9
        0... .... = gaps_in_frame_num_value_allowed_flag: 0
        .000 0001  0100 00.. = pic_width_in_mbs_minus1: 79
        .... ..00  0001 0110  1... .... = pic_height_in_map_units_minus1: 44
        .1.. .... = frame_mbs_only_flag: 1
        ..1. .... = direct_8x8_inference_flag: 1
        ...0 .... = frame_cropping_flag: 0
        .... 1... = vui_parameters_present_flag: 1
        .... .1.. = aspect_ratio_info_present_flag: 1
        .... ..00  0000 01.. = aspect_ratio_idc: 1
        .... ..0. = overscan_info_present_flag: 0
        .... ...0 = video_signal_type_present_flag: 0
        0... .... = chroma_loc_info_present_flag: 0
        .1.. .... = timing_info_present_flag: 1
        ..00 0000  0000 0000  0000 0000  1111 1010  01.. .... = num_units_in_tick: 1001
        ..00 0000  0000 0000  0010 1110  1110 0000  00.. .... = time_scale: 48000
        ..1. .... = fixed_frame_rate_flag: 1
        ...0 .... = nal_hrd_parameters_present_flag: 0
        .... 0... = vcl_hrd_parameters_present_flag: 0
        .... .0.. = pic_struct_present_flag: 0
        .... ..1. = bitstream_restriction_flag: 1
        .... ...1 = motion_vectors_over_pic_boundaries_flag: 1
        1... .... = max_bytes_per_pic_denom: 0
        .1.. .... = max_bits_per_mb_denom: 0
        ..00 0110  0... .... = max_mv_length_horizontal: 11
        .000 1100 = log2_max_mv_length_vertical: 11
        011. .... = num_reorder_frames: 2
        ...0 0010  10.. .... = max_dec_frame_buffering: 9
        ..1. .... = rbsp_stop_bit: 1
        ...0 0000 = rbsp_trailing_bits: 0

这些参数意义,在 新一代视频压缩编码标准H.264(毕厚杰) 第七章 7.3

Profile_idc : 指明 所用的profile 占用8bit
Constraint_set0_flag:
Constraint_set1_flag
Constraint_set2_flag
Constraint_set3_flag
Constraint_set4_flag
Constraint_set5_flag 
为0 表示不用遵循 附录 A.2的相关条件 应该是协议文档中附录

Reserved_zero_2bits :必须是0
Level_id:指明 level
seq_parameter_set_id:指明本序列参数集的 id 号,这个 id 号将被 picture 参数集引用 ,[0~31]
chroma_format_id:色度采样结构
bit_depth_luma_minus8:指定了亮度矩阵的比特深度以及亮度量化参数范围偏移量;此处取0,表示每个亮度像素用8为表示,QpBdOffset参数为0

bit_depth_chroma_minus8:和bit_depth_luma_minus8 类似 只不过是针对色度的
qpprime_y_zero_transform_bypass_flag:
seq_scaling_matrix_present_flag:

log2_max_frame_num_minus4: 主要为了获取 frame_num 服务的,frame_num  标识所属图像的解码顺序
,fram-num的解码函数是 ue(v),函数中的 v 在这里指定:
            v = log2_max_frame_num_minus4 + 4
也指明了 frame_num 的所能达到的最大值: 
            MaxFrameNum = 2( log2_max_frame_num_minus4 + 4 )
变量 MaxFrameNum 表示 frame_num 的最大值,在解码过程中它也是一个非常重要的变量。
 frame_num 是循环计数的,即当它到达 MaxFrameNum 后又从 0 重新开始新一轮
的计数。解码器必须要有机制检测这种循环,不然会引起类似千年虫的问题,在图像的顺序上造成
混乱。

pic_order_cnt_type:指明了 poc (picture order count) 的编码方法,poc 标识图像的播放顺序。
由于H.264 使用了 B 帧预测,使得图像的解码顺序并不一定等于播放顺序,但它们之间存在一定的映射
关系。poc 可以由 frame-num 通过映射关系计算得来
H.264 中一共定义了三种 poc 的编码方法,这个句法元素就是用来通知解码器该用哪种方法来计算poc

log2_max_pic_order_cnt_lsb_minus4:指明了变量 MaxPicOrderCntLsb 的值:
MaxPicOrderCntLsb = 2( log2_max_pic_order_cnt_lsb_minus4 + 4 )
该变量在 pic_order_cnt_type = 0 时使用。

num_ref_frames:指定参考帧队列可能达到的最大长度,解码器依照这个句法元素的值开辟存储区,
这个存储区用于存放已解码的参考帧, H.264 规定最多可用 16 个参考帧,本句法元素的值最大为 16

gaps_in_frame_num_value_allowed_flag:这个句法元素等于 1 时,表示允许句法元素 frame_num 可
以不连续。当传输信道堵塞严重时,编码器来不及将编码后的图像全部发出,这时允许丢弃若干帧
图像
pic_width_in_mbs_minus1:本句法元素加 1 后指明图像宽度,以宏块为单位:
    PicWidthInMbs = pic_width_in_mbs_minus1 + 1
通过这个句法元素解码器可以计算得到亮度分量以像素为单位的图像宽度:
    PicWidthInSamplesL = PicWidthInMbs * 16
从而也可以得到色度分量以像素为单位的图像宽度:
    PicWidthInSamplesC = PicWidthInMbs * 8
以上变量 PicWidthInSamplesL、PicWidthInSamplesC 分别表示图像的亮度、色度分量以像素为单位
的宽
pic_height_in_map_units_minus1:本句法元素加 1 后指明图像高度:
    PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1
    PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits
图像的高度的计算要比宽度的计算复杂,因为一个图像可以是帧也可以是场,从这个句法元素可以
在帧模式和场模式下分别计算出出亮度、色度的高。值得注意的是,这里以 map_unit 为单位

frame_mbs_only_flag: 等于 0 时表示本序列中所有图像的编码模式都是帧,没有其他编
码模式存在;等于 1 时 ,表示本序列中图像的编码模式可能是帧,也可能是场或帧场自适应
某个图像具体是哪一种要由其他元素决定
结合 map_unit 的含义,这里给出上一个句法元素 pic_height_in_map_units_minus1 的进一步解析步骤:
当 frame_mbs_only_flag 等于1,pic_height_in_map_units_minus1 指的是一个 picture 中帧的高度;当
frame_mbs_only_flag 等于0,pic_heght_in_map_units_minus1 指的是一个 picture 中场的高度,所以
可以得到如下以宏块为单位的图像高度:
    FrameHeightInMbs = ( 2 – frame_mbs_only_flag ) * PicHeightInMapUnits
    PictureHeightInMbs= ( 2 – frame_mbs_only_flag ) * PicHeightInMapUnits

direct_8x8_inference_flag: 用于指明 B 片的直接和 skip 模式下运动矢量的预测方法
frame_cropping_flag: 用于指明解码器是否要将图像裁剪后输出,如果是的话,后面紧跟着的
四个句法元素分别指出左右、上下裁剪的宽度。
分别是frame_crop_left_offset,frame_crop_right_offset
,frame_crop_bottom_offset,frame_crop_bottom_offset

vui_parameters_present_flag: 指明 vui 子结构是否出现在码流中 用以表征视频格式等额外信息 
aspect_ratio_info_present_flag: 
aspect_ratio_idc: 
overscan_info_present_flag: 
video_signal_type_present_flag: 
chroma_loc_info_present_flag: 
timing_info_present_flag: 
num_units_in_tick: 
time_scale: 48000
fixed_frame_rate_flag: 
nal_hrd_parameters_present_flag: 
vcl_hrd_parameters_present_flag: 
pic_struct_present_flag: 
bitstream_restriction_flag: 
motion_vectors_over_pic_boundaries_flag: 1
max_bytes_per_pic_denom: 
max_bits_per_mb_denom: 
max_mv_length_horizontal: 
log2_max_mv_length_vertical: 
num_reorder_frames: 
max_dec_frame_buffering: 
rbsp_stop_bit:
rbsp_trailing_bits:

解码的元素好多? 标记


猜你喜欢

转载自blog.csdn.net/engineer_james/article/details/81750864