FFmpeg音视频学习(1) 理论准备
理论准备
PCM — Pulse-Code Modulation 脉冲调制编码
一种用数字表示采样模拟信号的方法.
要将一段音频模拟信号转换为数字表示,包含如下三个步骤:
- 1、Sampling(采样)
- 2、Quantization(量化)
- 3、Coding(编码)
PCM常用指标 :
采样率(Sample rate):每秒钟采样多少次,以Hz为单位。
位深度(Bit-depth):表示用多少个二进制位来描述采样数据,一般为16bit。
字节序:表示音频PCM数据存储的字节序是大端存储(big-endian)还是小端存储(little-endian),为了数据处理效率的高效,通常为小端存储。
声道数(channel number):当前PCM文件中包含的声道数,是单声道(mono)、双声道(stereo),此外还有5.1声道(常用于影院立体环绕声)等。
采样数据是否有符号(Sign):要表达的就是字面上的意思,需要注意的是,使用有符号的采样数据不能用无符号的方式播放。
以FFmpeg中常见的PCM数据格式s16le为例:它描述的是有符号16位小端PCM数据。
s表示有符号,16表示位深,le表示小端存储。
如果我们有一个PCM文件,在代码中,我们可以通过以下方式来读取这样的PCM数据流(Stream)。
1 |
|
伪代码仅仅表示一种加载方式。但在代码中,一开始就将整个文件加载到了内存中,这是不对的。因为我们的音频数据量往往会比较大,一次性全部加载增加了内存负担,而且并不必要。
通常我们会为buffer分配一个固定的长度,例如2048字节,通过循环的方式一边从文件中加载PCM数据,一边播放。
加载好PCM数据后,需要送到音频设备驱动程序中播放,这时我们应该能听到声音。与PCM数数据一同到达驱动程序的通常还有采样率(sample rate),用来告诉驱动每秒钟应该播放多少个采样数据。如果传递给驱动程序的采样率大于PCM实际采样率,那么声音的播放速度将比实际速度快,反之亦然。
YUV — 亮度/色度模型
这种模型可以描述每一帧画面的每个像素的亮度和色度, 以此排列起来就组成了视频.
- Y代表亮度, 人对亮度更敏感, 因此要更细致, 对存储占比大.
- UV代表色度, 分别代表蓝红色度, 可以组合成各种颜色.
格式及存储方式(排列方式) :
最经典的格式是 YUV420P
, 是FFmpeg的默认输出.
在这种排列方式中 :
- 每个像素都有独立的Y, 也就是说 x * y 的画面中有 x * y字节的Y数据.
- 每四个(2 * 2)像素中有独立的一组UV, 也就是说 x * y 的画面中有 (x / 2) * (y / 2) 字节的U数据, V等同.
因此一个YUV420p格式的视频帧的内存分布可以表示如下 :
1 |
|
其实就是每个4个像素需要花费6个字节来存储(4Y + 1U + 1V).
基础概念
帧率 :
fps — 每秒播放的图像帧数.
数据大小 = 每帧字节数 × 帧率 × 秒数.
采样率 :
Hz — 每秒采集多少个音频样本点. 用于 音频信号的时间分辨率.
位深 :
每个音频样本用多少个 bit 表示. 控制声音的动态范围(响度).