音视频编解码学习: FFmpeg 的基础知识

简介

FFmpeg 是一个集录制、转换、音/视频编码解码功能为一体完整开源解决方案FFmpeg开发是基于 Linux 操作系统的,但是可以在大多数操作系统中编译和使用

FFmpeg 支持 MPEG、 DivX、MPEG4、AC3、DV、FLV 等40多种编码,AVI、MPEG、OGG、Matroska、ASF 等90多种解码

TCPMP,VLC, MPlayer 等开源播放器都用到了 FFmpeg

FFmpeg 主目录下主要有 libavcodec、libavformat和libavutil 等子目录

其中 libavcodec 用 于存放各个 encode/decode 模块,libavformat 用于存放 muxer/demuxer 模块,libavutil 用于 存放内存操作等辅助性模块

以 flash movie 的 flv 文件格式为例, muxer/demuxer 的 flvenc.c 和 flvdec.c 文件在

libavformat 目录下,encode/decode 的 mpegvideo.c 和 h263de.c 在 libavcodec 目录下

FFmpeg 编解码基础知识

FFmpeg 基本信息查询

封装格式

所谓封装格式是指音视频的组合格式,例如最常见的封装格式mp4、mp3、flv 等;简单来说,我们平时接触到的带有后缀的音视频文件都是一种封装格式不同的封装格式遵循不同的协议标准,有兴趣的可以自行扩展

编码格式

以 mp4 为例,通常应该包含有视频和音频;视频的编码格式为 YUV420P,音频的编码格式PCM;再以 YUV420 编码格式为例;我们知道通常图像的显示为 RGB(红绿蓝三原色),在视频压缩的时候会首先将代表每一帧画面的 RGB 压缩为 YUV ,再按照关键帧(I帧),过渡帧(P 帧或B 帧)进行运算和编码

解码的过程正好相反解码器会读到 I 帧,并根据 I 帧运算和解码 P 帧以及 B 帧;并最终根据视频文件预设的 FPS 还原每一帧画面的 RGB 数据,最后推送给显卡;所以通常我们说的编码过程就包括:画面采集、转码、编码再封装

FFmpeg 对编码解码器的支持

ffmpeg 支持的编解码器种类共有 280 多种, 涵盖了几乎所有常见音视频编码格式, 能解码几乎所有的音视频, 每种音视频编解码器的实现都在 libavcodec 目录下有具体的 C 语言实现

  • 注:编码器和解码器的名称不是完全匹配的,因此有些编码器没有对应相同名称的解码器,反之, 解码器也一样。即使编码和解码都支持也不一定是完全对应的,例如 h263 解码器对应有 h263p 和 h263 编码器

FFmpeg 对容器格式的支持

ffmpeg 支持对绝大多数的容器格式的读写操作,共计 190 多种, 涵盖了互联网上各 种常见媒体格式及日常生活中及专业应用中的各种媒体格式

视频解码和音频解码有什么区别?

FPS 是图像领域中的定义,是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面数FPS 太低画面会感觉闪烁不够连贯,FPS越高需要显卡性能越好

一些高速摄像机采集速度能够达到 11000帧/秒,那么在播放这类影片的时候我们是否也需要以 11000帧/秒播放呢?

当然不是,通常我们会按照 25 帧/秒或者 60 帧/秒设定图像的 FPS 值;但是由于视频存在关键帧和过渡帧的区别,关键帧保存了完整的画面而过渡帧只是保存了与前一帧画面的变化部分,需要通过关键帧计算获得

因此我们需要对每一帧都进行解码,即获取画面的 YUV 数据;同时只对我们真正需要显示的画面进行转码,即将 YUV 数据转换RGB 数据,包括计算画面的宽高等

但是音频则不然音频的播放必须和采集保持同步提高或降低音频的播放速度都会让音质发生变化,这也是变声器的原理;因此在实际开发中为了保证播放的音视频同步,我们往往会按照音频的播放速度来控制视频的解码转码速度

FFmpeg 结构图


(高清图片文章末尾获取)

