作者:yoyokk99的秋天 | 来源:互联网 | 2023-07-27 20:03
ffmpeg 结构以及作用:
- AVUtil: 核心工具库
- AVFormat:提供了音视频容器格式的封装和解析以及所支持的协议文件格式和协议库
- AVCodec: 编解码库
- AVFilter: 音视频滤镜库 如视频加水印、音频变声
- AVDevice: 输入输出设备库,提供设备数据的输入与输出,如读取摄像头数据、屏幕录制
- SwrRessample: 音频重采样
- SWScale: 图像格式转换的模块,yuv -> rgb
- PostProc:后期处理
解码流程:
-
av_register_all:
先调用avcodec_register_all来注册所有config.h里面开放的编解码器,然后会注册所有的Muxer和Demuxer(也就是封装格式),最后注册所有的Protocol(即协议层的东西)
-
avformat_alloc_context:
分配初始化一个AVFormatContext结构体
-
avformat_open_input:
解码时,根据文件路径判断文件格式,决定使用哪个Demuxer,构建好AVStream
-
avformat_find_stream_info:
解码时,作用是从文件中提取流信,将所有的Stream的MetaData信息填充好,先read_packet一段数据解码分析流数据
-
穷举所有的流,查找其中种类为 CODEC_TYPE_VIDEO
-
avcodec_find_decoder:
作用是找解码器,avcodec_resgister_all已经将解码器和编码器放到一个链表中,根据codec Id和name循环遍历找出
-
avcodec_open2:
avcodec_open2(AVCodecContext, Codec, NULL)
作用是打开编码器或解码器
-
avcodec_alloc_frame:
为解码帧分配内存
-
不停地从码流中提取出帧数据 av_read_frame:
解码时,读取出AVPacket,对应音频流,一个AVPacket可能包含多个AVFrame,对应视频流,一个AVPacket对应一个AVFrame
-
判断帧的类型,对于视频帧调用: avcodec_decode_video:
-
avcodec_close:
释放解码器
-
av_close_input_file:
关闭输入文件
编码流程
-
avformat_alloc_output_context2:
初始化输出码流的 AVFormatContext
-
avio_open:
打开输出文件
-
av_new_stream:
创建输出码流的 AVStream
-
avcodec_find_encoder:
查找编码器。
-
avcodec_open2:
打开编码器
-
avformat_write_header:
写文件头(对于某些没有文件头的封装格式,不需要此函数。比如说 MPEG2TS)
-
avcodec_encode_video2:
编码一帧视频。即将 AVFrame(存储 YUV 像素数据)编码为 AVPacket(存储 H.264 等格式的码流数据)
-
av_write_frame:
将编码后的视频码流写入文件。
-
flush_encoder:
输入的像素数据读取完成后调用此函数。用于输出编码器中剩余的 AVPacket。
-
av_write_trailer:
写文件尾(对于某些没有文件头的封装格式,不需要此函数。比如说 MPEG2TS)。
-
释放资源
记录下主要模块
AVPacket: 存储压缩数据,视频对应的H264数据流、音频对应的AAC/MP3数据流
AVFrame:存储原始数据,视频对应的RGB/YUV像素数据,音频对应的PCM数据
AVStream包含AVCodecContext,描述编码格式codec_type,根据格式打开编码器解码器进行AVPacket和AVFrame之间解码和编码
参考链接:
《音视频开发进阶指南》
https://blog.csdn.net/leixiaohua1020/article/details/14214577
https://blog.csdn.net/zhaodebbs/article/details/65628801
https://www.jianshu.com/p/ceaa286d8aff