参考链接:1. 解析H264的SPS信息 https://blog.csdn.net/lizhijian21/article/details/80982403
2. h.264的POC计算 https://www.cnblogs.com/TaigaCon/p/3551001.html
3. 视音频数据处理入门:H.264视频码流解析 https://blog.csdn.net/leixiaohua1020/article/details/50534369
代码中的注释, 有对SPS,PPS,SLICE的分析,未进行代码分析(有些可能不准确)。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <arpa/inet.h> 5 6 #define TAB44 " " 7 #define PRINTF_DEBUG 8 9 #define PRTNTF_STR_LEN 10 10 11 /************************************************************************************************************ 12 ** nalu header: 负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中, 13 覆盖了所有片级以上的语法级别(NALU的作用, 方便网络传输) 14 ** 15 ------------------------------------------------------------------------------------------------------------- 16 ** 字段名称 | 长度(bits) | 有关描述 17 ------------------------------------------------------------------------------------------------------------- 18 ** forbidden_bit | 1 | 编码中默认值为0, 当网络识别此单元中存在比特错误时, 可将其设为1, 以便接收方丢掉该单元 19 ** nal_reference_idc | 2 | 0~3标识这个NALU的重要级别 20 ** nal_unit_type | 5 | NALU的类型(类型1~12是H.264定义的, 类型24~31是用于H.264以外的, 21 RTP负荷规范使用这其中的一些值来定义包聚合和分裂, 其他值为H.264保留) 22 23 ** nal_unit_type: 24 0 未使用 25 1 未使用Data Partitioning, 非IDR图像的Slice 26 2 使用Data Partitioning且为Slice A 27 3 使用Data Partitioning且为Slice B 28 4 使用Data Partitioning且为Slice C 29 5 IDR图像的Slice(立即刷新) 30 6 补充增强信息(SEI) 31 7 序列参数集(sequence parameter set, SPS) 32 8 图像参数集(picture parameter set, PPS) 33 9 分界符 34 10 序列结束 35 11 码流结束 36 12 填充 37 13...23 保留 38 24...31 未使用 39 40 ** SPS, PPS. SLICE等信息就不解析了. 为了减少bits, 用了哥伦布编码(自己解析比较麻烦, 但是网上有很多). 41 42 ** SPS信息说明: 43 1. 视频宽高, 帧率等信息; 44 2. seq_parameter_set_id, 指明本序列参数集的id号, 这个id号将被picture参数集引用; 45 3. pic_width_in_mbs_minus1, 加1指定以宏块(16*16)为单位的每个解码图像的宽度, 即width = (pic_width_in_mbs_minus1 + 1) * 16 46 4. pic_height_in_map_units_minus1; 47 5. pic_order_cnt_type, 视频的播放顺序序号叫做POC(picture order count), 取值0,1,2; 48 6. time_scale, fixed_frame_rate_flag, 计算帧率(fps). 49 视频帧率信息在SPS的VUI parameters syntax中, 需要根据time_scale, fixed_frame_rate_flag计算得到: fps = time_scale / num_units_in_tick. 50 但是需要判断参数timing_info_present_flag是否存在, 若不存在表示FPS在信息流中无法获取. 51 同时还存在另外一种情况: fixed_frame_rate_flag为1时, 两个连续图像的HDR输出时间频率为单位, 获取的fps是实际的2倍. 52 53 ** PPS信息说明: 54 1. pic_parameter_set_id, 用以指定本参数集的序号, 该序号在各片的片头被引用; 55 2. seq_parameter_set_id, 指明本图像参数集所引用的序列参数集的序号; 56 3. 其他高深的暂时还不理解, 指明参考帧队列等. 57 58 ** SLICE信息说明: 59 1. slice_type, 片的类型; 60 2. pic_parameter_set_id, 引用的图像索引; 61 3. frame_num, 每个参考帧都有一个连续的frame_num作为它们的标识, 它指明了各图像的解码顺序. 非参考帧也有,但没有意义; 62 4. least significant bits; 63 5. 综合三种poc(pic_order_cnt_type), 类型2应该是最省bit的, 因为直接从frame_num获得, 但是序列方式限制最大; 64 类型1, 只需要一定的bit量在sps标志出一些信息还在slice header中表示poc的变化, 但是比类型0要节省bit, 但是其序列并不是随意的, 要周期变化; 65 对于类型0因为要对poc的lsb(pic_order_cnt_lsb, last bit)进行编码所以用到的bit最多, 优点是序列可以随意. 66 ** 自我理解, 不一定准确(这边算显示顺序, 要根据SPS中的pic_order_cnt_type, 为2, 意味着码流中没有B帧, frame_num即为显示顺序; 67 为1, 依赖frame_num求解POC; 为0, 把POC的低位编进码流内, 但这只是低位, 而POC的高位PicOrderCntMsb则要求解码器自行计数, 68 计数方式依赖于前一编码帧(PrevPicOrderCntMsb与PrevPicOrderCntLsb. 69 70 ** 一般的码流分析所见(未