前言
相对而言,音视频开发算是有些门槛的。记得我第一次接触的时候,看别人的博客都看不懂。特别是写代码的时候,非常痛苦,只能抄别人的代码,却不知道为什么要这么写,也不知道应该怎么调整。后来总结了一下,痛苦的原因是在写代码之前没有掌握相关的基础知识,因此现在特地写了这样一篇博客,希望对大家有所帮助。
另,这篇博客主要是对自己做的笔记的一些总结,前前后后参考了许多文章和一些书籍,内容之间的连贯性或许不够好,也可能存在一些错误,如果发现了还望评论指正。
基本概念
声波
声波有三要素:
1) 频率,代表音调,即常说的高音、低音。频率越低,波形越长,穿越障碍物时能量衰减越小,可传播距离越远。
2) 振幅,代表响度,即音量大小。
3) 波形,代表音色,同样的音调和响度,钢琴和小提琴的声音听起来完全不同,这就是音色。波的形状决定了声音的音色,钢琴和小提琴的音色不同就是因为它们的介质所产生的波形不同。
人类耳朵的听力有一个频率范围,大约是 20Hz ~ 20kHz,而根据奈奎斯特定理(采样定理),按比声音最高频率高两倍以上的频率对声音进行采样,能够保证采样声音能够数字化,所以采样频率一般为 44.1kHz。
数字音频
数字音频有三个重要概念:
1) 采样,将信 从连续时间域上的模拟信 转换到离散时间域上的离散信 的过程。
2) 量化,指将信 的连续取值(或者大量可能的离散取值)近似为有限多个(或较少的)离散值的过程:
YUV
对于视频的裸数据而言,用得更多的是 YUV 数据格式,其中 “Y” 表示明亮度(Luminance 或 Luma),即灰度值;而 “U” 和 “V” 表示的则是色度(Chrominance 或 Chroma),作用是描述影像色彩及饱和度,指定像素的颜色。
YUV 主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有 UV 信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV 不像RGB 那样要求三个独立的视频信 同时传输,所以用 YUV 数据占用的内容更少。
RGB 转 YUV (从 ITU-R BT.601-7 标准中可以拿到推荐的相关系数):
Y = 0.299R + 0.587G + 0.114B
Cb = 0.564(B – Y)
Cr = 0.713(R – Y)
上述就是 YCbCr 颜色模型的基本原理。YCbCr 是属于 YUV 家族的一员(Cb、Cr 的含义等同于 U、V ),是在计算机系统中应用最为广泛的颜色模型。在 YCbCr 中,Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量。
YCbCr 转 RGB:
R = Y + 1.402Cr
G = Y – 0.344Cb – 0.714Cr
B = Y + 1.772Cb
此时我们发现,YCbCr 仍然用了 3 个数字来表示颜色,那么它是如何节省了空间的呢面通过图片说明。
图片由类似下面的像素组成:
上图中,每个像素的 3 个分量的信息是完整的,Y : Cb : Cr = 4 : 4 : 4,属于 YUV444 格式。
而根据人类视觉系统对亮度信 比色度信 敏感的原理,我们可以省略图片的一些信息,对图片的质量影响却不会太大,比如:
上图中,每四个 Y 共用一组 UV 分量,Cb、Cr 交替出现,在第一行数据里 Y : Cb : Cr = 4 : 2 : 0;而在第二行数据,Y : Cb : Cr = 4 : 0 : 2,这就是最常见的 YUV420 格式。
YUV420
YUV 格式有两大类:planar 和 packed。planar 先存储所有 Y,紧接着存储所有 U,最后是 V;而 packed 则是每个像素点的 Y、U、V 连续交叉存储。不过,packed 格式的已经不怎么能见到了,现在几乎都用 planar 格式。planar 的意思是平面,一个 planar 存储一个分量,因此 YUV 需要三个 planar 来存储图像信息。
最常用数据格式是 YUV420,其中又有 YUV420p、YUV420sp 两种:
也有 UV 数据顺序相反的,比如 Android 平台中的 YV12、NV21 两种格式:
还有一个和 YUV 数据相关的概念:stride——指内存中每行像素所占的空间。为了实现内存对齐,每行像素在内存中所占的空间不一定是图像的宽度。因此 stride 大于等于图像帧的宽度,同时,stride 为 4 的倍数。
H264
和音频编码一样,图像数据的编码方式也有很多种,比如 ISO 制定的 MPEG2、MPEG4 标准,ITU-T 的 H.261、H.262、H.263、H.264、H.265,Google 的 VP8、VP9 , AOM 的 AV1 等。其中 H265(HEVC)、VP9、AV1 是最新的几个编解码标准/格式,还在互相竞争中,现在用得最多的还是 H264。
H264 又称为 MPEG-4 Part 10, Advanced Video Coding,简写为 AVC。因为 ITU-T H.264 标准和 ISO/IEC MPEG-4 AVC 标准(正式名称是ISO/IEC 14496-10—MPEG-4 第十部分,高级视频编码)有相同的技术内容,故被共同管理。
H264 的相关概念有:序列、图像、片组、片、NALU、宏块、亚宏块、块、像素。
图像、帧、场
在 H.264 中,「图像」是个集合的概念,一帧或一场都可以称为图像。一帧通常就是一幅完整的图像。当采集视频信 时,如果采用逐行扫描,则每次扫描得到的信 就是一副图像,也就是一帧。而如果采用的是隔行扫描(奇、偶数行),则扫描下来的一帧图像就被分为了两个部分,这每一部分就称为「场」,根据次序分为:「顶场」和「底场」。「帧」和「场」的概念又带来了不同的编码方式:帧编码、场编码。逐行扫描适合于运动图像,所以对于运动图像采用帧编码更好;隔行扫描适合于非运动图像,所以对于非运动图像采用场编码更好。
NAL Unit 的头占一个字节,由三部份組成,包括 forbidden_bit、nal_reference_idc 和 nal_unit_type。其中 forbidden_bit 占 1 bit,一般来说其值为 0;nal_reference_idc 占 2 bit,用于表示此 NAL 在重建过程中的重要程度。剩下 5 bit 表示 nal_unit_type,用于表示该 NAL Unit (RBSP)的类型:
值 | 定义 |
---|---|
0 | Undefined |
1 | Slice layer without partitioning non IDR |
2 | Slice data partition A layer |
3 | Slice data partition B layer |
4 | Slice data partition C layer |
5 | Slice layer without partitioning IDR |
6 | Additional information (SEI) |
7 | Sequence parameter set(SPS) |
8 | Picture parameter set(PPS) |
9 | Access unit delimiter |
10 | End of sequence |
11 | End of stream |
12 | Filler data |
13..23 | Reserved |
24..31 | Undefined |
举例来说,若截取某一段 H.264 bitstream 为 00 00 00 01 67 42 e0 14 da 05 82 51。其中 00 00 00 01 为 startcode(起始码),每个NALU之间通过 startcode 进行分隔。之后才是 NAL 的数据,因为 67 = 0 11 00111,nal_unit_tye = 00111 = 7,所以这一段为 SPS。SPS 信息在整个视频编码序列中是不变的,用于描述一个视频编码序列;PPS 信息在一幅编码图像之内是不变的,用于描述一个或多个独立的图像。SPS、PPS 的作用是防止在某些数据丢失后,整幅图像都受到影响的情况。
一个视频图像可编码成一个或更多个片(Slice):
SPS、PPS
H.264 引入了参数集的概念,每个参数集包含了相应的编码图像的信息。序列参数集 SPS 包含
的是针对一连续编码视频序列的参数,如标识符 seq_parameter_set_id、帧数及参考帧数目、解码图像尺寸等等。图像参数集 PPS 对应的是一个序列中某一幅图像或者某几幅图像 ,其参数如标识符 pic_parameter_set_id、可选的 seq_parameter_set_id、片组数目等等。
通常, SPS 和 PPS 在片的头信息和数据解码前传送至解码器。每个片的头信息对应一个pic_parameter_set_id, PPS 被其激活后一直有效到下一个 PPS 被激活;类似的,每个 PPS 对应一个 seq_parameter_set_id, SPS 被其激活以后将一直有效到下一个 SPS 被激活。
参数集机制将一些重要的、改变少的序列参数和图像参数与编码片分离,并在编码片之前传送至解码端,或者通过其他机制传输。
H264 vs x264
H264 是一个标准,一种格式,定义了视频流应该如何被压缩编码
x264 是一个开源的编码器,用于产生 H264 格式的视频流
h264 vs avc1
属于 MP4 封装的 H264 视频的两种格式,都是“H264”,区别为:
h264:带起始码 0x00 00 01 或 0x00 00 00 01
avc1:不带起始码
常用软件
1) MediaInfo
用于查看视频参数,比如:

2) VideoEye
雷神写的:开源实时视频码流分析软件:VideoEye
除了查看视频参数之外,还有音视频码流分析等功能
3) ffmpeg
它的三个命令行工具很好用,分别是:
ffplay:用于播放音视频,包括 yuv、pcm 等裸数据
ffprobe:用于查看媒体文件头信息
ffmpeg:强大的媒体文件转换工具,还可以转换图片格式
下载链接:https://www.ffmpeg.org/download.html
4) 其它
YUVPlayer:播放 yuv 裸数据
VLC:多媒体播放器
最后,因为上面的内容不是同一时间写的,哪些内容来自哪些文章都忘得差不多了,这些只列出最重要的几个:
[总结]视音频编解码技术零基础学习方法 (雷神是真大神)
《音视频开发进阶指南》
《新一代视频压缩编码标准》
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!