Android RTMP协议直播之H264标准(一)

视频编码

视频编码是指一个能够对数字视频进行压缩或者解压缩的程序或者设备。通常这种压缩属于有损数据压缩。所谓视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式。视频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264,运动静止图像专家组的M-JPEG和国际标准化组织运动图像专家组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo、微软公司的WMV以及Apple公司的QuickTime等。注:以上来自维基百科&百度百科

常用的视频编解码器

  • MPEG(Moving Picture Experts Group)以MPEG组织制定MPEG-X系列标准编码,MPEG组织制定的各个标准都有不同的目标和应用。视频编码方面主要是Mpeg1(vcd用的就是它)、Mpeg2(DVD使用)、Mpeg4(的DVDRIP使用的都是它的变种,如:divx,xvid等)、Mpeg4 AVC(正热门);音频编码方面主要是MPEG Audio Layer 1/2、MPEG Audio Layer 3(大名鼎鼎的mp3)、MPEG-2 AAC 、MPEG-4 AAC等等。注:DVD音频没有采用Mpeg的
  • H.26X 由[ITU-T]制定开发,包含了包括H.261、H.262、H.263、H.263+、H.263++、H.264。

H264编码

H264 MPEG-4的一部分(MPEG-4 Part 10, Advanced Video Coding,缩写为MPEG-4 AVC)是一种面向块,基于运动补偿的视频编码标准。

H.264/AVC项目的目的是为了创建一个更佳的视频压缩标准,在更低的比特率的情况下依然能够提供良好视频质量的标准(如,一半或者更少于MPEG-2,H.263,或者MPEG-4 Part2 )。同时,还要不会太大的增加设计的复杂性。H.264的另外一个目标是提供足够的灵活性,以允许该标准能够应用于各种各样的网络和系统的各应用上,包括低和高比特率,低和高分辨率视频,广播,DVD存储,RTP / IP分组网络和ITU-T多媒体电话系统。H.264标准可以被视为由多个不同的应用框架 / 配置文件(profiles)组成的“标准系列”。

H264标准各主要部分有Access Unit delimiter(访问单元分割符),SEI(附加增强信息),primary coded picture(基本图像编码),Redundant Coded Picture(冗余图像编码)。还有Instantaneous Decoding Refresh(IDR,即时解码刷新)、Hypothetical Reference Decoder(HRD,假想参考解码)、Hypothetical Stream Scheduler(HSS,假想码流调度器)。

H264编码框架结构

H264码流文件分为两层:

  1. VCL(Video Coding Layer)视频编码层:负责高效的视频内容表示,VCL 数据即编码处理的输出,它表示被压缩编码后的视频数据序列。
  2. NAL(Network Abstraction Layer)网络提取层:负责以网络所要求的恰当的方式对数据进行打包和传送,是传输层,不管是在本地播放还是在网络播放的传输,都要通过这一层来传输。

H264编码原理

在H264协议里定义了三种帧,完整编码的帧叫I帧,参考之前的I帧生成的只包含差异部分编码的帧叫P帧,还有一种参考前后的帧编码的帧叫B帧。

在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以I帧开始,到下一个I帧结束。一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR图像都是 I 帧图像,但是I帧不一定是IDR。

  1. I帧
    I帧:帧内编码帧 ,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
    I帧特点:
    • 它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;
    • 解码时仅用I帧的数据就可重构完整图像;
    • I帧描述了图像背景和运动主体的详情;
    • I帧不需要参考其他画面而生成;
    • I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
    • I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;
    • I帧不需要考虑运动矢量;
    • I帧所占数据的信息量比较大。
  2. P帧
    P帧:前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
    P帧的预测与重构:P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,从而可得到完整的P帧。
    P帧特点:
    • P帧是I帧后面相隔1~2帧的编码帧;
    • P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);
    • 解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;
    • P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;
    • P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;
    • 由于P帧是参考帧,它可能造成解码错误的扩散;
    • 由于是差值传送,P帧的压缩比较高。
  3. B帧
    B帧:双向预测内插编码帧。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况,但我这样说简单些),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。
    B帧的预测与重构
    B帧以前面的I或P帧和后面的P帧为参考帧,“找出”B帧“某点”的预测值和两个运动矢量,并取预测差值和运动矢量传送。接收端根据运动矢量在两个参考帧中“找出(算出)”预测值并与差值求和,得到B帧“某点”样值,从而可得到完整的B帧。
    B帧特点
    • B帧是由前面的I或P帧和后面的P帧来进行预测的;
    • B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;
    • B帧是双向预测编码帧;
    • B帧压缩比最高,因为它只反映两参考帧间运动主体的变化情况,预测比较准确;
    • B帧不是参考帧,不会造成解码错误的扩散。

H264编码格式

在 VCL 数据传输或存储之前,这些编码的 VCL 数据,先被映射或封装进NAL 单元中。每个 NAL 单元包括一个原始字节序列负荷( RBSP, Raw Byte Sequence Payload)和一组对应于视频编码的 NAL 头信息。RBSP 的基本结构是:在原始编码数据的后面填加了结尾比特。一个 bit“1”若干比特“0”,以便字节对齐。

图1

NAL Header

NAL头由一个字节组成,如图所示。




语法:禁止位(第一位占1bit)、重要性位(2-3位占2bit)、NALU类型(4-8位占5bit)

NAL类型

nal_unit_type取值 含义
0 没有定义
1 不分区,非IDR图像的片
2 片分区A
3 片分区B
4 片分区C
5 IDR图像中的片
6 补充增强信息单元(SEI)
7 SPS(Sequence Parameter Set序列参数集,作用于一串连续的视频图像,即视频序列)
8 PPS(Picture Parameter Set图像参数集,作用于视频序列中的一个或多个图像)
9 序列结束
10 序列结束
11 码流结束
12 填充
13-23 保留
24 START-A 单一时间的组合包
25 START-B 单一时间的组合包
26 MTAP16 多个时间的组合包
27 MTAP24 多个时间的组合包
28 FU-A 分片的单元
29 FU-B 分片的单元
29 FU-B 分片的单元
30-31 没有定义

这里对IDR、SPS、PPS做一下简要说明



  • IDR帧属于H264中的I帧,在一个NAL序列单元里首次出现的I帧称为IDR帧,IDR帧的出现是为了方便控制编码和解码的流程,IDR帧是立即刷新帧,如果当前帧是IDR帧则会刷新SPS以及PPS防止错误不被传播。
  • SPS(Sequence Parameter Set)又称作序列参数集。SPS中保存了一组编码视频序列(Coded video sequence)的全局参数。所谓的编码视频序列即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。而每一帧的编码后数据所依赖的参数保存于图像参数集中。
  • PPS(Picture Parameter Set)通常情况下,PPS类似于SPS,在H.264的裸码流中单独保存在一个NAL Unit中,只是PPS NAL Unit的nal_unit_type值为8;而在封装格式中,PPS通常与SPS一起,保存在视频文件的文件头中。

总结

本文对视频编解码作了大体的介绍,主要讲解H264的IPB帧以及编码原理。NAL是H264里很重要的一个知识点,尤其是NAL的编码格式。在后续文章中再详细介绍部分取值在直播以及编码解码中的意义。另附上直播项目开源地址AndroidRTMPLive

随意分享,您的支持将鼓励我继续创作!