帧格式

H264帧由NALU头和NALU主体组成。
NALU头由一个字节组成,它的语法如下:

+---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+

F: 1个比特.
  forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.

NRI: 2个比特.
  nal_ref_idc. 取00~11,似乎指示这个NALU的重要性,如00的NALU解码器可以丢弃它而不影响图像的回放,0~3,取值越大,表示当前NAL越重要,需要优先受到保护。如果当前NAL是属于参考帧的片,或是序列参数集,或是图像参数集这些重要的单位时,本句法元素必需大于0。

Type: 5个比特.
  nal_unit_type. 这个NALU单元的类型,1~12由H.264使用,24~31由H.264以外的应用使用,简述如下:

0     没有定义
  1-23  NAL单元  单个 NAL 单元包
  1     不分区,非IDR图像的片
  2     片分区A
  3     片分区B
  4     片分区C
  5     IDR图像中的片
  6     补充增强信息单元(SEI)
  7     SPS
  8     PPS
  9     序列结束
  10    序列结束
  11    码流借宿
  12    填充
  13-23 保留

24    STAP-A   单一时间的组合包
  25    STAP-B   单一时间的组合包
  26    MTAP16   多个时间的组合包
  27    MTAP24   多个时间的组合包
  28    FU-A     分片的单元
  29    FU-B     分片的单元
  30-31 没有定义

AUD

一般文档没有对AUD进行描叙,其实这是一个帧开始的标志,字节顺序为:00 00 00 01 09 f0
从结构上看,有start code, 所以确实是一个NALU,类型09在H264定义里就是AUD(分割器)。大部分播放器可以在没有AUD的情况下正常播放。
        紧随AUD,一般是SPS/PPS/SEI/IDR的组合或者简单就是一个SLICE,也就是一个帧的开始。像Flash这样的播放器,每次需要一个完整的帧数据,那么把2个AUD之间的数据按照格式打包给播放器就可以了。

H.264编码时,在每个NAL前添加起始码 0x000001,解码器在码流中检测到起始码,当前NAL结束。为了防止NAL内部出现0x000001的数据,h.264又提出'防止竞争 emulation prevention"机制,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03。当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。
   0x000000  >>>>>>  0x00000300
   0x000001  >>>>>>  0x00000301
   0x000002  >>>>>>  0x00000302
   0x000003  >>>>>>  0x00000303

总的来说H264的码流的打包方式有两种,一种为annex-b byte stream format 的格式,这个是绝大部分编码器的默认输出格式,就是每个帧的开头的3~4个字节是H264的start_code,0x00000001或者0x000001。
另一种是原始的NAL打包格式,就是开始的若干字节(1,2,4字节)是NAL的长度,而不是start_code,此时必须借助某个全局的数据来获得编 码器的profile,level,PPS,SPS等信息才可以解码。

SPS,PPS的解析

SPS
profile_idc和level_idc是指比特流所遵守的配置和级别。

constraint_set0_flag 等于1是指比特流遵从某节中的所有规定。constraint_set0_flag 等于0是指该比特流可以遵从也可以不遵从某节中的所有规定。当profile_idc等于100、110、122或144时,constraint_set0_flag、constraint_set1_flag和constraint_set2_flag都应等于0。

log2_max_frame_num_minus4的值应在0-12范围内(包括0和12),这个句法元素主要是为读取另一个句法元素 frame_num  服务的,frame_num  是最重要的句法元素之一,它标识所属图像的解码顺序 。这个句法元素同时也指明了 frame_num 的所能达到的最大值: MaxFrameNum = 2*exp( log2_max_frame_num_minus4 + 4 ) 。

pic_order_cnt_type 是指解码图像顺序的计数方法。pic_order_cnt_type 的取值范围是0到2(包括0和2)。

log2_max_pic_order_cnt_lsb_minus4表示用于某节规定的图像顺序数解码过程中的变量MaxPicOrderCntLsb的值,

num_ref_frames规定了可能在视频序列中任何图像帧间预测的解码过程中用到的短期参考帧和长期参考帧、互补参考场对以及不成对的参考场的最大数量。num_ref_frames 的取值范围应该在0到MaxDpbSize。

gaps_in_frame_num_value_allowed_flag 表示某节给出的frame_num 的允许值以及在某节给出的frame_num 值之间存在推测的差异的情况下进行的解码过程。

pic_width_in_mbs_minus1加1是指以宏块为单元的每个解码图像的宽度。
pic_height_in_map_units_minus1 的语义依赖于变量frame_mbs_only_flag,规定如下:-— 如果 frame_mbs_only_flag 等于0,

pic_height_in_map_units_minus1加1就表示以宏块为单位的一场的高度。-— 否则(frame_mbs_only_flag等于1),pic_height_in_map_units_minus1加1就表示

