ffmpeg anull 是个啥?

1. ffmpeg anull 是个啥?
----------------------------------------
author: hjjdebug
date:   2023年 07月 13日 星期四 17:59:47 CST
----------------------------------------

当然是ffmpeg audio filter了,
$ ffmpeg -h filter=anull
给出了如下信息:
Filter anull
  Pass the source unchanged to the output.
    Inputs:
       #0: default (audio)
    Outputs:
       #0: default (audio)
这些信息是怎么来的? 它实际上打印了anull 对象定义的一些信息.
anull 对象是一个全局对象,它的地址是通过avfilter_get_by_name()找到的.
其它的引脚等,都是找的定义的变量或函数.
因为它简单,所以才好分析.

2. 打开ffmpeg4.4/libavfilter/af_anull.c
这里就是其真身了, 非常简单.

static const AVFilterPad avfilter_af_anull_inputs[] = {
    {
        .name = "default",
        .type = AVMEDIA_TYPE_AUDIO,
    },
    { NULL }
};

static const AVFilterPad avfilter_af_anull_outputs[] = {
    {
        .name = "default",
        .type = AVMEDIA_TYPE_AUDIO,
    },
    { NULL }
};

AVFilter ff_af_anull = {
    .name          = "anull",
    .description   = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
    .inputs        = avfilter_af_anull_inputs,
    .outputs       = avfilter_af_anull_outputs,
};

3. 关键是它是如何工作的?
3.1: 先分析一下 ffmpeg -h filter=anull 的执行过程.
因为命令行里有-h 选项,所以执行了 show_help()函数
由于参数是filter=anull, 从=号处分割,前为"filter", 后为"anull"
所以调用: show_help_filter("anull")
首先获取filter , 过程是枚举,这里忽略.拿到了AVFilter 对象的指针ff_af_anull, 在文件中定义的全局对象
    const AVFilter *f = avfilter_get_by_name(name);

关键成员如下:
$9 = {
  name = 0x7ffff65e9e38 "anull",
  description = 0x7ffff65e9e40 "Pass the source unchanged to the output.",
  inputs = 0x7ffff6673ee0 ,
  outputs = 0x7ffff6673f60 ,
  priv_class = 0x0,
  flags = 0,
    ...
}
首先打印filter 名字  printf("Filter %s\n", f->name);   //这就是 打印输出 "Filter anull" 的来历
然后打印filter 描述  printf("  %s\n", f->description); //这就是 打印输出 "Pass the source unchanged to the output."的来历
然后打印输入:   printf("    Inputs:\n");
然后是每一个引脚的序号,名称,类型
  int count = avfilter_pad_count(f->inputs);
    for (i = 0; i < count; i++) {
        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
               media_type_string(avfilter_pad_get_type(f->inputs, i)));
    }

同理, 打印输出引脚信息:
    printf("    Outputs:\n");
    count = avfilter_pad_count(f->outputs);
    for (i = 0; i < count; i++) {
        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
               media_type_string(avfilter_pad_get_type(f->outputs, i)));
    }
 
我们挖地三尺,继续看看下一层.
3.1.1:    count = avfilter_pad_count(f->inputs);

int avfilter_pad_count(const AVFilterPad *pads)
{
    int count;
    for (count = 0; pads->name; count++)
        pads++;
    return count;
}
我们看到,代码里只定义了一个输入脚,所以count 返回1, 同理输出也一样.

3.1.2: avfilter_pad_get_name(f->inputs,i)
#define media_type_string av_get_media_type_string
const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
{
    return pads[pad_idx].name;  //给了pads 指针,又给了idx,当然可以返回name, 这个指针对anull而言必然是文件中定义的地址.
}

enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
{
    return pads[pad_idx].type;
}

const char *av_get_media_type_string(enum AVMediaType media_type)
{
    switch (media_type) {
    case AVMEDIA_TYPE_VIDEO:      return "video";
    case AVMEDIA_TYPE_AUDIO:      return "audio";
    case AVMEDIA_TYPE_DATA:       return "data";
    case AVMEDIA_TYPE_SUBTITLE:   return "subtitle";
    case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
    default:                      return NULL;
    }
}
至此对 ffmpeg -h filter=anull 分析完毕!

3.2 anull filter 是如何工作的?
那需要分析一下如下命令是如何工作的.
ffmpeg -y -i /opt/test/test.ts  -af anull  1.ts

你可能感兴趣的:(ffmpeg,ffmpeg,anull)