H.264 编码基础知识

说明,以下内容很多参考 从零了解H.264结构

基本资料

H.264,又称为MPEG-4第10部分,高级视频编码(英语:MPEG-4 Part 10, Advanced Video Coding,缩写为MPEG-4 AVC)是一种面向块,基于运动补偿的视频编码标准。由ITU-T视频编码专家组与ISO/IEC联合工作组开发。

H.264 协议标准

音视频基础知识

在线视频兴起之前,互联网上看片的主要方式是下载到电脑后观看。比如下载了一个 test.mp4的视频,这个 mp4是一个容器,又叫封装格式,就是把已经编码封装好的视频、音频按照一定的规范放到一起。常见的容器格式有: avi, mp4, mov, ts, mkv, rmvb/rm, wmv, flv, 3gp, asf, webm 。
裸视频是非常大的,所以需要对视频做编码压缩,常见的视频编码格式有: mpeg-1, mpeg-2, mpeg-4, H.264/AVC/mpeg-4part 10, h.265/hevc, vc-1, RealVideo, AVS 。

在这里插入图片描述

H.264 视频编码

视频编码主要是利用空间、时间的冗余信息进行编码达到压缩的目的。空间冗余信息压缩是做每一帧图片内的压缩,跟 jpeg 图片压缩类似,可能会是降采样、联合周边像素信息等方式来进行编码。 时间冗余信息主要是参考前后帧的信息来进行编码,比如前后两帧的图片通常是有很多像素点是一样的,比如要表示两针图片的信息,能想到最简单的方式就是用第一帧的全量信息+第二帧相对第一帧有变化的变量信息来表示。H.264 的编码很复杂,但是大体的原理就是利用空间、时间信息来编码。
因为有利用时间信息来编码,所以必然要利用多帧的图片来编码,所以需要缓存多帧信息,给编解码以及视频流带来一些需要权衡的问题,比如要利用更多前后帧信息来进行编码,能够提高压缩比,但是相应的延迟就会比较高,对于实时视频推流是需要权衡的;另外解码顺序和渲染顺序也需要注意。

简介

H.264 编码功能分为两层,VCL(视频编码层/Video Coding Layer)和 NAL(网络提取层/Network Abstraction Layer)。VCL 主要分为 5 部分: 帧间和帧内预测(Estimation)、变换(Transform)和反变换、量化(Quantization)和反量化、环路滤波(Loop Filter)、熵编码(Entropy Coding)。VCL 负责怎么高效的进行编码,编码后的数据怎么进行存储和传输由 NAL 来负责,存到了NAL单元(NALU)。一帧图片经过 H.264 编码器之后,就被编码为一个或多个片(slice),而装载着这些片(slice)的载体,就是 NALU 了。片(slice)是 H.264 中提出的新概念,是通过编码图片后切分通过高效的方式整合出来的概念,一张图片至少有一个或多个片(slice)。除了装载编码数据的slice,有些NALU装载了编码的一些 meta 信息,比如 SPS(Sequence parameter set), PPS(Picture parameter set)。

在这里插入图片描述

在这里插入图片描述

  • 1 Frame (帧) = 1…n个Slice (片)1 Slice (片) = 1…n个Marcoblock(宏块)1 Marcoblock(宏块) = 16x16yuv数据
  • 1 Slice (片) = Slice Header + Slice Data
  • 1 NALU = 一组对应于视频编码的NALU头部信息 + 一个原始字节序列负荷(RBSP,Raw Byte Sequence Payload).

NALU

H.264的结构全部都是以 NALU 为主,理解了 NALU,就理解了 H.264 的结构。一个 NALU 由 NAL头+RBSP组成。一个原始的 H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload]三部分组成,其中 Start Code 用于标示这是一个 NALU 单元的开始,必须是 00 00 00 0100 00 01

在这里插入图片描述

NALU Header

NAL Header 由三部分组成,F/forbidden_bit(1bit),NRI/nal_reference_bit(2bits)(优先级),Type/nal_unit_type(5bits)(类型)。

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

在这里插入图片描述

比较经常会用到的 NALU 类型有:

00 00 00 01 06:  SEI信息   
00 00 00 01 67:  0x67&0x1f = 0x07 :SPS
00 00 00 01 68:  0x68&0x1f = 0x08 :PPS
00 00 00 01 65:  0x65&0x1f = 0x05: IDR Slice
00 00 00 01 41:  0x41&0x1f = 0x01: Coded slice of a non-IDR picture