以宏块为单位的一帧的高度。变量 FrameHeightInMbs 由下列公式得出:FrameHeightInMbs = ( 2 – frame_mbs_only_flag ) * PicHeightInMapUnits。

mb_adaptive_frame_field_flag 等于0表示在一个图像的帧和场宏块之间没有交换。mb_adaptive_frame_field_flag 等于1表示在帧和帧内的场宏块之间可能会有交换。当mb_adaptive_frame_field_flag没有特别规定时,默认其值为0。

direct_8x8_inference_flag 表示在某节中规定的B_Skip、B_Direct_16x16和B_Direct_8x8亮度运动矢量的计算过程使用的方法。当frame_mbs_only_flag 等于0时

direct_8x8_inference_flag 应等于1。

frame_cropping_flag 等于1表示帧剪切偏移参数遵从视频序列参数集中的下一个值。frame_cropping_flag 等于0表示不存在帧剪切偏移参数。

vui_parameters_present_flag 等于1 表示存在如附录E 提到的vui_parameters( ) 语法结构。vui_parameters_present_flag 等于0表示不存在如附录E提到的vui_parameters( ) 语法结构。

PPS 
seq_parameter_set_id是指活动的序列参数集。变量seq_parameter_set_id的值应该在0到31的范围内(包括0和31)。

entropy_coding_mode_flag 用于选取语法元素的熵编码方式,在语法表中由两个标识符代表,具体如下:如果entropy_coding_mode_flag 等于0,那么采用语法表中左边的描述符所指定的方法。
pic_order_present_flag等于1 表示与图像顺序数有关的语法元素将出现于条带头中,pic_order_present_flag 等于0表示条带头中不会出现与图像顺序数有关的语法元素。

num_slice_groups_minus1加1表示一个图像中的条带组数。当num_slice_groups_minus1 等于0时,图像中所有的条带属于同一个条带组。

num_ref_idx_l0_active_minus1表示参考图像列表0 的最大参考索引号,该索引号将用来在一幅图像中num_ref_idx_active_override_flag 等于0 的条带使用列表0 预测时,解码该图像的这些条带。当MbaffFrameFlag等于1时,num_ref_idx_l0_active_minus1 是帧宏块解码的最大索引号值,而2 *num_ref_idx_l0_active_minus1 + 1是场宏块解码的最大索引号值。num_ref_idx_l0_active_minus1 的值应该在0到31的范围内(包括0和31)。

weighted_pred_flag等于0表示加权的预测不应用于P和SP条带。weighted_pred_flag等于1表示在P和SP条带中应使用加权的预测。

weighted_bipred_idc等于0表示B条带应该采用默认的加权预测。weighted_bipred_idc等于1表示B条带应该采用具体指明的加权预测。weighted_bipred_idc 等于2表示B 条带应该采用隐含的加权预测。
weighted_bipred_idc 的值应该在0到2之间(包括0和2)。

pic_init_qp_minus26表示每个条带的SliceQPY 初始值减26。当解码非0值的slice_qp_delta 时,该初始值在条带层被修正,并且在宏块层解码非0 值的mb_qp_delta 时进一步被修正。pic_init_qp_minus26 的值应该在-(26 + QpBdOffsetY ) 到 +25之间(包括边界值)。

pic_init_qs_minus26表示在SP 或SI 条带中的所有宏块的SliceQSY 初始值减26。当解码非0 值的slice_qs_delta 时,该初始值在条带层被修正。pic_init_qs_minus26 的值应该在-26 到 +25之间(包括边界值)。

chroma_qp_index_offset表示为在QPC 值的表格中寻找Cb色度分量而应加到参数QPY 和 QSY 上的偏移。chroma_qp_index_offset的值应在-12 到 +12范围内(包括边界值)。

deblocking_filter_control_present_flag等于1 表示控制去块效应滤波器的特征的一组语法元素将出现在条带头中。deblocking_filter_control_present_flag 等于0 表示控制去块效应滤波器的特征的一组语法元素不会出现在条带头中,并且它们的推定值将会生效。

constrained_intra_pred_flag等于0 表示帧内预测允许使用残余数据,且使用帧内宏块预测模式编码的宏块的预测可以使用帧间宏块预测模式编码的相邻宏块的解码样值。constrained_intra_pred_flag 等于1 表示受限制的帧内预测,在这种情况下,使用帧内宏块预测模式编码的宏块的预测仅使用残余数据和来自I或SI宏块类型的解码样值。

redundant_pic_cnt_present_flag等于0 表示redundant_pic_cnt 语法元素不会在条带头、图像参数集中指明(直接或与相应的数据分割块A关联)的数据分割块B和数据分割块C中出现。redundant_pic_cnt_present_flag等于1表示redundant_pic_cnt 语法元素将出现在条带头、图像参数集中指明(直接或与相应的数据分割块A关联)的数据分割块B和数据分割块C中。

分包

h264包在传输的时候,如果包太大,会被分成多个片。NALU头会被如下的2个自己代替。

