Tips:
- 音视频文件转 MP4 格式
- MP4 文件由许多个Box与FullBox组成
- 每个Box由Header和Data两部分组成
- FullBox是Box的扩展,其在Box结构的基础上,在 Header 中增加 8 位 version 标志 和 24 位的 flags 标志
-
视频中的 B 帧越多,同等码率时的清晰度将会越高,但是 B 帧越多,编码与解码所带来的复杂度也就越高,所以合理地使用 B 帧非常重要,尤其是在进行清晰度与码率衡量时。
-
音视频转码与转封装不同在于,转码会占用大量的计算资源,转封装则主要是将音频数据或者视频数据取出,然后转而封装成另外一种封装格式。转封装主要占用 IO 资源,而转码主要占用 CPU 资源,同时转码也会使用更多的内存资源。
流媒体
RTMP流
rtmp_app & rtmp_playpath
RTSP
DASH
在 DASH 直播格式中,音视频是分开切片的,也就是说视频是一路切片,音频是一路切片。
libavformat
.1 音视频流封装
image.png<1>
注册
<2>
申请 AVFormatContext
<3>
申请 AVStream
<4>
增加目标容器头信息
<5>
写入帧数据
<6>
写容器尾信息
.2 音视频文件解封装
image.png<1>
av_register_all();
<2>
构建 AVFormatContext
<3>
查找音视频流信息
<4>
读取音视频流
.3 音视频文件转封装
image.png<1>
av_register_all();
<2>
构建 输入AVFormatContext
<3>
查找音视频流信息
<4>
构建 输出 AVFormatContext
<5>
申请 AVStream
<6>
Stream 信息的复制
<7>
写文件头信息
<8>
数据包读取和写入
<9>
写文件尾信息
.4 avio 内存数据操作
image.png<1>
av_register_all();
<2>
读一个文件到内存 av_file_map()
<3>
申请 AVFormatContext
<4>
申请 AVIOContext
<5>
打开 AVFormatContext
<6>
查看音视频流信息
<7>
读取帧
Libavcodec
.1 旧接口视频解码
image.png<1>
av_register_all();
<2>
查找解码器
avcodec_find_decoder
<3>
申请 AVCodecContext
<4>
同步 AVCodecParameters
<5>
打开解码器
<6>
帧解码
<7>
帧存储 - 解码的最终目的是将压缩的数据解码为yuv420p这类色彩数据。
.2 旧接口视频编码
image.png<1>
av_register_all();
<2>
查找编码器
<3>
申请 AVCodecContext
<4>
打开编码器
<5>
申请帧结构 AVFrame
<6>
帧编码
<7>
写封装 - av_interleaved_write_frame
.3 旧接口音频解码
image.png<1>
音频解码
avcodec_decode_video2 & avcodec_decode_audio4
<2>
数据存储至 AVFrame
.4 旧接口音频编码
image.png<1>
编码参数设置
<2>
设置音频参数
<3>
计算音频帧信息
<4>
挂载信息至 AVFrame
<5>
音频编码
<6>
封装 - av_interleaved_write_frame
.1 新接口音频编码
avcodec_encode_audio2 — avcodec_send_frame + avcodec_receive_packet
image.png
<1>
查找和打开编码器
<2>
填充数据
<3>
音频编码
.2 新接口音频解码
avcodec_decode_audio4 - avcodec_send_packet + avcodec_receive_frame
image.png
<1>
查找和打开解码器
<2>
音频解码准备
<3>
音频解码函数
.3 新接口视频编码
image.png.4 新接口视频解码
image.pngLibavfilter
image.png<1>
avfilter_register_all()
<2>
获得滤镜处理的源
<3>
处理 AVfilterGraph
<4>
创建 AVFilterContext
<5>
设置其他参数
<6>
建立滤镜解析器
<7>
数据解码
<8>
获取数据
网友评论