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

在上文Android RTMP协议直播之H264标准(一)中对视频编码以及H264编码做了大致介绍,本次将对H264的NAL单元以及码流传输格式进行介绍。OK 废话不多说进入正题,通过对H264结构的了解H264包含了VCL(Video Coding Layer)和NAL(Network Abstraction Layer,我们知道不论是在网络传输或者本地播放等,VCL中部分属性都会被解析包装在NAL单元中。H264根据不同的nal_unit_type来确定NAL单元类型并使用相关的压缩算法来进行编解码。

H264码流结构

H264码流结构大致可以分为两层分别为Annexb格式以及RTP格式,如下图。

  • 第一层:比特流。该层有两种格式:附录NALN格式和RTP格式。
  • 第二层:NAL Unit层。包含了NAL Header和NAL Body信息。
  • 第三层:Slice层。
    一帧视频图像可编码成一个或者多个片,每片包含整数个宏块,即每片至少 一个宏块,最多时包含整个图像的宏块。
    片的目的:为了限制误码的扩散和传输,使编码片相互间保持独立。片共有 5 种类型: I 片(只包含 I 宏块)、P 片(P 和 I 宏块)、B 片(B 和 I 宏块)、SP 片(用于不同编码流之 间的切换)和 SI 片(特殊类型的编码宏块)。
    片的语法结构(如图所示):片头规定了片的类型、属于哪个图像、有关的参考图像等;片的数据包含了一系列宏块和不编码数据。
  • 第四层:Slice data层。Slice由宏块(macro block, MB)组成。宏块是编码处理的基本单元。
  • 第五层:PCM类。
  • 第六层:残差层。

再谈NAL Header

通过对H264的码流结构了解到H264分为两种格式分别为Nal unit以及RTP,Nal Unit码流格式为。如果对nal_unit_type不了解的请参考上一篇文章Android RTMP协议直播之H264标准(一)



NAL Unit结构中分为NAL Header和NALU主体,如下图。



通过上一篇文章中对NAL Header的了解,我们知道NAL Header是由8位组成的,假如一个NAL单元是IDR帧则它的NAL格式为00000001|00000101|payload(符号”|”为了区分其中的关系,实际码流中不存在)



四字节起始码在所有的NAL单元中都存在为固定格式,在实际编码开发过程中可以忽略该四字节起始码。

1
2
3
4
5
6
7
8
//忽略四字节起始码
if (frame[2] == 0x00) { //00 00 00 01
frame += 4;
len -= 4;
} else if (frame[2] == 0x01) { // 00 00 01
frame += 3;
len -= 3;
}

H264的Level和Profile

在了解H264的Level和Profile之前,我们先来了解一下码流、帧数、帧率、比特率。

码流(Data Rate)

码流(Data Rate)是指视频文件在单位时间内使用的数据流量,也叫码率,是视频编码中画面质量控制中最重要的部分。同样分辨率下,视频文件的码流越大,压缩比就越小,画面质量就越好。

帧数

帧数可以解释为一个静止画面的数量,也就是说,如果一个动画的帧率恒定为 60 帧每秒(FPS),那么它在一秒钟内的帧数则为60帧

帧率(Frame Rate)

帧率(Frame rate) = 帧数(Frames)/时间(Time),单位为帧每秒(f/s, frames per second, fps)

帧率是用于测量显示帧数的量度,测量单位为“每秒显示帧数”( Frame per Second, FPS)或“赫兹”( Hz),一般来说 FPS 用于描述视频、电子绘图或游戏每秒播放多少幀。

FPS( Frame per Second)每秒显示帧数

FPS 是图像领域中的定义,是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面数。 FPS 是测量用于保存、显示动态视频的信息数量。每秒钟帧数愈多,所显示的动作就会愈流畅.

比特率(Bit Rate)

比特率(Bit rate)是单位时间内传输送或处理的比特的数量。在数字多媒体领域,比特率是单位时间播放连续的媒体如压缩后的音频或视频的比特数量。在这个意义上讲,它相当于术语数字带宽消耗量,或吞吐量。比特率规定使用“比特每秒”(bit/s或bps)为单位,经常和国际单位制词头关联在一起,如“千”(kbit/s或kbps),“兆”(百万)(Mbit/s或Mbps),“吉”(Gbit/s或Gbps)和“太”(Tbit/s或Tbps)

1
2
3
1,000 bps		= 【1 kbps】 =	1,000 bit/s		= 0.97656 Kibi bit/s
1,000,000 bps = 【1 Mbps】 = 1,000,000 bit/s = 0.95367 Mebi bit/s
1,000,000,000 bps = 【1 Gbps】 = 1,000,000,000 bit/s = 0.93132 Gibi bit/s

常用视频比特率参考

  • 16 kbit/s—可视电话质量(用户可以接受的”说话的头”照片的最低要求)
  • 128 – 384 kbit/s—商业导向的视频会议系统质量
  • 700 kbit/s(最高)YouTube 240p视频(使用H.264)
  • 1 Mbit/s—VHS质量
  • 1.25 Mbit/s – VCD质量(使用MPEG1压缩)
  • 5 Mbit/s—DVD质量(使用MPEG2压缩)
  • 8 – 15 Mbit/s—高清晰度电视(HDTV)质量(使用H.264压缩)
  • 29.4 Mbit/s(最高)– HD DVD质量
  • 40 Mbit/s(最高)– 蓝光光盘(Blu-ray Disc)质量(使用MPEG2、H.264或VC-1压缩)
  • 440或880 Mbit/s – Sony HDCAM SR质量(SQ/HQ)

H264的Level(级别)是用来约束分辨率、帧率和码率。


  • Maximum frame size in macroblocks最大宏块数。
    • per second:每秒(的最大宏块数)。可用于约束帧率。
    • per frame:每帧(的最大宏块数)。可用于约束分辨率。
  • Maximum video bit rate in kbits/s:最大视频码率。不同档次(Profile)下会有区别。
    • BP:Baseline Profile,基线档次。
    • XP:Extended Profile,进阶档次。
    • MP:Main Profile,主要档次。
    • HiP:High Profile,高级档次。
    • Hi10P:High 10 Profile,高级10位档次。
    • Hi422P:High 4:2:2 Profile,高级4:2:2档次。
    • Hi444PP:High 4:4:4 Predictive Profile,高级4:4:4(实验性?)档次。

主要Profile说明

  • BP(Baseline profile):提供I/P帧,仅支持Progressive(逐行扫描)和CAVLC。多应用于“视频会话”,如可视电话、会议电视、远程教学、视频监控等实时通信领域;
  • XP(Extended profile):提供I/P/B/SP/SI帧,仅支持Progressive和CAVLC。多应用于流媒体领域,如视频点播、基于网络的视频监控等;
  • MP(Main profile):提供I/P/B帧,支持Progressive和Interlaced(隔行扫描),提供CAVLC和CABAC。多应用于数字电视广播、数字视频存储等领域;
  • HiP(High profile):(Fidelity Range Extensions,FRExt)在Main profile基础上新增8*8帧内预测,Custom Quant,Lossless Video Coding,更多YUV格式(4:2:2,4:4:4),像素精度提高到10位或14位。多应用于对高分辨率和高清晰度有特别要求的领域。

关于DTS和PTS

一个视频是由很多帧组成,这些帧在一定时间顺序下进行播放就有了动画的效果。但是这些原始帧如果不进行压缩会对磁盘或者网络造成成本上的提高,H264在编码视频时提供了三种帧分别为IPB帧。IPB帧具体含义在上文Android RTMP协议直播之H264标准(一)中已作出解释。

在视频编解码的时候I帧不需要以来其他参考帧就可以独立完成编解码操作,因为I帧属于帧内压缩,我们可以说一个I帧包含了一个完整的画面,但是PB帧不可以,PB帧属于帧间压缩需要依赖于参考帧来进行编解码。这就会导致一个问题,假如在一个H264编码单元里的帧结构为IBBP帧,此时需要编解码B帧,但是B帧需要预知它的前后帧内容,所以需要先编解码BP帧。就会出现这样的帧结构IPBB帧,这种情况的出现就会帧编码错乱导致时间和编码错乱,通过这个场景就有了DTS和PTS的概念.DTS 告诉我们该按什么顺序解码这几帧图像,PTS 告诉我们该按什么顺序显示这几帧图像。顺序大概如下:

1
2
3
4
5
A Stream	IBBP
--->
N Stream IPBB
DTS 1234
PTS 1423

值得注意的是如果没有B帧的情况下,通常DTS以及PTS的顺序基本上是一致的。

  • DTS(Decoding Time Stamp)即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
  • PTS(Presentation Time Stamp)即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

总结

本文对H264的码流结构以及NAL单元格式进行了分析,通过对H264码流结构的分析我们知道H264码流结构分为Nal Unit以及RTP格式,在NAL Unit格式下,NAL Unit通常是由四字节起始码开始。在上篇文章对NAL Header基础上对本文对NAL Header进行了拆解分析,让我们更加直观的了解到NAL单元在码流格式中的结构形式。H264标准提供了多种Profile以及Leve以支持不同分辨率不同码率格式等,另外在文章末尾补充了DTS以及PTS,DTS和PTS是很重要的一个知识点,在处理音视频同步上有很重要的作用,包括后续视频直播中也会体积DTS和PTS。好了本篇文章到此就要结束了,喜欢文章的同学请留言点赞吧!另附上直播项目开源地址AndroidRTMPLive

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