FFmpeg前传,音视频呀😳
FFmpeg 剧情前传
在使用ffmpeg之前还是要有一些音视频基础知识的,虽然不多,但是在满足日常需求应该足够啦,防止我失忆,赶紧把知道的记录一下。
音频处理基础知识
音频处理流程(基于娱乐直播系统)

- 音频数据流转
采集音频的原始数据为 PCM 数据
多媒体文件(mp4/flv 等)在传输过程中可以不用生成,如果向保存成常用格式可以被播放那就当我没说。
声音基础三要素
- 音调 音频的快慢
- 音色
谐波: 此处峰值最高的绿色波形为基频,变化全部在基频之上进行变化,通过两条峰值较低的频率,将基频变成粉色波线的频率, 而此处,粉色的波型,顶峰弯曲部分则称为谐波, 两条小的波形为一次谐波和二次谐波 - 音量 振动的幅度,初中都知道就不说了。
模数转换
对模拟信号进行数字量化
-
每隔一段时间对模拟信号进行采样



音频常用原始数据及基本量化概念
原始数据常用格式
- PCM
- WAV
基本量化三个概念(在视频采样时,也是可以进行类比)
- 采样大小(位深): 一个采样用多少 bit 存放。常用的是 16bit(16 位 位深)
- 采样率: 采样频率 8k, 16k, 32k, 44.1k, 48k
- 声道数: 单声道,双声道,多声道
码率计算
eg: 采样率为 44.1KHz, 采样大小为 16bit, 双声道 PCM 数据编码的 WAV 文件,码率为 44.1K x 16 x 2= 1411.Kb/s
相当于每秒传输 1.4mb 大小的数据
WAV 编码数据,相当于在 PCM 数据上添加了一个 Header 来描述 PCM 数据

例如使用ffmpeg从flv视频中提取出音频wav数据文件并且使用xxd转换为16进制文件
ffmpeg -i v1.flv -vn -acodec pcm_s16le -ar 44100 -ac 2 out.wav
使用vim打开wav文件,并且使用xxd进行转换。
vim out.wav
# 在vim内的命令模式下
:%!xxd
下面是部分观察到的数据。

FFmpeg 采集音频流程
整体流程

打开设备
- 注册设备
- 相关 api
#include "libavdevice/avdevice.h" avdevice_register_all(); - 设置采集方式 avfoundation(mac)/dshow(windows)/alsa(linux)
- 相关 api
#include "libavformat/avformat.h" AVInputFormat *iformat = av_find_input_format("audiostring") - 打开音频设备
- 相关 api
#include <libavcodec/avcodec.h> AVFormatContext *fmt_ctx = NULL; AVDictionary *options = NULL; int ret = avformat_open_input(&fmt_ctx, "device_name", iformat, &options); // 释放上下文 avformat_close_input(&fmt_ctx);- 获取数据包相关 api
AvPacket pkt; av_read_frame(fmt_ctx, &pkt); // 初始化资源 av_init_packet(&pkt); // 释放资源 av_packet_unref(&pkt);
录制音频
- 创建文件
- 将数据写入文件
- 关闭文件
音频编码(压缩)
-
消除冗余信息(有损压缩) (人耳听觉范围之外的音频信号以及被遮蔽掉的音频信号)
-
频域遮蔽

-
时域遮蔽

-
-
无损压缩(zip 等) 熵编码 _ 哈夫曼编码 _ 算数编码 * 香农编码
音频编码过程

常见的音频编码器
- OPUS 较新 WebRTC 默认使用 OPUS
- AAC 在直播系统中应用广泛
- Ogg
- Speex
- iLBC
- AMR
- G.711
音频编码质量比较

音频编码码率

AAC 格式

ADTS 格式详解

- header 二进制含义查看网址 http://www.p23.nl/projects/aac-header/
音频重采样
将音频三元组(采样率,采样大小和通道数)的值转成另外一组值 eg: 44100/16/2 -> 48000/16/2
重采样的步骤
- 创建采样上下文
- 设置参数
- 初始化重采样
- 进行重采样
- 涉及 api
swr_alloc_set_opts swr_init swr_convert swr_free
ffmpeg 编码过程

