解决方案

h264结构与码流

seo靠我 2023-09-25 22:09:54

h264基本概念结构图

  H264视频压缩后会成为一个序列帧,帧里包含图像,图像分为很多片,每个片可以分为宏块,每个宏块由许多子块组成

H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(sliSEO靠我ce)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。

场和帧:

视频的一场或者一帧可以用来产生一个编码图像。在PAL电视中,每个电SEO靠我视帧都是通过扫描屏幕两次而产生的,第二个扫描的线条刚好填满第一次扫描所留下的缝隙。每个扫描即称为一个场(顶场底场)。因此 30 帧/秒的电视画面实际上为 60 场/秒

I帧 P帧 B帧,引用斯巴克兄弟的SEO靠我博客,图文并茂

举个简单的例子,网络上的电影很多采用了B帧,因为B帧记录的是前后帧的差别,比P帧能节约更多的空间。但是如果遇到不支持B帧的播放器就会很尴尬,因为虽然文件通过B帧压缩确实缩小了非常多,但是SEO靠我在解码时,不仅要用之前缓存的画面,还要知道下一个I或者P的画面。如果B帧丢失,就会用之前的画面简单重复,就会造成画面卡,B帧越多,画面越卡。

一般来说,I 帧的压缩率是7(跟JPG差不多),P 帧是20SEO靠我,B 帧可以达到50。

在如上图中,GOP (Group of Pictures)长度为13,S0 ~ S7 表示 8个视点,T0~T12 为 GOP的 13个时刻。每个 GOP包含帧数为视点数 GOPSEO靠我 长度的乘积。在该图中一个 GOP 中,包含94 个 B帧。B 帧占一个 GOP 总帧数的 90.38%。GOP 越长,B 帧所占比例更高,编码的率失真性能越高

I帧只包含I宏块

P帧包含I宏块和P宏块

BSEO靠我帧包含I宏块、P宏块、B宏块

当帧内slice全部为I像片时,则此帧为I帧

当全部为P slice或和I slice的组合时,则为P帧

当为B slice或和I、P slice的组合时,则为B帧。

片(sliSEO靠我ce):

每个图像中,若干个宏块被排列成片。片的目的:为了限制误码的扩散和传输,使编码片相互间保持独立。片共有5种类型:I片(只包含I宏块)、P片(P宏块和/或I宏块)、B片(B宏块和/或I宏块)、SPSEO靠我片(用于不同编码流之间的切换,包含P宏块和/或I宏块)和SI片(特殊类型的编码宏块,包含SI宏块)。

I slice只包含I宏块

P slice包含P宏块和/或I宏块

B sliceB宏块和/或I宏块。

宏块SEO靠我

一个编码图像首先要划分成多个块(4x4 像素)才能进行处理,显然宏块应该是整数个块组成,通常宏块大小为16x16个像素。宏块分为I、P、B宏块,I宏块只能利用当前片中已解码的像素作为参考进行帧内预测SEO靠我;P宏块可以利用前面已解码的图像作为参考图像进行帧内预测;B宏块则是利用前后向的参考图形进行帧内预测

  序列(切片slice)和宏块的关系如下

  切片头:包含了一组片的信息,比如片的数量,顺序等等

H264编码SEO靠我分层

NAL层:(Network Abstraction Layer,视频数据网络抽象层): 关心压缩后如何进行传输,它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H26SEO靠我4的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。

VCL层:(Video Coding Layer,视频数据编码层): 关心如何进行SEO靠我压缩,对视频原始数据进行压缩

H.264编码原理

  H.264采用的编码算法就是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。

视频中一般会存在一段变化不大的图像画面,我们可以SEO靠我先编码出一个完整的图像帧t1,之后的图像帧t2就可以不编码全部图像,而只写入与t1帧的差别,之后的图像帧参考t3帧仍旧可以参照这种方式继续进行编码。这样循环下去就可以得到一个序列(slice)。如果下SEO靠我一个图像帧t4与之前的图像变化很大,无法参考前面的图像帧,就结束上一序列,并开始下一序列。

序列就可以定义为一段图像编码后的数据流,以I帧开始,到下一个I帧结束,H.264中图像就是以序列为单位进行组织SEO靠我的。

码流的具体分析

码流的整体结构如下

SODB:(String of Data Bits,原始数据比特流):

  由VCL层产生,数据长度不一定是8的倍数,所以处理起来比较麻烦

RBSP:(Raw Byte SSEO靠我equence Payload,SODB+trailing bits,编码后的数据流):

