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
2
3
4
5
FILE *file
int8_t *buffer;
file = fopen("PCM file path");
buffer = malloc(fileSize);
fread(buffer, sizeof(int8_t), fileSize / sizeof(int8_t), file);

伪代码仅仅表示一种加载方式。但在代码中,一开始就将整个文件加载到了内存中,这是不对的。因为我们的音频数据量往往会比较大,一次性全部加载增加了内存负担,而且并不必要。

通常我们会为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
[Y, 大小 W×H][U, 大小 (W/2)×(H/2)][V, 大小 (W/2)×(H/2)]

其实就是每个4个像素需要花费6个字节来存储(4Y + 1U + 1V).

基础概念

  • 帧率 :

    fps — 每秒播放的图像帧数.

    数据大小 = 每帧字节数 × 帧率 × 秒数.

  • 采样率 :

    Hz — 每秒采集多少个音频样本点. 用于 音频信号的时间分辨率.

  • 位深 :

    每个音频样本用多少个 bit 表示. 控制声音的动态范围(响度).


FFmpeg音视频学习(1) 理论准备
http://example.com/2025/06/27/FFmpeg音视频学习(1) 理论准备/
作者
天目中云
发布于
2025年6月27日
许可协议