《FFMPEG使用、源码框架、架构解析》

《FFMPEG使用、源码框架、架构解析》


Fabrice Bellard真是个人才!软件代码结构又简单又实用,QEMU也是他写的。
如果FFMPEG、QEMU、Linux kernel中的架构都学会了,可以当一个合格的架构师了(里面的细节没有那么多时间和精力学,但学习到里面的思想是可以的)。

作者 日期
将狼才鲸 2021-08-14

CSDN阅读完整版
b站其它视频才鲸嵌入式
Gitee源码下载地址才鲸/音视频编解码

一、使用方法一(直接使用软件)

1.1 ffplay使用

  • 功能
  1. 播放文件
  2. 打印ffplay软件的各种信息
  3. 播放控制
    设置宽高、静音、禁用音频、跳转、播放固定时间、设置窗口标题、循环播放、显示音频波形、显示音频频带、切换模式、指定输入文件、指定解码器、匹配流、指定解复用格式、指定流过滤器、指定协议、指定输入输出设备、指定像素格式、指定采样格式、指定频道布局、自动监测输出设备、设置日志级别、日志另存、设置CPU类型、libavformat/libavdevice/libavcodec库直接提供的AVOptions、设置帧大小、禁用字幕、设置无边框、窗口置顶、设置音量、设置任意键退出、自动旋转、自动丢帧、缓存大小
  4. 播放时支持的快捷键
    退出、全屏、暂停、切换显示模式、单步跳到下一帧、快进快退10s、快进快退1min、跳转到前章后章、跳转到鼠标点击位置(以百分比算)
  • 资料

    FFplay使用指南
    ffplay Documentation

1.2 ffmpeg使用

  • 功能
  1. 转换(转码、压缩、合并、拼接、裁剪、播放速度、分辨率、宽高、去掉音频、去掉视频……)
  2. 录制(录像、添加字幕、截图……)
  3. 流化(网络推送……)
  4. 过滤器(旋转、翻转、填充、裁剪、缩放、覆盖、模糊、锐化、Logo、文本、图片、马赛克、颤抖、色彩平衡、彩色黑白转换……)
  5. 图片处理(JPEG、GIF、视频转图片、图片转视频、裁剪、填充、翻转、旋转、覆盖、缩放……)
  6. 打印ffmpeg软件的各种信息:
    显示帮助、显示支持的输入输出格式、编解码、协议
  7. 操作参数:
    指定格式、指定输入输出文件名、是否覆盖输出文件、指定持续时间、指定开始时间点、设置标题/作者/版权/评论、音视频质量、时间偏移,比特率、帧数、宽高比、像素补齐、码率误差、缓冲区大小、指定编解码格式、流直接拷贝、处理遍数、图像组大小、视频量化标度、编码的初始复杂度、qp因子偏差、dct算法、idct算法、宏块决策、运动矢量、数据划分、与标准的严格性、高级帧内编码、无限运动矢量、是否交织编码、压缩帧psnr、标准比特率、最大Q值差距,音频码率、采样率、通道数、字幕codec、禁止字幕、多输出源、一个输入映射一个输出、视频同步方法、音频同步方法、解封装解码延时、过滤图、
  • 资料

    FFMPEG使用参数详解
    ffmpeg用法大全
    ffmpeg 常用命令汇总
    FFmpeg常用命令合集
    FFMPEG命令入门到提高,一篇文章就够了
    ffmpeg Documentation

1.3 ffprobe使用

  • 功能
  1. 打印音视频文件信息
    封装格式、编码格式、流数量、码率、帧信息、版本信息、以JSON输出、以XML输出、以INI输出,指定输入文件格式、指定解码器、指定解复用器、指定过滤器、指定协议、指定像素格式、指定CPU、显示有效载荷、每个数据包、每个帧、章节、流、时间码
  • 资料:
    FFprobe使用指南
    ffprobe-命令行详解
    ffprobe Documentation
  • 其中是基于libavXXX库来实现的

二、使用方法二(使用库)

2.1 可以使用的库

libavutil libswscale libswresample libavcodec libavformat libavdevice libavfilter