The FU indicator octet has the following format:

+---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+

别被名字吓到这个格式就是上面提到的RTP h264负载类型,Type为FU-A

The FU header has the following format:

+---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |S|E|R|  Type   |
      +---------------+

S bit为1表示分片的NAL开始,当它为1时,E不能为1
   E bit为1表示结束,当它为1,S不能为1

R bit保留位

Type就是NALU头中的Type,取1-23的那个值

参见:http://blog.csdn.net/evsqiezi/article/details/8492593

H264帧的分析sps pps相关推荐

  1. sps和pps一篇好的解释 H264码流中SPS PPS详解<转>

    https://blog.csdn.net/luzubodfgs/article/details/86775940 H264码流中NALU sps pps IDR帧的理解 https://blog.c ...

  2. H264码流中SPS PPS

    转载地址:https://www.cnblogs.com/wainiwann/p/7477794.html 1 SPS和PPS从何处而来? 2 SPS和PPS中的每个参数起什么作用? 3 如何解析SD ...

  3. CMSampleBufferRef获取h264 char*数据及sps/pps

    直接看代码: CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuf);size_t len_offset = 0 , ...

  4. FFmpeg SPS/PPS剖析

    场景说明             在解码过程中,需要设置SPS/PPS等解码信息,才能够初始化解码器.有两种方式可以设置SPS/PPS,一种是手动指定SPS/PPS内容,指定AVCodecContex ...

  5. H264 帧、pps 、sps

    H264帧 对于H.264而言,每帧的界定符为00 00 00 01 或者00 00 01. 例如下面是一个H264的文件片段 00 00 00 01 67 42 C0 28 DA 01 E0 08 ...

  6. H264——H264码流分析实例(SPS、PPS)

    目录 工具 原理 NALU SPS PPS 实例视频二进制数据 SPS分析 nal_header profile_idc level_idc seq_parameter_set_id chroma_f ...

  7. H264 SPS/PPS 分析

    文章目录 SPS 文件分析 PPS分析 SPS 文件分析 H264文件对应的SPS参数如下: 9816B 的SPS 长度为20: 00 00 00 01 67 4D 00 2A 96 35 40 F0 ...

  8. 【H264码流分析】 SPS/PPS/Slice Header

    SPS中相关 H264 Profile 对视频压缩特性的描述,Profile越高,就说明采用了越高级的压缩特性 H264 Level Level是对视频的描述,Levrl越高,视频的码率,分辨率,fp ...

  9. 给h264帧增加start code和sps/pps

    从音视频文件中读取数据,抽取其中的h264视频数据,并保存在文件中,如果想要此文件被播放器正常解码播放,还需要添加在每个帧之前添加start code,在每个关键帧前添加sps/pps. 播放器需要知 ...

最新文章

  1. 使用Python+OpenCV预测年龄与性别
  2. 面向dba的linux shell 脚本简介,面向 DBA 的 Linux Shell 脚本简介
  3. tensorflow学习:分布式tensorflow使用,代码实现inGraph方式
  4. java的import关键字的使用
  5. js的跨域问题和解决办法
  6. 使用Android自带DownloadManager下载文件
  7. SpringBoot, 启动类,使用「SpringBootApplication」标注
  8. ffmpeg中的sws_scale算法性能测试
  9. 【mybatis】 mybatis在mysql 更新update 操作 更新时间字段按照年月日时分秒格式 更新为当前时间...
  10. MyBatis分页插件PageHelper
  11. 从键盘输入二叉树怎么输入_手机输入法派别之争!九宫格和全键盘谁才是正统...
  12. Java开发必备软件安装大全(建议学生党初学Java开发收藏)
  13. 小米4 miui6 android,小米4 rom刷机包 4.10.11(MIUI6) 官方最新版
  14. retrofit简单的网络请求
  15. Go语言优秀的Revel开源框架推荐
  16. 灰灰考研c语言讲义,【灰灰考研】操作系统复习全书.pdf
  17. Mysql配置ssl证书
  18. 第七章第三十一题(合并两个有序列表)(Merge two ordered tables)
  19. BP_TOOLS_MODE[] = bp-tools
  20. redis主从复制,主读不到从节点信息的坑

热门文章

  1. [转]计算机视觉之跟踪算法——相关滤波器Correlation Filter
  2. 如何借助配置中心ACM加速企业IT服务快速迭代
  3. Python 学习笔记9(装饰器,decorator)
  4. ubuntu网站收集
  5. 防止内存泄露 Linux下用Valgrind做检查
  6. 微软公司将在英国开设三个数据中心
  7. JS 实现3D立体效果的首页轮播图(瞬间让你的网站高大上,逼格满满)
  8. 使用Spire.Barcode程序库生成二维码
  9. NSArray中存的是实体时的排序
  10. 配置gitlab环境实现代码管理及Web Hook测试和ldap认证