音视频基础 #1
1. 音频参数 (ZPCM)
采样率 (Sample Rate)
-
采样率 sample_rate 44100 (CD)
1s内 有44100的声音被采集下来,值越大,声音越真实
通道数 (Channels)
一般是左右声道,5.1通道,双通道的话会是 两个通道同时采样。
样本大小/格式 (Sample Size)
AV_SAMPLE_FMT_S16 (16位) AV_SAMPLE_FMT_FLTP (float存储、效率更高)
样本类型
AV_SAMPLE_FMT_S16 在内存的格式就像c1 c2 c1 c2 ...AV_SAMPLE_FMT_S16P 的格式为c1 c1 c1 ... c2 c2 c2 ...2. H264 / AVC 视频编码标准
概述
AVC(Advanced Video Coding) 是一种广泛使用的视频压缩标准,通常称为H.264,能够以较低的比特率提供高质量的视频。
编码架构
- VCL:负责核心的视频编码工作,输出的是表示视频像素数据的切片(Slices)。这是编码器的”核心技术部门”。
- NAL:负责将 VCL 产生的切片以及其他重要信息,封装成一种标准化、适用于网络传输的包,即 NAL 单元。这是公司的”包装和物流部门”
NAL 单元
单纯来看,每个帧都可以视作一个NAL单元 (SPS,PPS)除外,一般来说编码器编出的首个帧中,往往帧前面都带有00 00 00 01 或者 00 00 00 01 分隔符, 再往后就是I帧了。
SPS 和 PPS
SPS(Sequence Parameter Set,序列参数集)和 PPS(Picture Parameter Set,图像参数集)的区别:
SPS:
- 作用于整个视频序列
- 包含视频序列的全局参数,如档次(profile)、级别(level)、分辨率、帧率等
PPS:
- 作用于单个图像(帧)或一组图像
- 包含与图像编码相关的参数,如熵编码模式、量化参数、去块滤波强度等


