本文记录对ffmpeg这个工具的理解和掌握,随时添加。

源代码获取

获取 ffmpeg 源代码快照:
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg

多次尝试下载失败,减少了深度也一样:
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg --depth=1

放弃直接从git拉取代码,下载官网提供的快照代码:
https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2

编译

配置Makefile:
./configure

执行编译,要等挺久的,可以去干掉别的事情:
make

编译完成后,在根目录下生成了ffmpeg等可执行程序,在doc目录下生成了文档,清理下中间文件
make clean

类库结构

  • libavcodec 一组编解码实现
  • libavformat 实现流协议,容器格式和基础IO访问
  • libavutil 包含哈希、解压等辅助库
  • libavfilter 提供解码管道中使用的过滤器
  • libavdevice 提供访问、捕获、播放设备的抽象
  • libswresample 实现音频混淆和重采样
  • libswscale 实现颜色转换和缩放

可以看到,ffmpeg的代码结构组织清晰直接。

源码分析(libavcodec)

入口文件:/libavcodec/avcodec.h

ffmpeg在每个类库里面定义了一些group,每个group完成一类功能,并且可以有子grouplibavcodec的分组如下:

  • libavc libavcodec
    • lavc_encdec
    • lavc_core
  • lavc_decoding
  • lavc_encoding
  • lavc_codec
  • lavc_codec_native
  • lavc_codec_wrapers
  • lavc_codec_hwaccel
  • lavc_internal

lavc_encdec组定义了一组编解码的发送和接收API,每组API围绕一个特定的数据结构:

  • lavc_encdec ( AVCodecContext )
    • 发送 AVFrame 给编码器,并且循环调用recv方法获得 AVPacket ,一直到返回 AVERROREAGAIN
      • avcodec_send_frame
      • avcodec_receive_packet
    • 发送 AVPacket 给解码器,并且循环调用recv方法获得 AVFrame ,一直到返回 AVERROREAGAIN
      • avcodec_send_packet
      • avcodec_receive_frame

编解码内部有不同的阶段:

  • 开始阶段,codec 可能接受很多 frams/packets 输入,一直到内部缓存被填满才会返回 frame
  • 中间阶段,发送输入数据后可能返回 ENGAIN,仅当并非所有的数据都被接收时发生,例如你可以在每个迭代中发送新数据,同时在返回 ENGAIN 时接收数据
  • 结束阶段,需要刷新( flushing / draining )
    • 对于编码,发送NULL给 avcodec_send_frame,循环调用 avcodec_receive_packet 一直到 AVERROR_EOF
    • 对于解码,发送NULL给 avcodec_send_packet,循环调用 avcodec_receive_frame 一直到 AVERROR_EOF

参考资料

相关文章:

  • 2021-09-01
  • 2021-07-12
  • 2021-06-09
  • 2021-06-10
  • 2021-08-21
  • 2022-12-23
  • 2021-12-26
  • 2021-10-19
猜你喜欢
  • 2021-11-27
  • 2021-06-01
  • 2021-06-08
  • 2021-10-31
  • 2021-12-26
  • 2021-12-09
  • 2022-02-17
相关资源
相似解决方案