2.2 API调用示例:

  • 打开音视频文件、打印音视频信息
    avio_reading.c
  • 解码音频、输出PCM文件
    decode_audio.c
  • 解码视频、每帧保存一张PGM图片
    decode_video.c
  • 解封装、解码、输出YUV视频流和PCM音频流
    demuxing_decoding.c
  • 声音编码、保存为MP2文件
    encode_audio.c
  • 视频编码、保存为你指定格式的文件
    encode_video.c
  • 计算hash校验值
    ffhash.c
  • 音频过滤器、生成一个正弦波音频、进行采样格式/采样率/音量过滤后输出
    filter_audio.c
  • 视频过滤器、变换宽高旋转后输出
    filtering_video.c
  • 多播组播,输入一个文件,多个客户端可以连接并接收相同的文件
    http_multiclient.c
  • 硬件解码
    hw_decode.c
  • 使用元数据(键值对、字典)功能
    metadata.c
  • 复用(封装)为MP4等容器
    muxing.c
  • 使用Intel GPU视频surfaces中的输出帧进行QSV加速的H.264解码
    qsvdec.c
  • 转复用(转封装)从MP4等容器中提取视频流和音频流封装成别的格式
    remuxing.c
  • 音频重采样
    resampling_audio.c
  • 视频缩放转换
    scaling_video.c
  • 将MP4中音频转码为AAC
    transcode_aac.c
  • 转码
    transcoding.c
  • Intel VAAPI加速规范编码,YUV到H264
    vaapi_encode.c
  • Intel VAAPI加速规范转码
    vaapi_transcode.c
  • 通过麦克风录音
    ffmpeg实现录屏+录音
  • 通过摄像头录像
    最简单的基于FFmpeg的AVDevice例子(读取摄像头)
  • 录屏
    最简单的基于FFmpeg的AVDevice例子(屏幕录制)

2.2.1 libavdevice API详解

设备输入输出
16个API,4个结构体,2个枚举

  • 整体:
    libavdevice说明

  • 结构体:
    AVDeviceRect: 图像窗口的起始xy,窗口宽高大小
    AVDeviceCapabilitiesQuery: 一个封装的类可继承,包含了封装类,指定编解码、音频采样深度、音频采样率、音频通道数、图像位宽、窗口宽高、帧宽高、帧率
    AVDeviceInfo: 设备名字符串,设备描述字符串
    AVDeviceInfoList: 设备名、设备总数、默认设备

  • API:
    avdevice_version 获取版本号
    avdevice_configuration 获取库编译时的配置
    avdevice_license 获取许可证
    avdevice_register_all 注册所有输入输出设备
    av_input_audio_device_next 迭代获取一项音频输入设备
    av_input_video_device_next 迭代获取一项视频输入设备
    av_output_audio_device_next 迭代获取一项音频输出设备
    av_output_video_device_next 迭代获取一项视频输出设备
    avdevice_app_to_dev_control_message 从应用程序向设备发送控制消息
    avdevice_dev_to_app_control_message 从设备向应用发送控制消息
    avdevice_capabilities_create 获取设备名对应的可用的设备参数信息(不同设备私有)
    avdevice_capabilities_free 上一条API使用后进行释放用
    avdevice_list_devices 获取可用的设备名和参数
    avdevice_free_list_devices 和上一条配套使用
    avdevice_list_input_sources 获取可用的输入设备名和参数
    avdevice_list_output_sinks 获取可用的输出设备

2.2.2 libavformat API详解

