前言
各种api,流程,比如编码流程需要什么参数,调用什么api都记不住,很正常,我也记不住,记住一下4条骨架即可
1. 视频编码骨架
准备编码器
准备目标帧
输入裸数据
做格式转换
设置 pts
send_frame
receive_packet
流程例如:
BGRA -> YUV420P -> H.264 packet
2. 音频编码骨架
准备编码器
准备重采样器
输入 PCM
做格式转换/重采样
设置 pts
send_frame
receive_packet
例如:
PCM S16 -> FLTP -> AAC packet
3.封装骨架
创建输出容器
添加视频流
添加音频流
写 header
写 packet
写 trailer
也就是:
packet -> MP4
4. 调度同步骨架
打开音视频输入
比较当前音频时间和视频时间
谁落后先处理谁
最后 flush
也就是:
cpp
谁慢补谁
参数也不要散着记
觉得会乱,是因为你在脑子里觉得参数太碎。
其实它们可以分成 3 组:
输入参数
描述裸流原料是什么:
- 视频:width height fps in_pix_fmt
- 音频:sample_rate channels in_sample_fmt
编码目标参数
描述你想压成什么:
- 视频:out_pix_fmt bitrate
- 音频:out_sample_fmt bitrate
时间参数
决定同步怎么走:
- 视频:time_base = 1/fps
- 音频:time_base = 1/sample_rate
- 视频 pts:按帧加
- 音频 pts:按采样数加
你以后看到参数,不要一个个散着记,而是先问:
- 这是描述输入原料的?
- 这是描述编码目标的?
- 还是描述时间线的?
这样脑子就不会乱。
API 记不住怎么办
很简单,分层记,不要平铺记。
你只先记每层最核心的 2~3 个:
视频层
- sws_scale
- avcodec_send_frame
- avcodec_receive_packet
音频层
- swr_convert
- avcodec_send_frame
- avcodec_receive_packet
封装层
- avformat_write_header
- av_interleaved_write_frame
- av_write_trailer
调度层
- 不用记 FFmpeg API
- 只记逻辑:比较 video_time / audio_time
这样一下子就轻很多。