下面解释一下图中关键标记的含义

函数背景色

函数在图中以方框的形式表现出来;不同的背景色标志了该函数不同的作用:

  • 粉红色背景函数: FFmpeg 的 API 函数
  • 白色背景的函数: FFmpeg 的内部函数
  • 黄色背景的函数: URLProtocol结构体中的函数,包含处理协议(Protocol)的功能
  • 绿色背景的函数: AVInputFormat结构体中的函数,包含处理封装格式(Format)的功能
  • 蓝色背景的函数: AVCodec结构体中的函数,包含了编解码器(Codec)的功能

PS: URLProtocol,AVInputFormat,AVCodecFFmpeg 开始运行并且注册完组件之后,都会分别被连接成一个个的链表;因此实际上是有很多的 URLProtocol,AVInputFormat,AVCodec

图中画出了解码一个输入协议是**“文件”(其实就是打开一个文件;“文件”也被当做是一种广义的协议**),封装格式为 FLV视频编码格式是 H.264 的数据的函数调用关系

区域

整个架构图可以分为以下几个区域:

  • 左边区域——架构函数区域: 这些函数并不针对某一特定的视频格式
  • 右上方黄色区域——协议处理函数区域: 不同的协议(RTP,RTMP,FILE)会调用不同的协议处理函数
  • 右边中间绿色区域——封装格式处理函数区域: 不同的封装格式(MKV,FLV,MPEGTS,AVI)会调用不同的封装格式处理函数
  • 右边下方蓝色区域——编解码函数区域: 不同的编码标准(HEVC,H.264,MPEG2)会调用不同的编解码函数

箭头线

为了把调用关系表示的更明显,图中的箭头线也使用了不同的颜色:

  • 黑色箭头线: 标志了函数之间的调用关系
  • 红色的箭头线: 标志了解码的流程
  • 其他颜色的箭头线: 标志了函数之间的调用关系

其中:

调用 URLProtocol 结构体中的函数用黄色箭头线标识
调用 AVInputFormat 结构体中的函数用绿色箭头线标识
调用 AVCodec 结构体中的函数用蓝色箭头线标识

函数所在的文件

每个函数旁边标识了它所在的文件的路径

此外,还有一点需要注意的是,一些 API 函数内部也调用了另一些 API 函数;也就是说,API 函数不一定全部都调用 FFmpeg 的内部函数,他也有可能调用其他的 API 函数

例如从图中可以看出来,avformat_close_input() 调用了 avformat_free_context()avio_close()这些在内部代码中被调用的API函数也标记为粉红色

今天有关于 FFmpeg 架构的相关内容就介绍到这里了,有需要文中高清版 FFmpeg 架构图的朋友可以私信发送:“架构图” 即可 直达获取,现在还可以额外获取一份高级音视频开发学习笔记,里面包含了许多音视频开发所需的技术知识点希望这份笔记能够对你有所帮助

内容展示如下:

高级音视频开发学习笔记目录

高级音视频开发学习笔记 获取方式 :私信发送 “笔记” 即可 直达获取

FFmpeg 编译过程

  • 准备资料
  • ndk 环境配置
  • 编写脚本文件

FFmpeg 引入 AndroidStudio

  • 新建项目
  • 配置 build.gradle
  • 配置 CMakeLists.txt 文件
  • 编写测试代码(头文件一定要用 extern 包含住)

高级音视频开发学习笔记 获取方式 :私信发送 “笔记” 即可 直达获取

音视频格式封装原理

  • 视频解码基础 01 -封裝格式
  • 视频文件封装格式
  • 音视频编码方式简介
  • 视频编码方式
  • 音频编码方式
  • MP3
  • AAC
  • WMA

有需要文中高清版 FFmpeg 架构图及高级音视频开发学习笔记 的朋友可以私信发送:“架构图”“笔记” 即可 直达获取

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

最后祝各位开发者早日精通音视频开发 ,攀登上更高的高峰

猜你喜欢

转载自blog.csdn.net/m0_70748845/article/details/126855885