前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >H.264编码格式简单分析

H.264编码格式简单分析

作者头像
望天
发布2019-07-11 13:36:35
1.8K0
发布2019-07-11 13:36:35
举报
文章被收录于专栏:along的开发之旅along的开发之旅

  H.264的重要性不再提了。本文主要记录一下H.264的编码格式。H.264官方文档:https://github.com/jiayayao/DataSheet/tree/master/encode-decode/h264

  H.264从层次来看分为两层:视频编码层(VCL, Video Coding Layer)和网络提取层(NAL,Network Abstraction Layer)。VCL输出的是原始数据比特流(SODB,String of data bits),表示H.264的语法元素编码完成后的实际的原始二进制码流。SODB通常不能保证字节对齐,故需要补齐为原始字节序列负荷(RBSP,Raw Byte Sequence Payload)。NAL层实际上就是最终输出的H.264码流,它是由一个个NALU组成的,每个NALU包括一组对应于视频编码数据的NAL头信息和一个原始字节序列负荷(RBSP,Raw Byte Sequence Payload)。以上名词之间的关系如下:

代码语言:javascript
复制
RBSP = SODB + RBSP trailing bits
NALU = NAL header(1 byte) + RBSP
H.264 = Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU +…

  所以H.264码流的结构如下:

  每个NALU之间由起始码(Start Code Prefix)分隔,起始码分为两种:0x000001(3 bytes) or 0x00000001(4 bytes). 如果NALU 对应的Slice 为一帧的开始,则用4 字节表示,即0x00000001;否则用3 字节表示,0x000001.NALU针对起始码设计了防止冲突机制,如果出现连续的0x000000,0x000001,0x000002,0x000003时,会在两个0之间插入03,如下:

代码语言:javascript
复制
0x00 00 00 -> 0x00 00 03 00
0x00 00 01 -> 0x00 00 03 01
0x00 00 02 -> 0x00 00 03 02
0x00 00 03 -> 0x00 00 03 03

  一个NALU就是编码后的一帧数据。NAL header是一个字节:

  forbidden_zero_bit(1 bit) 禁止位,等于0;

  nal_ref_idc(2 bit)指示当前NAL的优先级,取值范围为0~3,值越高,表示当前NAL越重要。H.264规定,如果当前NAL是序列参数集,或是图像参数等,该值必须大于0.比如nal_unit_type等于5时,nal_ref_idc大于0;nal_unit_type等于6,9,10,11或12时,nal_ref_idc等于0;

  nal_unit_type表示当前NALU的类型,表格如下:

nal_unit_type

NAL类型

C

0

未使用

1

不分区、非IDR图像的片

2,3,4

2

片分区A

2

3

片分区B

3

4

片分区C

4

5

IDR图像中的片

2,3

6

补充增强信息单元(SEI)

5

7

序列参数集(SPS)

0

8

图像参数集(PPS)

1

9

分界符

6

10

序列结束

7

11

码流结束

8

12

填充

9

13~23

保留

24~31

未使用

  nal_unit_type=5时,表示当前NAL是IDR图像的一个片,此时,IDR图像中的每个片的nal_unit_type都应该等于5.

  一般H.264原始码流是以SPS->PPS->SEI->IDR->SCLICE->SCLICE…开头的。

  GOP即Group of picture(图像组),指两个I帧之间的距离。即几秒有一个关键帧。一般在2、3秒之间。

  H.264有两种封装格式:

  (1)annexb模式:传统模式,使用start code来分隔NAL, SPS和PPS是在ES流的头部;

Annex-B: startCode Nalu1, startCode Nalu2......startCode NaluN

  (2)mp4模式:没有start code,使用NALU长度(固定字节,通常为4个字节)来分隔NAL。AVCodecContext的extradata内部保存着分隔的字节数,SPS和PPS;

mp4(AVCC): NaluLength Nalu1, LaluLength Lalu2, ......NaluLength NaluN

  SPS的头部是0x67,PPS的头部是0x68,要保持对数据的敏感性。

  当解码器性能不足需要丢帧时,nal_ref_idc可以作为判断能否丢帧的依据。如果nal_ref_idc为0,则可以丢弃。当该帧nal_unit_type等于6,9,10,11或12时,nal_ref_idc为0。部分非IDR帧的nal_ref_idc也为0,也可以丢弃。丢弃的同时也能保证不会花屏。

  附:

  leixiaohua的H.264分析器,本人在此基础上做了大量注释,方便理解H.264:https://github.com/jiayayao/h264_analysis

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档