封装与解封装(mp4等容器解析)
基础类函数: 15个API
解封装(解复用):19个API,1个结构体
封装(复用):11个API,1个结构体
工具类函数:24个API,

  • 整体:
    libavformat

  • 结构体:
    AVOutputFormat: 一个类,容器名称、容器详细名称、音频编解码器、视频编解码器、字幕编解码器、写音视频流的头(方法/函数接口)、写包、写尾、容器是否允许当前流的编码格式、获取输出时间戳、发送控制消息到设备、写未解码帧、获取设备列表、初始化、检查比特流

  • API:
    avformat_version 获取libavformat库版本号
    avformat_configuration 获取库编译时的配置
    avformat_license 获取库许可证
    avformat_network_init 初始化网络库
    avformat_network_deinit 与上一条配合使用
    av_muxer_iterate 迭代所有封装器
    av_demuxer_iterate 迭代所有解封装器
    avformat_alloc_context 分配AVFormatContext
    avformat_free_context 与上一条配合使用
    avformat_get_class 调用父类元素时使用
    avformat_new_stream 添加一个流到多媒体文件(如添加h264、aac等)
    av_stream_add_side_data 将现有数据封装流side信息
    av_stream_new_side_data 与上一条配合使用
    av_stream_get_side_data 获取流side信息
    av_new_program (文档里没说)

    av_find_input_format 找到特定的解封装器
    av_probe_input_format 猜测文件封装格式(如MP4)
    av_probe_input_format2 同上,参数不一样(同一方法的重载)
    av_probe_input_format3 同上
    av_probe_input_buffer 使用文件的一部分内容猜测封装格式
    av_probe_input_buffer2 同上,参数不一样
    avformat_open_input 打开流,读头信息
    av_demuxer_open 打开解封装器
    avformat_find_stream_info 读文件多媒体包以获取流信息
    av_find_program_from_stream 找到用以处理这个流的程序
    av_program_add_stream_index 加上流的序号
    av_find_best_stream 找到文件中最好的流
    av_read_frame 递归的读流中的一帧
    av_seek_frame 按时间戳跳到关键帧
    avformat_seek_file 跳到指定时间
    avformat_flush 丢弃所有内部缓存数据
    av_read_play 开始播放一个网络流
    av_read_pause 暂停网络流
    avformat_close_input 关闭文件

    avformat_write_header 写流的头信息到输出文件
    avformat_init_output 初始化解码器但是不写流的头信息
    av_write_frame 写一帧到输出文件
    av_interleaved_write_frame 确保正确的交织将帧写到输出文件
    av_write_uncoded_frame 写未解码的帧
    av_interleaved_write_uncoded_frame 以交织写未解码的帧
    av_write_uncoded_frame_query 测试封装器是否支持未解码的帧
    av_write_trailer 写流的尾信息并释放资源
    av_guess_format 使用参数猜测输出文件封装信息(如.mp4 .m4v等)
    av_guess_codec 通过封装器和文件名猜测解码器
    av_get_output_timestamp 获取时间信息

    av_hex_dump 调试打印文件十六进制信息
    av_hex_dump_log 调试打印文件十六进制信息到日志文件
    av_pkt_dump2 发送调试包到文件流
    av_pkt_dump_log2 发送调试包到日志文件
    av_codec_get_id 获取给定编解码器的id
    av_codec_get_tag 获取编解码器标志
    av_codec_get_tag2 同上,参数不同
    av_find_default_stream_index 找到默认流索引
    av_index_search_timestamp 按时间戳找索引
    av_add_index_entry 加索引到已排序列表
    av_url_split 分割网址
    av_dump_format 打印音视频流的细节参数
    av_get_frame_filename 获取文件名
    av_get_frame_filename2 同上,参数不同
    av_filename_number_test 检查文件名是否是一组带序列名字的其中一个
    av_sdp_create 为RTP网络推流生成SDP
    av_match_ext 判断文件名的扩展名(后缀)
    avformat_query_codec 判断容器是否支持当前流的编码类型
    av_guess_sample_aspect_ratio 猜测视频流的宽高比
    av_guess_frame_rate 猜测帧率
    avformat_match_stream_specifier 检查流的规范
    avformat_queue_attached_pictures 附加图片
    avformat_transfer_internal_stream_timing_info 从一个流转移时间信息到另一个流
    av_stream_get_codec_timebase 获取流的解码时间戳

2.2.3 libavcodec API详解

编解码(h264 aac等流)

  • 整体:
    libavcodec

  • API:
    基础类: 35个API,11个结构体
    详见Core functions/structures.
    基础类-未解码包:29个API,2个结构体
    详见AVPacket
    基础类-图片:8个API,1个结构体
    详见AVPicture
    解码:15个API
    详见Decoding
    解码-帧:7个API,2个结构体
    详见Frame parsing
    编码:5个API
    详见Encoding
    工具类:50个API,3个结构体
    详见Utility functions
    工具栏-像素格式:7个API
    详见Pixel formats
    工具类-快速傅里叶变换
    详见FFT functions

2.2.4 libavfilter API详解