GOP (Group of Picture)
在视频编码序列中,GOP即Group of picture(图像组),指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧。
所以在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量。
GOP Size (N)
指的是一个GOP内所包含的总帧数。
- 长GOP(N值大):压缩效率高,文件小/码率低。但拖动不灵敏,错误恢复慢。常用于点播、存储。
- 短GOP(N值小):压缩效率低,文件大/码率高。但拖动灵敏,容错性好。常用于直播、视频会议。
GOP Structure (M)
指的是两个参考帧(I帧或P帧) 之间的B帧数量。
一个典型的GOP结构:IBBPBBPBBPBBPBB
开放GOP vs. 封闭GOP
-
封闭GOP:
- 每个GOP都是完全独立的。GOP内的B帧不会引用上一个GOP的帧。
- 优点:无缝拼接、随机访问更精确、容错性好。
- 应用:广播电视、视频编辑、流媒体。
-
开放GOP:
- GOP内的B帧可以向前引用上一个GOP的帧。
- 优点:压缩效率更高。
- 应用:本地文件存储,追求极限压缩率的场景。
GOP 特性对比
| 特性 | 短GOP / 多I帧 | 长GOP / 少I帧 |
|---|---|---|
| 压缩效率 | 低 | 高 |
| 文件大小/码率 | 大 | 小 |
| 随机访问/拖动 | 快且准 | 慢且不准 |
| 容错性 | 高 | 低 |
| 编码延迟 | 低 | 高 |
| 典型应用 | 直播、视频会议、视频编辑 | 视频点播、文件存储 |
3. 视频流的完整构成
第一部分:全局说明书(参数集)
这是全书的前言和目录,告诉解码器如何解读后续所有内容。
-
SPS(序列参数集):
- 相当于全书的出版规格:纸张大小(分辨率)、印刷色彩标准(色彩空间)、装订方式(编码档次)。
- 定义了整个视频序列的全局参数。
-
PPS(图像参数集):
- 相当于章节排版规范:字体大小、行间距、页边距。
- 定义了单帧图像的编码细节。
-
VPS(视频参数集,H.265/HEVC特有):
- 相当于多卷本的协调说明,用于复杂场景和多层编码。
重要性:没有这些说明书,后面的视频数据完全无法解码!
第二部分:内容组织单元(GOP序列)
这是全书的核心内容,由多个章节(GOP) 连续组成。
[GOP 1] → [GOP 2] → [GOP 3] → ... → [GOP N]每个GOP(章节)内部包含:
- I帧(章节开头):完整的独立页面,不依赖前后内容就能看懂。
- P帧(承上启下的段落):基于前面内容的总结和发展,只写变化的部分。
- B帧(细节补充):同时参考前后内容,做最精细的描述。
第三部分:辅助信息(元数据)
这些是书中的脚注、批注和索引。
- SEI(补充增强信息):包含时间码、版权信息、编码设置等。
- AUD(访问单元分隔符):相当于章节标记,明确指示每一帧的开始位置。
第四部分:实际的数据切片
这是书中的具体文字和图片。
- 切片(Slices):一帧图像可能被分割成多个切片,每个切片封装在一个NAL单元中。
完整视频流的时序结构
[全局说明书区]SPS → PPS → VPS(可选) → SEI[内容数据区 - 循环往复]→ AUD → I帧切片 → I帧切片 ... ← GOP 1开始→ AUD → B帧切片 → B帧切片 ...→ AUD → P帧切片 → P帧切片 ...→ AUD → B帧切片 → B帧切片 ...→ AUD → I帧切片 → I帧切片 ... ← GOP 2开始(可能是场景切换)...(继续循环)...不同封装格式的影响
视频流可以存储在不同的”书架”(容器)中:
- 原始H.264/H.265流(.h264, .hevc):NAL单元的原始序列。
- MP4/MKV文件:将NAL单元重新组织,添加索引。
- 传输流(TS):将NAL单元分割成固定大小的包,添加时间戳和纠错信息。
4. FFmpeg SDK 软硬解码基础
处理流程
解封装 -> 软硬编码 -> 像素格式转换 -> 重采样 -> pts/dts -> 同步策略
解封装函数
av_register_all()- 注册所有的封装格式,全局注册avformat_network_init()- 通过网络打开文件avformat_open_input(...)avformat_find_stream_info()- 打开文件并解析av_find_best_stream(...)- 查找最佳流
核心数据结构
AVFormatContext - 格式上下文
比喻:整个DVD光盘 + DVD播放机
// 它包含的信息就像DVD播放机的屏幕显示:AVFormatContext { - 文件格式: "MP4", "AVI", "MKV" // 就像知道是DVD、VCD还是蓝光 - 持续时间: 2小时15分钟 // 影片总长度 - 比特率: 1500 kbps // 数据读取速度 - 元数据: 标题、作者、版权信息 // 光盘封面信息 - 流列表: [视频流, 音频流1, 音频流2, ...] // 光盘包含的所有轨道 - 文件位置: 当前播放到01:23:45 // 当前播放进度}AVStream - 流信息
比喻:光盘里的不同轨道
// 每个轨道的信息:AVStream { - 流类型: 视频 / 音频 / 字幕 // 这是什么轨道? - 编解码器参数: H.264, AAC, SRT // 数据的编码格式 - 时间基: 1/1000 秒 // 时间计量单位 - 帧率: 25 fps // 视频帧率 - 分辨率: 1920x1080 // 视频尺寸 - 采样率: 44100 Hz // 音频采样率 - 时长: 2小时15分钟 // 该轨道的长度 - 索引: 0, 1, 2... // 轨道编号}AVPacket - 数据包
比喻:从光盘里读取出来的一小段压缩数据
// 每个数据包就像一截电影胶片:AVPacket { - 数据指针: 指向压缩数据的内存地址 // 胶片上的图像 - 数据大小: 65536 字节 // 胶片的长度 - 流索引: 0 // 属于哪个轨道? - 显示时间戳(PTS): 123456 // 什么时候显示? - 解码时间戳(DTS): 123450 // 什么时候解码? - 持续时间: 40ms // 播放多长时间? - 关键帧标志: 是/否 // 是否是I帧?}操作函数比喻
avformat_open_input() // 插入光盘到播放机avformat_find_stream_info() // 读取光盘目录信息av_read_frame() // 从光盘读取下一段数据avformat_close_input() // 弹出光盘,关闭播放机对于 H.264/H.265 视频流
在大多数情况下:
- 一个 AVPacket 包含一个完整的 NAL 单元
- AVPacket 的
data字段指向的就是 NAL 单元的起始位置
// 典型情况:一个AVPacket对应一个NAL单元AVPacket { .data = [NAL起始码] [NAL头] [NAL负载] // 整个NAL单元数据 .size = NAL单元的总长度 .stream_index = 视频流索引}总结关系
| FFmpeg结构 | 比喻 | 职责 | 生命周期 |
|---|---|---|---|
| AVFormatContext | DVD播放机+光盘 | 管理整个媒体文件 | 从打开文件到关闭文件 |
| AVStream | 光盘轨道 | 描述单一媒体流的信息 | 存在于FormatContext的生命周期内 |
| AVPacket | 电影胶片段 | 存储压缩的媒体数据 | 短暂存在,解码后即可释放 |
部分信息可能已经过时