工具(7): ffmpeg

本文记录对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

参考资料

posted @ 2020-07-14 10:40  ffl  阅读(363)  评论(0编辑  收藏  举报