视频滤镜

  • 整体:
    libavfilter

  • API:
    滤镜: 34个API,5个结构体
    详见libavfilter
    滤镜-缓存:6个API,2个结构体
    详见Buffer sink API
    滤镜-缓存-访问:11个API
    详见Buffer sink accessors

2.2.5 libswscale API详解

视频缩放

  • API:
    缩放:31个API,2个结构体
    详见libavfilter

2.2.6 libswresample API详解

音频重采样(声音倍速)

  • API:
    重采样: 21个API
    详见libswresample

2.2.7 libpostproc API详解

后期效果处理 网上搜过后我还是不知道这个库干什么用的

  • API:
    后期效果处理: 8个API
    详见libpostproc

2.2.8 libavutil API详解

工具模块 (这一块是重点,有很多代码结构和思想可供借鉴)

  • 整体:
    libavutil

  • API:
    加解密和校验: 8个API
    包含的模块有:AES Base64 Blowfish CAMELLIA CAST5 DES Hash HMAC LZO RC4 TEA TWOFISH XTEA
    详见Crypto and Hashing
    数学运算:12个API
    详见Mathematics
    数学运算-用整数实现小数(时间基):13个API,1个结构体
    详见AVRational
    字符串处理(功能和string.h类似):28个API
    详见String Manipulation
    内存管理-堆管理:19个API
    详见Heap Management
    内存管理-动态数组:3个API
    详见Dynamic Array
    内存管理-杂项功能(设置可分配大小、检查溢出):2个API
    详见Miscellaneous Functions
    数据结构-有引用计数的数据缓存区:11个API,1个结构体
    详见AVBuffer
    数据结构-有锁的线程安全的有引用计数的数据缓存区:4个API
    详见AVBufferPool
    数据结构-有引用计数的已解码帧:43个API,2个结构体
    详见AVFrame
    数据结构-操作符重载(C实现面向对象):23个API,3个结构体
    详见AVOptions
    数据结构-操作符重载-猜测数据类型:6个API
    详见Evaluating option strings
    数据结构-操作符重载-赋值:11个API
    详见Option setting functions
    数据结构-操作符重载-取值:10个API
    详见Option getting functions
    数据结构-键值对(字典、元数据):8个API,1个结构体
    详见AVDictionary
    数据结构-树状结构:5个API
    详见AVTree
    视频相关-显示坐标系矩阵变换:3个API
    详见Display transformation matrix functions
    视频相关-球面映射(可用来播放360°视频、VR视频、3D等):4个API,1个结构体
    详见Spherical video mapping
    视频相关-3D处理(3D、VR):4个API,1个结构体
    详见Stereo3D types and functions
    音频相关-先进先出缓存:11个API
    详见Audio FIFO Buffer
    音频相关-多声道:11个API
    详见Audio channel layouts
    音频相关-混音:1个API,1个结构体
    详见Audio downmix metadata
    音频相关-采样格式:9个API
    详见Audio sample formats
    音频相关-采样调制:5个API
    详见Samples manipulation
    错误处理:2个API
    详见Error Codes
    日志记录:12个API
    详见Logging Facility
    其它(获取字符串、判断指针空、计算长度、打开UTF-8文件、获取时间基、按4字节填充字符串):6个API
    详见Other
    其它-一些宏和一些const字符串
    其它-图片相关:16个API
    详见Image related

三、使用方法三(修改、增删源码重新编译生成库)

如:
1、将.m4v的后缀文件解析由默认的苹果视频文件格式改为mpeg4的流
2、按只选中编译自己支持的特定容器封装解封装、音视频编解码,输出最小的libavXXX的动态库文件

四、使用方法四(学习、拷贝、修改自己需要的代码块在专用硬件上编译,实现自己需要的某几项音视频相关的功能)

4.1 AVClass(C实现面向对象,可继承)

资料:
FFmpeg源代码简单分析:结构体成员管理系统-AVClass

4.2 AVOption(C实现操作符重载)

资料:
FFmpeg源代码简单分析:结构体成员管理系统-AVOption

4.3 日志

4.4 字典、键值对、元数据

Public Metadata API

4.5 文件读写(带缓存)

4.6 MP4(容器)封装、解封装

4.7 MKV(容器)封装、解封装

4.8 音视频同步播放

4.9 MP4同步录制

你可能感兴趣的:(5,杂项:音视频,GUI等,音视频,linux,stm32,c语言)