参数集是 H.264 标准的一个新概念,是一种通过改进视频码流结构增强错误恢复能力的方法。
SPS序列参数集 (包括一个图像序列的所有信息,即两个 IDR 图像间的所有图像信息,如图像尺寸、视频格式等)。
PPS图像参数集 (包括一个图像的所有分片的所有相关信息, 包括图像类型、序列号等,解码时某些序列号的丢失可用来检验信息包的丢失与否)

分片(Slice)

我们可以理解为一 张/帧 图片可以包含一个或多个分片(Slice),而每一个分片(Slice)包含整数个宏块(Macroblock),即每片(Slice)至少一个宏块(Macroblock)。 Slice = Slice Header + Slice Data

在这里插入图片描述

  1. 分片头中包含着分片类型、分片中的宏块类型、分片帧的数量、分片属于那个图像以及对应的帧的设置和参数等信息。
  2. 分片数据中则是宏块,这里就是我们要找的存储像素数据的地方。

有五种分片类型

Slice内容
I Slice只包含I宏块
P Slice包含P和I宏块
B Slice包含B和I宏块
SP Slice包含P 和/或 I宏块,用于不同码流之间的切换
SI Slice一种特殊类型的编码宏块

宏块(Macroblock)

宏块是视频信息的主要承载者。一个宏块由一个16×16亮度像素和附加的一个8×8 Cb和一个 8×8 Cr 彩色像素块组成。每个图象中,若干宏块被排列成片的形式。

在这里插入图片描述

宏块分类

宏块分类说明
I Macroblock利用从当前片中已解码的像素作为参考进行帧内预测
P Macroblock利用前面已编码图像作为参考进行帧内预测,一个帧内编码的宏块可进一步作宏块的分割:即16×16.16×8.8×16.8×8亮度像素块。如果选了8×8的子宏块,则可再分成各种子宏块的分割,其尺寸为8×8,8×4,4×8,4×4
B Macroblock利用双向的参考图像(当前和未来的已编码图像帧)进行帧内预测

I,P,B帧与 PTS/DTS

帧的分类名称说明
I帧帧内编码帧,又称intra picture自身可以通过视频解压算法解压成一张单独的完整的图片
P帧前向预测编码帧,又称predictive-frame需要参考其前面的一个I frame 或者B frame来生成一张完整的图片
B帧双向预测帧,又称bi-directional interpolated prediction frame则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片
名称说明
PTS(Presentation Time Stamp)PTS主要用于度量解码后的视频帧什么时候被显示出来
DTS(Decode Time Stamp)DTS主要是标识内存中的bit流再什么时候开始送入解码器中进行解码

GOP(Group Of Pictures)

GOP (图像组)主要用作形容一个 i 帧 到下一个 i 帧之间的间隔了多少个帧。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧。在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量。在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。

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

一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。
I和IDR帧都使用帧内预测。I帧不用参考任何帧,但是之后的P帧和B帧是有可能参考这个I帧之前的帧的。IDR就不允许这样。
比如这种情况:
IDR1 P4 B2 B3 P7 B5 B6 I10 B8 B9 P13 B11 B12 P16 B14 B15 这里的B8可以跨过I10去参考P7

核心作用:
H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。

附录

将一张图片转成 H.264 视频

ffmpeg -i minimal.png -pix_fmt yuv420p minimal_yuv420.h264

使用 mediainfo 查看 h264 文件信息

➜ mediainfo minimal_yuv420.h264
General
Complete name                            : minimal_yuv420.h264
Format                                   : AVC
Format/Info                              : Advanced Video Codec
File size                                : 1.23 KiB
Duration                                 : 40 ms
Overall bit rate                         : 252 kb/s
Writing library                          : x264 core 157 r2969 d4099dd
Encoding settings                        : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=2 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=crf / mbtree=1 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00

Video
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : High@L1
Format settings                          : CABAC / 4 Ref Frames
Format settings, CABAC                   : Yes
Format settings, Reference frames        : 4 frames
Duration                                 : 40 ms
Width                                    : 64 pixels
Height                                   : 64 pixels
Display aspect ratio                     : 1.000
Frame rate mode                          : Variable
Frame rate                               : 25.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Writing library                          : x264 core 157 r2969 d4099dd
Encoding settings                        : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=2 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=crf / mbtree=1 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00

使用 hexdump 查看二进制数据