创建并打开编码器
- 创建编码器 avcodec_find_encoder
- 创建上下文 avcodec_alloc_context3
- 打开编码器 avcodec_open2
视频基础
基础概念
- 视频由一组图像组成,而图像又由像素组成,像素又由 RGB 组合而成
码流的计算
分辨率
- X 轴的像素个数 x Y 轴的像素个数
- 常见宽高比 16:9 / 4:3
- 360P/72P/1K/2K
帧率
- 每秒钟采集/播放图像的个数
- 动画的帧率是 25 帧/s
- 常见的帧率: 15 帧/s(满足实时通话), 30 帧/s, 60 帧/s
未编码的 RGB 码流
eg: 1280x720x3x25 = 69120000 约 69M 通常说的码流用位来表示,此处还得乘 8
图像的显示
- 图像等于显示区域
- 图像小于显示区域(拉伸/留白)
- 图像大于显示区域(缩小/截断)
YUV
YUV(也称 YCBCr): Y 表示明亮度, UV 的作用是描述的影像色彩及饱和度
- 如果只存在 Y 数据,则图像位黑白
- Cb 表示蓝色部分, Cr 部分表示红色部分
主要的采样格式有 YUV4:2:2, YUV4:2:2 和 YUV4:4:4
RGB 与 YUV 的关系
- RGB 用于屏幕图像展示
- YUV 用于采集与编码
RGB 转 YUV
YUV 转 RGB
YUV 常见格式
-
YUV4:4:4

-
YUV4:2:2

-
YUV4:2:0(应用最广泛) 4:2:0

YUV 数据量的计算
YUV4:2:0 存储格式

YUV 码流
H264 视频编码
GOP (Group of Pictures)
I/P/B IDR 帧
I 帧之前存在两个数据集,反别描述图像序列与图像本身

- I 帧(interframe frame), 关键帧,采用帧内压缩技术, IDR 帧属于 I 帧
- P 帧(forward Predicted frame), 向前参考帧.压缩时,只参考前面已经处理的帧,采用帧间压缩技术. 它占 I 帧的一半大小
- B 帧(Bidirectionally predicted frame), 双向参考帧。压缩时,既参考前面已经处理的帧,也参考后面的帧,帧间压缩技术。它占 I 帧的 大小
- IDR 帧(Instantaneous Decoder Refresh) 解码器立即刷新帧
- 每当遇到 IDR 帧时,解码器就会清空解码器惨开 buffer 中的内容
- 每个 GOP 中的第一帧就是 IDR 帧
- IDR 帧是一种特殊的 I 帧
帧与分组的关系

先解码 I 帧,再解码 P 帧,B 帧参考前面的 I 和后面的 P 帧 而播放时,读取帧就是顺序读取
H264 压缩技术
宏块
- 宏块是视频压缩操作的基本单元
- 无论是帧内压缩还是帧间压缩,它们都以宏块位单位

帧内压缩
解决空域数据冗余问题(有损压缩)
帧内压缩理论
注:帧内压缩解决的是 I 帧的压缩问题
- 相邻像素差别不大,所以可以进行宏块预测
- 帧内预测
- 9 种预测模式

内部4x4矩形为预测结果 分别为垂直,水平,平均值预测结果 预测图象与原图进行比较 - 帧内预测残差值 原始图与预测图的差值计算获取残差值 - 压缩 预测模式信息与残差值压缩 压缩图解 - 9 种预测模式
- 帧内预测
- 人对亮度的敏感超过色度
- YUV 很容易将亮度与色度分开
帧间压缩
解决时域数据冗余问题(有损压缩)
GOP
进行帧间压缩的基础为 GOP,即在同一组画面相邻的图像间进行压缩
参考帧
见 I/P/B 帧部分
运动估计(宏块匹配 + 运动矢量)
- 宏块查找
- 三步搜索
- 二维对数搜索
- 四步搜索
- 钻石搜索 查找宏块当前帧的坐标,并查找下一帧相似度最高宏块的坐标,这两个坐标即为运动矢量 整个过程即为 运动估计 需要存储的即为运动矢量


运动估计也存在残差值
-
视频花屏的原因
如果 GOP 分组中有帧丢失,会造成解码端的图像发生错误,出现花屏现象
-
视频卡顿的原因

整数的离散余弦变换(DCT)(无损压缩)
将空间上的相关性变为频域上无关的数据然后进行量化(无损压缩)
VLC (变长编码) 压缩(无损压缩)

CABAC 压缩(无损压缩)

H264 编码整体流程

H264 码流
- NAL 层(Network Abstration Layer) 视频数据网络抽象层
- VCL 层(Video Coding Layer), 视频数据编码层
码流的基本概念
-
H264 Slice

-
SODB (String of Data Bits) 原始数据比特流,长度不一定是 8 的倍数,需要补齐,由 VCL 层产生
-
RBSP (Raw Byte Sequence Payload) SODB + trailing bites 算法是如果 SODB 最后一个字节不对齐,则补 1 和多个 0
-
NALU (Network Abstration Layer Unit) NAL Header(1B) + RBSP

整体码流分层

Profile and Level (SPS(sequence paramater set))
H264 Profile
对视频压缩特性的描述,Profile 越高,说明采用了越高的压缩特性

H264 Level
Level 是对视频的描述,Level 越高,视频的码率,分辨率,fps 越高

PPS(Picture parameter set) and slice header
PPS

Slice Header
- 帧类型
- GOP 中解码帧序号
- 预测权重
- 滤波
RTMP 协议相关
....有时间再记录
评论 (...)
加载中...