FFmpeg源码世界:命令篇

前言

最近在做一些音视频领域的工作,这个领域基本绕不开 FFmpeg ,因此想对其源码进行一些研究,站着这个巨人的肩膀上,学习一下其设计思想以及实现思路,FFmpeg 很多人最开始接触的应该都是它的命令和 ffplay ,这篇我们就先分析下 ffmpeg 命令 的实现。

从问题出发

  • FFmpeg的命令结构是什么样的
  • 怎么实现任意功能、配置的随意组装的
  • 倒放这种非线性的情况是怎么处理的
  • 当不需要转码类似只需要转封装的话是如何处理的

命令结构

ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

流程推测

  1. 应该要有一个数据层,按照输入参数进行数据解析
  2. 将解码、转码、功能处理、编码四个模块抽象分开
  3. 按第一个环节数据解析的结构组装上述四个模块,形成一条或多条责任链的效果
  4. 开始处理

过程中应该有很多分支判断、参数设置之类的情况,在这里都不考虑,我们先只分析主链路。

主流程

首先 ffmpeg 命令的入口在于 fftools/ffmpeg.c 的 main 函数上,先从这个函数来看下整体的流程,代码用的是 ffmpeg 4.4 的版本,同时会省略一些无关紧要的内容:

int main(int argc, char **argv)
{
    /* 一些前置的初始化动作 */
        ...

    /* 数据解析函数,不过在这个函数里面还会去开启输入/输出文件流等处理 */
    ret = ffmpeg_parse_options(argc, argv);

    /* 一些数据判断、开启基准测试之类的处理 */
        ... 

    /* 开始做实际的文件转换,即按命令开始处理了 */  
    if (transcode() < 0)
        ...

    /* 结束了,统计耗时等等 */
    ...
}

从上述代码可以看到核心的环节就是两部分:数据解析 + 文件转换,接下来我们将针对这两部分再深入进去看看。

接下去我们分析过程中使用的命令如下:

ffmpeg -i douyin_700x1240.mp4 -vf reverse -af areverse reversed.mp4

上述命令是将一个 douyin_700x1240.mp4 这个视频中的视频流于音频流同时倒放,生成 reversed.mp4

数据解析

在分析 ffmpeg_parse_options 函数之前,我们先介绍下 FFmpeg 命令中参数配置相关的几个主要的结构体:

OptionParseContext

typedef struct OptionParseContext {
    OptionGroup global_opts; // 全局配置参数集

    OptionGroupList *groups; // 输出/输入配置参数集
    int           nb_groups; // groups的长度

    /* parsing state */
    OptionGroup cur_group; // 下面讲解到 add_opt 的时候会提到
} OptionParseContext;

该对象用来存储被解析后的数据,全局参数,输入输出参数等。

OptionGroupList

/**
 * A list of option groups that all have the same group type
 * (e.g. input files or output files)
 */
typedef struct OptionGroupList {
    const OptionGroupDef *group_def;

    OptionGroup *groups;
    int       nb_groups;
} OptionGroupList;

上面的注释已经解释得比较清楚了。

OptionGroup

typedef struct OptionGroup {
    const OptionGroupDef *group_def;
    const char *arg;

    Option *opts;
    int  nb_opts;

    AVDictionary *codec_opts;
    AVDictionary *format_opts;
    AVDictionary *resample_opts;
    AVDictionary *sws_dict;
    AVDictionary *swr_opts;
} OptionGroup;

这里就是各类参数的存储地了,再往下就是单个配置参数的存储地 Option 了。

Option

/**
 * An option extracted from the commandline.
 * Cannot use AVDictionary because of options like -map which can be
 * used multiple times.
 */
typedef struct Option {
    const OptionDef  *opt;
    const char       *key;
    const char       *val;
} Option;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值