Ffmpeg 1.0 Filter format流程分析

本文详细分析了Ffmpeg 1.0中filter format的流程,涉及query_formats函数在avfiltergraph.c中的实现,以及如何通过filter_query_formats和buffer.src.c中的query_formats函数进行格式查询和转换。文章通过代码示例解释了如何处理不同filter之间的格式合并和转换,特别是在视频和音频格式不匹配时自动插入转换过滤器的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

201410 22

Ffmpeg1.0 Filter format流程分析

         Ffmpeg –y – i vga.3gp –vcodec libx264 –an –strict -2 merge.3gp

Filter为: buffer->null->format->ffbuffersink

 

 

第三行的 query_formats位于avfilter\avfiltergraph.c文件里,主要代码如下:

static intquery_formats(AVFilterGraph *graph, AVClass *log_ctx)

{

         AVFilterFormats* a,*b;

    int i, j,ret;

    charfilt_args[128];

    AVFilterFormats *formats;

    AVFilterChannelLayouts *chlayouts;

    AVFilterFormats *samplerates;

    intscaler_count = 0, resampler_count = 0;

 

//下面这个奇怪的循环是一个临时解决方案,目的是让buffer filter(souce) 的query_formats函数先被调用。Filter链: buffer->null->format->ffbuffersink,但是在内存里却是:graph->filters[0]=null, graph->filters[1]=buffer,graph->filters[2]= ffbuffersink, graph->filters[3]= format.

  for (j = 0; j< 2; j++) {

    /* ask all thesub-filters for their supported media formats */

    for (i = 0;i < graph->filter_count; i++) {

        /* Callquery_formats on sources first.

           This is a temporary workaround foramerge,

           until format renegociation isimplemented. */

        if(!graph->filters[i]->nb_inputs == j)

            continue;

        if(graph->filters[i]->filter->query_formats)

            ret =filter_query_formats(graph->filters[i]); //会调用avfiltergraph.c文件的filter_query_formats函数

        else

            ret =ff_default_query_formats(graph->filters[i]);//会调用ff_set_common_formats(ctx, ff_all_formats(type)),将所有formt都设置到in_formats或者out_formats,如果有的话

        if (ret< 0)

            returnret;

    }

    }

 

    /* go through andmerge as many format lists as possible */

    for (i = 0;i < graph->filter_count; i++) {

        AVFilterContext *filter =graph->filters[i];

 

        for (j= 0; j < filter->nb_inputs; j++) {

            AVFilterLink *link = filter->inputs[j];

            intconvert_needed = 0;

 

            if(!link)

                continue;

 

            if(link->in_formats != link->out_formats &&

               !ff_merge_formats(link->in_formats,

                                       link->out_formats)) //合并filter,见下面具体函数

                convert_needed = 1;

            if(link->type == AVMEDIA_TYPE_AUDIO) {

                if(link->in_channel_layouts != link->out_channel_layouts &&

                   !ff_merge_channel_layouts(link->in_channel_layouts,

                                             link->out_channel_layouts))

                    convert_needed = 1;

                if(link->in_samplerates != link->out_samplerates &&

                   !ff_merge_samplerates(link->in_samplerates,

                                         link->out_samplerates))

                    convert_needed = 1;

            }

 

            if(convert_needed) {//格式需要转换,插入新的filter

                AVFilterContext *convert;

                AVFilter *filter;

                AVFilterLink *inlink, *outlink;

                charscale_args[256];

                charinst_name[30];

 

                /*couldn't merge format lists. auto-insert conversion filter */

                switch(link->type) {

                caseAVMEDIA_TYPE_VIDEO:

                    if(!(filter = avfilter_get_by_name("scale"))){

                        av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "

                               "not present, cannot convert pixel formats.\n");

                        return AVERROR(EINVAL);

                    }

 

                    snprintf(inst_name, sizeof(inst_name), "auto-insertedscaler %d",

                      &n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值