删繁就简,音视频的处理流程可以划分为如下几个大的步骤:
- 采集(声音-图像的数字化)
- 编码(压缩数据便于存储和传输):音频、视频都有各自的编码格式
- 封装(按格式封装便于控制音视频的展现):flv、mkv、avi等,将音频、视频数据打包整合成一个文件
- 传输(用于网络):视频文件涉及到流媒体协议,单纯的音频就没有这么多限制
- 解封装:把音频数据、视频数据从封装的文件中分离出来
- 解码:将压缩过的音频、视频文件解压成原始的yuv/rgb(图片)、pcm(音频)数据
- 渲染
基础概念
封装格式
音视频文件的后缀,像是mp4、avi、flv、mkv等,这些代表的是封装格式,就是如何把视频数据、音频数据打包成一个文件的规范。
封装格式的主要作用是把视频码流和音频码流按照一定的格式存储在一个文件中,常见的音视频封装格式如下:
名称 | 推出机构 | 流媒体 | 支持的视频编码 | 支持的音频编码 | 使用领域 |
---|---|---|---|---|---|
avi | 微软 | 不支持 | 几乎所有格式 | 几乎所有格式 | |
mp4 | MPEG | 支持 | mpeg-2,mpeg-4,h264,h263等 | AAC, MPEG-1 Layers I, II, III, AC-3等 | |
ts | MPEG | 支持 | MPEG-1, MPEG-2, MPEG-4, H.264 | MPEG-1 Layers I, II, III, AAC | |
flv | Adobe | 支持 | Sorenson, VP6, H.264 | MP3, ADPCM, Linear PCM, AAC等 | |
mkv | CoreCodec Inc | 支持 | 几乎所有格式 | 几乎所有格式 |
除了avi之外,其他格式都支持流媒体,即可以“边下边播”。
多媒体文件基本概念
- 多媒体文件就是一个容器
- 在容器中有很多的流(Stream/ Track)
- 每种流是由不同的编码器编码而成的
- 从流中读取的数据称为包
- 一个包中包含一个或多个帧
RGB-YUV-PCM
RGB、YUV是图片存储的格式。PCM是音频采样格式
一般用YUV来做压缩
音频
音频编码
音频编码的主要作用是将音频采样数据(PCM等)压缩成音频码流,从而降低音频的数据量。主要的音频编码格式:
名称 | 推出机构 | 推出时间 | 使用领域 |
---|---|---|---|
AAC | MPEG | 1997 | 各个领域 |
AC-3 | Dolby | 1992 | 电影 |
MP3 | MPEG | 1993 | 各个领域 |
WMA | 微软 | 1999 | 微软平台 |
代码库实现:
- AAC:libfdk-aac
音频的量化编码
- 模拟信号到数字信号的转换过程(连续->离散)
- 模拟信息->采样->量化->编码->数字信号
- 量化的基本概念:采样大小=一个采样点用多少个bit存放,常用是16bit
- 采样率:一秒内采样的次数,一般采样率越高,声音还原度越高
- 声道数:从不同的方位同时获取声音,每个方位就是一个声道
- 码率:每秒传输的bit数,比特率越高,每秒传输数据就越多,音质就越好
码率计算公式:
码率 = 采样率 * 采样大小 * 声道数
比如采样率44.1kHz,采样大小为16bit,双声道PCM编码的WAV文件:
码率=44.1hHz*16bit*2=1411.2kbit/s。
录制1分钟的音乐的大小为(1411.2 * 1000 * 60) / 8 / 1024 / 1024 = 10.09M。
声道类型
从声道数量上划分:
- 单身道
- 双声道
- 多声道
从感官上来划分:
- Mono 单身道
- Stereo 立体声
2.0音响是最常见的音响系统,2.0音响为两通道立体声音响,一般的电脑音响都分为左右双声道,一共两个箱体,也有条形音响将左右两个喇叭合二为一的设计。采用两分频设计,每个单元都采用了一个独立的中低频单元和一个高频单元。适合欣赏音乐。
2.1音响同样是最常见的音响系统之一,常见的2.1音响分为一个独立的低音单元和两个中高音单元,所以2.1音响系统可以在低音上发挥更好,对于爆炸、摇滚的声音可以得到更好的听感,更适合电竞玩家以及摇滚乐爱好者。
5.1音响相比以上两种音响系统就更加复杂了,也是高级音响系统的入门门槛,5.1音响系统包括6个音响:2个前置音箱、2个后置音箱、1个中置环绕音箱、1个重低音音箱。增加的中置环绕音箱对于加强人声很有效果,可以把电影中的对话声音集中到系统中央,从而提高临场感。5.1音响系统对于喜欢听脚步的电竞玩家来说也很有效果,可以明显的判断出声音的方向。但是相比音箱数量更多的7.1系统来说还有欠缺。
7.1音响是目前消费市场最复杂的音响系统,7.1音响系统包括8个音箱:2个前置音箱、2个后置音箱、1个前中置环绕音箱、2个后中置环绕音箱、1个重低音音箱。两个后中置环绕音箱是为了防止因为位置偏差而产生听觉上的偏差。现在绝大多数的蓝光电影都提供了7.1声道的音源,7.1音响系统对于搭建一套完美的家庭影院是很有必要的。并且对于游戏的体验也是极佳,这也是很多游戏耳麦在宣传7.1声道的原因。可以更容易的分辨声音的方向来源。并且你主板上的6个音频接口也是为了5.1、7.1音响系统而准备的。
I/B/P帧
- I帧是关键帧,它采用帧内压缩技术;
- B帧是前后参考帧,它属由帧间压缩技术。也就是说在压缩成 B帧前,它会参考它前面的非压缩视频帧,和后面的非压缩的视频帧,记录下前后两帧都不存放的“残差值”,这样可以达到更好的压缩率;
- P帧是向前参考帧,也就是它参考的是前一个关键帧的数据。P帧也属于帧间压缩技术,相对于 B帧来说,P帧的压缩率要比B帧低。
音频重采样
1. 什么是重采样
通俗的讲,就是改变音频的采样率、采样格式(sample format)、声道数(channel)等参数,使得音频文件能够按照我们期望的样子输出。
2. 为什么要进行音频信号重采样?
音频最终是要被设备所播放的,因为不同的设备能够支持的音频格式不一样,假设一个小音箱是播放双声道16位44.1khz或者48khz的音频,那么你一个单声道16位44.1khz的音频文件放出来就有问题。所以我们就需要对音频进行重采样来构造目标设备需要的格式。
3. 重采样的原理
todo
视频
视频编码
视频编码的主要作用就是将视频的像素数据(RGB,YUV等)压缩成视频码流,从而降低视频的数据量。主流的视频编码规范:
名称 | 推出机构 | 推出时间 | 使用领域 |
---|---|---|---|
HEVC(H.265) | MPEG/ITU-T | 2013 | |
H.264 | MPEG/ITU-T | 2003 | 各个领域 |
MPEG4 | MPEG | 2001 | 不温不火 |
MPEG2 | MPEG | 1994 | 数字电视 |
VP9 | 2013 | 研发中 | |
VP8 | 2008 | 不普及 | |
VC-1 | Microsoft Inc. | 2006 | 微软平台 |
这些定义了编码规范,具体的代码库实现:
- HEVC:libx265
- H.264:libx264
- VP8/VP9:libvpx
时间基
- PTS:presentation time stamp,显示时间戳,这个时间戳用来告诉播放器该在什么时候显示第一帧的数据
- DTS:decode time stamp,解码时间戳,主要是标识读入内存中的bit流什么时候开始送入解码器进行解码
- time_base:时间基,可以理解成时间片单元
- tbr:time base rate,是我们通常所说的帧率
- tbn:time base stream,视频流的时间基
- tbc:time base codec,视频解码的时间基
PTS、DTS是时间刻度,不是秒,不是具体的时间值,是一个计量数。
**问题:为什么要有时间基转换?**因为不同的封装格式,timebase是不一样的
使用如下结构代表time_base,num是分子,den是分母。之所以不采用1/20这种表示方法,是因为除法表示会损失精度。
/**
* Rational number (pair of numerator and denominator).
*/
typedef struct AVRational{
int num; ///< Numerator
int den; ///< Denominator
} AVRational;
1. ffmpeg内部时间基
#define AV_TIME_BASE 1000000
#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
在ffmpeg中进行换算时,将不同的时间基转成秒单位的计算方式:
timestamp(秒) = pts * av_q2d(time_base);
解复用
将多媒体文件中的流找出来。
AVFormatContext *format_ctx = nullptr;
avformat_open_input(); //1,打开多媒体文件
avformat_find_stream_info(); //2,找到多媒体文件中的所有流信息
找到多媒体文件中的流信息后,会存储到format_ctx中,其中:
- nb_number:多媒体中含有的流总数
- stream[]:流信息数组
可以通过format_ctx->streams[i]->codecpar->codec_type知道流的类型。
enum AVMediaType {
AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA
AVMEDIA_TYPE_VIDEO,
AVMEDIA_TYPE_AUDIO,
AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous
AVMEDIA_TYPE_SUBTITLE,
AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse
AVMEDIA_TYPE_NB
};
关键帧
参考资料
- PCM wiki in multimedia
- PCM音量控制
- PCM音频采样数据处理
- stackoverflow/What is the difference between AV_SAMPLE_FMT_S16P and AV_SAMPLE_FMT_S16?
- 音视频基础概念合集:148 个问题带你快速上车音视频 - 简书 (jianshu.com)
- 深入理解pts,dts,time_base - 知乎 (zhihu.com)
- ffmpeg中的时间戳与时间基_慕课手记 (imooc.com)
- 音频信号重采样知识
- 关于PCM音频重采样思路及注意事项(频率变换和通道数变换(单通道转双通道))
- 视频压缩编码和音频压缩编码的基本原理
- PCM数据格式介绍
...