1. 基本概念
1. FourCC(四字符代码)
-
定义:FourCC是一个4字节的代码,用于标识视频编码器(Codec)。例如,'avc1'代表H.264编码,'mp4v'代表MPEG-4编码。FourCC 是多媒体行业的国际标准标识符系统。
-
作用:告诉系统或播放器使用哪种编解码器来解码视频流。
-
示例 :在OpenCV中,我们使用
cv2.VideoWriter_fourcc(*'avc1')来指定使用H.264编码器。
2.编解码器
FourCC 是严格标准化的 ,每个编解码器通常对应一个标准 FourCC:
| 编解码器 | 标准 FourCC | 说明 |
|---|---|---|
| H.264/AVC | avc1 |
唯一标准标识 |
| H.265/HEVC | hev1或 hvc1 |
有两个标准变体 |
| MPEG-4 Part 2 | mp4v |
标准标识 |
| MPEG-1 | mp1v |
标准标识 |
| Motion JPEG | MJPG |
标准标识 |
3. 文件后缀(File Extension)
-
定义:文件后缀是文件名的一部分,用于指示文件格式(例如.mp4、.avi)。
-
作用:帮助操作系统和应用程序识别文件类型,从而用正确的程序打开它。
-
示例:一个文件名为"video.mp4"的后缀是".mp4"。
4. 视频容器(Container)
-
定义:容器是一种文件格式,用于存储视频流、音频流、字幕等多媒体数据。常见的容器有MP4、AVI、MKV等。
-
作用:容器将不同的数据流封装在一起,并提供同步播放的信息。
-
示例:MP4容器可以包含H.264编码的视频和AAC编码的音频。
常见容器:
-
MP4:现代标准,支持H.264/H.265
-
AVI:较旧但兼容性好
-
MKV:功能丰富,支持多种编码
-
MOV:Apple QuickTime 格式
2. 区别与联系
区别
-
FourCC是标识编解码器的代码,它关注的是视频数据的压缩方式。
-
文件后缀是文件名的扩展名,它通常与容器类型对应。
-
容器是文件的整体格式,它规定了如何存储视频、音频等数据。
联系
-
一个容器可以支持多种编解码器。例如,MP4容器可以包含H.264(FourCC为'avc1')或MPEG-4(FourCC为'mp4v')编码的视频。
-
文件后缀通常反映容器的类型。例如,MP4容器通常使用".mp4"后缀。
-
当我们创建视频文件时,需要同时选择容器和编解码器。在OpenCV中,我们通过文件后缀指定容器,通过FourCC指定编解码器。
┌─────────────────────────────────────────────────────────────┐
│ 视频文件 (如:video.mp4) │
├─────────────────────────────────────────────────────────────┤
│ 容器格式:MP4 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 视频流 音频流 │ │
│ │ FourCC: avc1 编码: AAC │ │
│ │ (H.264编码) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
应用层
↓
文件后缀 (.mp4) ← 用户可见
↓
视频容器 (MP4) ← 文件格式规范
↓
编码器 (avc1) ← 压缩算法标识(FourCC)
↓
原始视频数据 ← 实际像素信息
3. 容器示例
常见的FourCC编码器和对应的文件后缀:
MP4容器
| FourCC 编码器 | 描述 | 推荐后缀 | 兼容性 |
|---|---|---|---|
'avc1' |
H.264/AVC 标准编码 | .mp4 |
⭐⭐⭐⭐⭐ |
'h264' |
H.264 编码 | .mp4 |
⭐⭐⭐⭐ |
'x264' |
x264 编码器 | .mp4 |
⭐⭐⭐⭐ |
'mp4v' |
MPEG-4 Part 2 | .mp4 |
⭐⭐⭐⭐⭐ |
AVI 容器(高兼容性)
| FourCC 编码器 | 描述 | 推荐后缀 | 兼容性 |
|---|---|---|---|
'XVID' |
MPEG-4 编码 | .avi |
⭐⭐⭐⭐⭐ |
'DIVX' |
DivX 编码 | .avi |
⭐⭐⭐⭐ |
'MJPG' |
Motion JPEG | .avi |
⭐⭐⭐⭐⭐ |
'PIM1' |
MPEG-1 | .avi |
⭐⭐⭐ |
MOV 容器(macOS 友好)
| FourCC 编码器 | 描述 | 推荐后缀 | 兼容性 |
|---|---|---|---|
'avc1' |
H.264 | .mov |
⭐⭐⭐⭐ |
'mp4v' |
MPEG-4 | .mov |
⭐⭐⭐⭐ |
'rle ' |
动画编码 | .mov |
⭐⭐ |
4. 在OpenCV中的使用
参考文章 "AI视觉算法中的OpenCV API (二)"
1.国际标准 vs OpenCV 实现的差异对比表
| 特性 | 国际标准 | OpenCV 实现 | 说明 |
|---|---|---|---|
| 大小写 | 理论上不区分 | 偏好小写 | OpenCV 内部转换 |
| 字符集 | 4字节ASCII | 4字符字符串 | 本质相同 |
| 兼容性 | 广泛支持 | 有限支持 | OpenCV 依赖后端 |
| 错误处理 | 严格验证 | 宽松+回退 | OpenCV 更用户友好 |
2.OpenCV对FourCC的适配和容错
OpenCV在设计上考虑到了用户使用的方便性,因此对FourCC代码进行了以下适配:
-
大小写转换:尽管FourCC标准是区分大小写的(因为FourCC是4个字节,每个字节都是ASCII字符,不同大小写对应的字节值不同),但OpenCV在内部会将用户输入的代码转换为标准大小写,然后再进行匹配。这样,用户输入"AVC1"和"avc1"在OpenCV中会被视为相同。
'XVID', '大写' # ❗这个比较特殊 -
映射和回退机制:OpenCV维护了一个映射表,将一些常见的非标准FourCC代码映射到标准代码。例如,当用户输入"H264"时,OpenCV可能会将其映射到"avc1"。这是因为"H264"并不是标准的FourCC代码(标准的H.264的FourCC是"avc1"),但很多用户会习惯性地使用"H264"。OpenCV通过映射表来提高容错性。
-
后端依赖:OpenCV本身并不实现所有的编解码器,而是依赖于后端的多媒体框架(如FFmpeg、GStreamer等)。因此,OpenCV支持的FourCC代码集实际上取决于后端支持哪些编解码器。OpenCV会尝试使用用户指定的FourCC代码,如果后端不支持,它可能会回退到某种默认的编解码器(如果可能的话)。
- 降低学习曲线:用户不需要记忆精确的FourCC
- 提高代码可读性:'h264'比'avc1'对新手更直观
- 错误容错:错误拼写也能工作
- 社区习惯:尊重现有的编程习惯
- 平滑过渡:从非标准逐步迁移到标准
- 用户输入 'h264' → 自动映射为 'avc1' → 成功
3.推荐使用的FourCC代码
对于不同的容器格式,推荐使用的FourCC代码如下:
MP4容器(.mp4文件)
MP4容器通常与H.264编码器配合使用,因此推荐使用:
-
avc1:这是标准的H.264编码的FourCC代码,具有很好的兼容性,尤其是在现代设备和播放器上。 -
mp4v:这是MPEG-4 Part 2编码器的FourCC代码。如果系统不支持H.264,可以回退到MPEG-4。但注意,MPEG-4 Part 2的压缩效率不如H.264。
因此,对于MP4容器,优先使用avc1,如果不行再尝试mp4v。
AVI容器(.avi文件)
-
XVID:一种流行的MPEG-4 Part 2编码器,兼容性好。 -
MJPG:Motion JPEG,质量高但文件大。 -
DIVX:DivX编码器,也是MPEG-4 Part 2的一种。
对于AVI容器,推荐使用XVID,因为它具有较好的压缩比和兼容性。
4.不是所有 FourCC 都能用于 OpenCV
所有国际标准 FourCC
↓(过滤)
FFmpeg/GStreamer 支持的 FourCC
↓(过滤)
系统已安装的编解码器
↓(过滤)
OpenCV 编译时启用的功能
↓
实际可用的 FourCC
5. 注意事项
-
兼容性:不同的系统和播放器对编解码器和容器的支持程度不同。H.264编码的MP4文件具有最好的兼容性。
-
匹配问题:不是所有的编解码器都能用于所有的容器。例如,'XVID'编解码器通常与AVI容器一起使用,而不是MP4容器。