0%

接着上一篇《FFmpeg API(上)》中的示例代码,其中代码很多方法调用并没有详细注释,现在特意注释一下,顺便对着这张图熟悉熟悉FFmpeg处理音视频的基本流程。需要理解的几个重要的结构体 AVFormatContext 、AVCodecContext 、AVPacket 与 AVFrame,这同样也是上篇文章中的示例程序里用的特别多的几个结构体。

FFmpeg主要模块

上面的示例程序基本上演示了 FFmpeg 的一些常用 API,现在就对这些函数进行一个大致解读。

libavformat模块

AVFormatContext 是API层直接接触到的结构体,它会进行格式的封装与解封装,它的数据部分由底层提供,底层使用了 AVIOContext,这个 AVIOContext 实际上就是为普通的I/O增加了一层Buffer缓冲区,再往底层就是URLContext,也就是到达了协议层,协议层的具体实现有很多,包括rtmp、http、hls、file等,这就是libavformat的内部封装了。

libavcodec模块

对于开发者来说,这一层我们能接触到的最顶层的结构体就是 AVCodecContext,该结构体包含的就是与实际的编解码有关的部分。首先,AVCodecContext 是包含在一个 AVStream里面的,即描述了这路流的编码格式是什么,其中存放了具体的编码格式信息,根据Codec的信息可以打开编码器或者解码器,然后利用该编码器或者解码器进行 AVPacket 与 AVFrame 之间的转换(实际上就是解码或者编码的过程),这是 FFmpeg 中最重要的一部分。

函数功能

主要是介绍从文件/文件夹操作之后的一些函数。

av_register_all

在编译FFmpeg的时候,其中开启或者关闭了很多选项,生成 config.mk 与 config.h。config.mk实际上就是makefile文件需要包含进去的子模块,从而编译出正确的库;而config.h是作用在运行阶段,这一阶段将确定需要注册哪些容器以及编解码格式到FFmpeg框架中。所以该函数的内部实现会先调用 avcodec_register_all 来注册所有config.h 里面开放的编解码器,然后会注册所有的Muxer和Demuxer(也就是封装格式),最后注册所有的Protocol(即协议层的东西)。

avformat_open_input

函数 avformat_open_input 会根据所提供的文件路径判断文件的格式,其实就是通过这一步来决定使用的到底是哪一个 Demuxer。举例来说,如果是 flv,那么 Demuxer 就会使用对应的 ff_flv_demuxer,所以对应的关键生命周期的方法 read_header、read_packet、read_seek、read_close 都会使用该 flv的 Demuxer 中函数指针指定的函数。read_header 函数会将 AVStream 结构体构造好,以便后续的步骤继续使用 AVStream 作为输入参数。

FFmpeg 的功能非常强大,FFmpeg 不但有丰富的命令行工具来帮助我们处理音视频数据,而且 FFmpeg 提供了非常易用的 API,通过这些 API 就可以把 FFmpeg 集成到我们自己的程序中,以写代码的方式调用这些 API 来完成对媒体文件的操作。 另外在使用这些 API 的同时可以参考下面的图,该图展示了 FFmpeg 处理流数据基本流程,一定要想搞楚每一步操作在干什么,目的是什么。

最近收拾东西时居然发现了之前买的STM32单片机(普中STM32-F1),之前差点挂闲鱼卖了,很好奇是什么勇气让我直接买了STM32的板子?哈哈哈,买回来直接吃灰,连光盘都在。现在闲暇之余准备系统地学习一下单片机子,没准还能造些有意思的小玩意,那还是从89C51开始吧,哈哈。

FFmpeg是全世界的音视频开发工程师都应该掌握的工具,FFmpeg是一套可以用来记录、处理数字音频、视频并将其转换为流的开源框架,提供了录制、转换以及流化音视频的完整解决方案。本篇文章主要是FFmpeg的源码本地编译(Mac与CentOS)、交叉编译(Android平台)和命令行工具的使用。

LAME是目前非常优秀的一种MP3编码引擎,在业界转码成MP3格式的音频文件时,最常用的编码器就是LAME库。用LAME的源码通过交叉编译就能得到SO库(这一部分在交叉编译那篇文章已经有完整的过程了,此处不再赘述),现在只需要把SO库集成到我们自己的项目中即可,需要做的就是编写好接口,上层调用即可。

回顾平时的 C/C++ 程序开发,直接 gcc 编译出可执行文件,这就非常普通的编译过程,也称为本机编译。那么什么是交叉编译呢?交叉编译本质就是在一个平台(如PC、Mac)上生成另外一个平台 (Android、iOS 或者其他嵌入式设备)的可执行代码。本篇将以编译 LAME 这个 Mp3 编码库为例,编译出 Android 平台的可执行代码。

在Android平台上开发音视频相关的项目,必定会涉及到NDK(Native Develop Kit)开发,Android提供了ndk-bundle一系列NDK工具集。在早期Android的NDK开发会涉及到编写Android.mk文件,也就是Android专用的MakeFile,现在已经不推荐这种方式了,所以还是拥抱CMake吧(虽然CMake目前也不是最好的,但是相比Android.md确实已经方便了很多,另外CMake也可以用来构建其他的C/C++项目)。所以在此记录一下如何使用CMake快速搭建一个Android NDK项目。

CMake是一个跨平台的编译构建工具,可以用简单的语句来描述所有平台的编译过程。他能够输出各种各样的MakeFile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。

CMake的学习资料较少,只能通过github的各种例子进行学习。不过仍然建议在学习之前看一下《CMake实践》这本中文书,本CMake系列是依据github上的cmake-examples进行翻译总结。 英文github地址