相当于去掉附加03字节之后的数据,同原始的相比,算法是在SODB最后一位补1,不按字节对齐补0,如果补齐0,不知SEO靠我道在哪里结束,所以补1,如果不够8位则按位补0

EBSP:(Encapsulate Byte Sequence Payload):

生成编码后的数据流之后,我们还要在每个帧之前加一个起始位,需要开发者人为SEO靠我添加。起始位一般是十六进制的0001。但是在整个编码后的数据里,可能会出来连续的2个0x00。那这样就与起始位产生了冲突.那怎么处理了? H264规范里说明如果处理2个连续的0x00,就额外增加一个0SEO靠我x03 。这样就能预防压缩后的数据与起始位产生冲突

举个例子:

NALU: (NAL Header(1B)+EBSP)

.NALU就是在EBSP的基础上加1B的网络头.

H.264原始码流(又称为“裸流”)是SEO靠我由一个一个的NALU组成的,结构是这样的:

首先NALU是H.264编码数据存储或传输的基本单元,一般H.264码流最开始的两个NALU是SPS和PPS,第三个NALU是IDR。而SPS、PPS、SEISEO靠我这三种NALU不属于帧的范畴,它们的定义如下:

SPS(Sequence Parameter Sets):序列参数集,作用于一系列连续的编码图像。

PPS(Picture Parameter Set):图SEO靠我像参数集,作用于编码视频序列中一个或多个独立的图像。

SEI(Supplemental enhancement information):附加增强信息,包含了视频画面定时等信息,一般放在主编码图像数据之SEO靠我前,在某些应用中,它可以被省略掉。

IDR(Instantaneous Decoding Refresh):即时解码刷新。

HRD(Hypothetical Reference Decoder):假想码流SEO靠我调度器。

起始码

每个NALU之间通过起始码进行分隔,起始码分成两种:0x000001(3Byte)或者0x00000001(4Byte)。NALU对应的Slice为一帧的开始就用0x00000001,否SEO靠我则就用0x000001。H.264码流解析的步骤就是首先从码流中搜索0x000001和0x00000001,分离出NALU;然后再分析NALU的各个字段 。

起始码很容易被忽视但是有很重要,博主在遇见清SEO靠我空保存码流需求的时候曾直接cat /dev/null/ 定向了码流文件,重新保存码流时看见文件大小增加,但是重新保存后的文件就打不开了,原因就在重定向原大小的区域全部变成了00,播放器搜索了很久也没有SEO靠我找到起始码,可能就判定文件格式不对了

在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责SEO靠我格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。因此我们平时的每帧数据就是一个NAL单元(SPS与PPS除外)。在实际的H264数据帧中,往往帧前面带有00 00 00 01 或 0SEO靠我0 00 01分隔符,一般来说编码器编出的首帧数据为PPS与SPS,接着为I帧……

一个H.264文件如下:

在H264码流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0SEO靠我x01"为起始码的,找到起始码之后,使用起始码之后的第一个字节的低 5 位判断是否为 7(sps)或者 8(pps), 及 data[4] & 0x1f == 7 || data[4] & 0x1f SEO靠我== 8。然后对获取的 nal 去掉开始码之后进行 base64 编码,得到的信息就可以用于 sdp。 sps和pps需要用逗号分隔开来。

上图中,00 00 00 01是一个NALU的起始标志。后面的SEO靠我第一个字节,0x67,是NALU的类型,type &0x1f0x7表示这个NALU是SPS,type &0x1f0x8表示是PPS。

NAL Header:

NALU类型(5bit)、重要性指示位(2biSEO靠我t)、禁止位(1bit):第1位为禁位,默认固定为0,如果接收到的为1,那么就需要丢弃该单元;第2-3位表示重要性,00表示最不重要,11表示最重要,我们可以在解码来不及的情况下舍弃一些不重要的单元,SEO靠我比如在网传的时候,如果网络卡,那么就需要适当丢掉一些数据,丢掉哪些数据就是根据重要性来进行选择;第4-8位用来表示NALU的类型

0 没有定义 1-23 NAL单元 单个 NASEO靠我L 单元包 24 STAP-A 单一时间的组合 25 STAP-B 单一时间的组包 26 MTAP16 多个时间的合包 27 MTPA24 多个事件组合包 28 FU-A 一帧单包传输 29 FU-BSEO靠我 一帧分多包传输 30-31 没有定义

h264仅用1-23,24以后的用在RTP H264负载类型头中

  RBSP + RBSP trailing bits + SODE = RBSP

NAL headerSEO靠我(1byte) + RBSP = NALU
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2