➜  hexdump minimal_yuv420.h264
0000000 00 00 00 01 67 64 08 0a ac d9 44 26 84 00 00 03
0000010 00 04 00 00 03 00 c8 3c 48 96 58 00 00 00 01 68
0000020 eb e3 cb 22 c0 00 00 01 06 05 ff ff aa dc 45 e9
0000030 bd e6 d9 48 b7 96 2c d8 20 d9 23 ee ef 78 32 36
0000040 34 20 2d 20 63 6f 72 65 20 31 35 37 20 72 32 39
0000050 36 39 20 64 34 30 39 39 64 64 20 2d 20 48 2e 32
.........

下载测试视频

要学习 H.264 编码,就需要有用 H.264 编码的视频 demo 来测试,可以用 you-get 工具到主流的一些视频网站下载个视频来测试。

test you-get -i https://www.bilibili.com/video/av2650963\?from\=search\&seid\=15782581299335183738
site:                Bilibili
title:               Tribute to Hayao Miyazaki(致敬宫崎骏)
streams:             # Available quality and codecs
    [ DEFAULT ] _________________________________
    - format:        flv
      container:     flv
      quality:       高清 1080P
      size:          42.4 MiB (44452950 bytes)
    # download-with: you-get --format=flv [URL]

    - format:        flv720
      container:     flv
      quality:       高清 720P
      size:          42.4 MiB (44452999 bytes)
    # download-with: you-get --format=flv720 [URL]

    - format:        flv360
      container:     flv
      quality:       流畅 360P
      size:          9.0 MiB (9452072 bytes)
    # download-with: you-get --format=flv360 [URL]test you-get --format=flv360 https://www.bilibili.com/video/av2650963\?from\=search\&seid\=15782581299335183738

视频格式转换

视频格式转换大部分都可以用 ffmpeg 来实现。

ffmpeg -i input.flv output.mp4

此过程需要对视频进行重新编码,比较耗费 CPU 等资源。如果不做转码,可以用如下的方式:

ffmpeg -i input.flv -vcodec copy -acodec copy output.mp4
将视频转换为非压缩的裸视频

将视频 input.mp4转换为 pix_fmt nv12yuv 的裸视频 output.yuv, 裸视频可以作为后续视频编码的 input 。

ffmpeg -i input.mp4 -vcodec rawvideo -vframes 100 -pix_fmt nv12 -an output.yuv
flv 转 h264

将视频 input.flv转换为 output.h264

ffmpeg -i input.flv -vcodec copy output.h264
mp4 转 mkv

将视频 input.mp4转换为 output.mkv

ffmpeg -i input.mp4 -vcodec copy -acodec copy output.mkv

参考资料

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
H.264是一种视频编码标准,也被称为MPEG-4 Part 10或AVC(Advanced Video Coding)。它是目前最常用的视频编码标准之一,被广泛应用于在线视频、数字电视、蓝光光盘、视频会议等领域。 H.264编码器将视频信号压缩成一组数字编码,从而减少存储空间和传输带宽的需求。H.264编码器通过分析视频信号的空间和时间信息,将其转换为特定的编码格式。这些编码可以被解码器解码,以还原原始视频信号。 下面是一些关于H.264编码基础知识: 1. 编码过程 H.264编码过程由四个主要步骤组成:帧内预测、帧间预测、变换和量化。在帧内预测中,编码器利用已知像素值预测当前像素的值。在帧间预测中,编码器利用前一帧和当前帧之间的差异预测当前帧的像素值。变换和量化是将像素值转换为频域表示,并将高频分量量化为低比特率。 2. 比特率 比特率是指视频编码器在单位时间内产生的比特数。H.264编码器可以根据不同的应用需求进行配置,以产生不同的比特率。高比特率通常会产生更高质量的视频,但需要更高的存储空间和带宽。 3. 分辨率 分辨率是视频图像的大小,通常用像素表示。H.264编码器可以根据不同的应用需求进行配置,以产生不同的分辨率。高分辨率通常会产生更高质量的视频,但需要更高的存储空间和带宽。 4. I帧、P帧和B帧 H.264编码器使用三种不同类型的帧:I帧、P帧和B帧。I帧是完整的关键帧,不依赖于其他帧进行解码。P帧是预测帧,依赖于前一个I帧或P帧进行解码。B帧是双向预测帧,依赖于前面和后面的I帧或P帧进行解码。 5. 实时编码 H.264编码器可以进行实时编码,即在不影响视频质量的情况下,以最快的速度进行编码。这对于视频会议、视频流和实时监控等应用非常重要。 综上所述,H.264编码是一种非常重要的视频编码技术,它可以有效地减少存储空间和传输带宽的需求,同时保持高质量的图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值