LCOV - code coverage report
Current view: top level - fftools - ffmpeg_filter.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 448 633 70.8 %
Date: 2018-05-20 11:54:08 Functions: 23 26 88.5 %

          Line data    Source code
       1             : /*
       2             :  * ffmpeg filter configuration
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <stdint.h>
      22             : 
      23             : #include "ffmpeg.h"
      24             : 
      25             : #include "libavfilter/avfilter.h"
      26             : #include "libavfilter/buffersink.h"
      27             : #include "libavfilter/buffersrc.h"
      28             : 
      29             : #include "libavresample/avresample.h"
      30             : 
      31             : #include "libavutil/avassert.h"
      32             : #include "libavutil/avstring.h"
      33             : #include "libavutil/bprint.h"
      34             : #include "libavutil/channel_layout.h"
      35             : #include "libavutil/display.h"
      36             : #include "libavutil/opt.h"
      37             : #include "libavutil/pixdesc.h"
      38             : #include "libavutil/pixfmt.h"
      39             : #include "libavutil/imgutils.h"
      40             : #include "libavutil/samplefmt.h"
      41             : 
      42          58 : static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[])
      43             : {
      44             :     static const enum AVPixelFormat mjpeg_formats[] =
      45             :         { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
      46             :           AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
      47             :           AV_PIX_FMT_NONE };
      48             :     static const enum AVPixelFormat ljpeg_formats[] =
      49             :         { AV_PIX_FMT_BGR24   , AV_PIX_FMT_BGRA    , AV_PIX_FMT_BGR0,
      50             :           AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
      51             :           AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
      52             :           AV_PIX_FMT_NONE};
      53             : 
      54          58 :     if (codec_id == AV_CODEC_ID_MJPEG) {
      55           0 :         return mjpeg_formats;
      56          58 :     } else if (codec_id == AV_CODEC_ID_LJPEG) {
      57           4 :         return ljpeg_formats;
      58             :     } else {
      59          54 :         return default_formats;
      60             :     }
      61             : }
      62             : 
      63        3163 : enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target)
      64             : {
      65        3163 :     if (codec && codec->pix_fmts) {
      66         251 :         const enum AVPixelFormat *p = codec->pix_fmts;
      67         251 :         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
      68             :         //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
      69         251 :         int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
      70         251 :         enum AVPixelFormat best= AV_PIX_FMT_NONE;
      71             : 
      72         251 :         if (enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
      73          39 :             p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p);
      74             :         }
      75        1309 :         for (; *p != AV_PIX_FMT_NONE; p++) {
      76        1300 :             best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
      77        1300 :             if (*p == target)
      78         242 :                 break;
      79             :         }
      80         251 :         if (*p == AV_PIX_FMT_NONE) {
      81           9 :             if (target != AV_PIX_FMT_NONE)
      82           9 :                 av_log(NULL, AV_LOG_WARNING,
      83             :                        "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
      84             :                        av_get_pix_fmt_name(target),
      85             :                        codec->name,
      86             :                        av_get_pix_fmt_name(best));
      87           9 :             return best;
      88             :         }
      89             :     }
      90        3154 :     return target;
      91             : }
      92             : 
      93           0 : void choose_sample_fmt(AVStream *st, AVCodec *codec)
      94             : {
      95           0 :     if (codec && codec->sample_fmts) {
      96           0 :         const enum AVSampleFormat *p = codec->sample_fmts;
      97           0 :         for (; *p != -1; p++) {
      98           0 :             if (*p == st->codecpar->format)
      99           0 :                 break;
     100             :         }
     101           0 :         if (*p == -1) {
     102           0 :             if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0]))
     103           0 :                 av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
     104           0 :             if(av_get_sample_fmt_name(st->codecpar->format))
     105           0 :             av_log(NULL, AV_LOG_WARNING,
     106             :                    "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
     107           0 :                    av_get_sample_fmt_name(st->codecpar->format),
     108             :                    codec->name,
     109           0 :                    av_get_sample_fmt_name(codec->sample_fmts[0]));
     110           0 :             st->codecpar->format = codec->sample_fmts[0];
     111             :         }
     112             :     }
     113           0 : }
     114             : 
     115        4444 : static char *choose_pix_fmts(OutputFilter *ofilter)
     116             : {
     117        4444 :     OutputStream *ost = ofilter->ost;
     118        4444 :     AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
     119        4444 :     if (strict_dict)
     120             :         // used by choose_pixel_fmt() and below
     121          58 :         av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
     122             : 
     123        4444 :      if (ost->keep_pix_fmt) {
     124           0 :         avfilter_graph_set_auto_convert(ofilter->graph->graph,
     125             :                                             AVFILTER_AUTO_CONVERT_NONE);
     126           0 :         if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
     127           0 :             return NULL;
     128           0 :         return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt));
     129             :     }
     130        4444 :     if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
     131        3163 :         return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt)));
     132        1281 :     } else if (ost->enc && ost->enc->pix_fmts) {
     133             :         const enum AVPixelFormat *p;
     134         286 :         AVIOContext *s = NULL;
     135             :         uint8_t *ret;
     136             :         int len;
     137             : 
     138         286 :         if (avio_open_dyn_buf(&s) < 0)
     139           0 :             exit_program(1);
     140             : 
     141         286 :         p = ost->enc->pix_fmts;
     142         286 :         if (ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
     143          19 :             p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p);
     144             :         }
     145             : 
     146        1450 :         for (; *p != AV_PIX_FMT_NONE; p++) {
     147        1164 :             const char *name = av_get_pix_fmt_name(*p);
     148        1164 :             avio_printf(s, "%s|", name);
     149             :         }
     150         286 :         len = avio_close_dyn_buf(s, &ret);
     151         286 :         ret[len - 1] = 0;
     152         286 :         return ret;
     153             :     } else
     154         995 :         return NULL;
     155             : }
     156             : 
     157             : /* Define a function for building a string containing a list of
     158             :  * allowed formats. */
     159             : #define DEF_CHOOSE_FORMAT(suffix, type, var, supported_list, none, get_name)   \
     160             : static char *choose_ ## suffix (OutputFilter *ofilter)                         \
     161             : {                                                                              \
     162             :     if (ofilter->var != none) {                                                \
     163             :         get_name(ofilter->var);                                                \
     164             :         return av_strdup(name);                                                \
     165             :     } else if (ofilter->supported_list) {                                      \
     166             :         const type *p;                                                         \
     167             :         AVIOContext *s = NULL;                                                 \
     168             :         uint8_t *ret;                                                          \
     169             :         int len;                                                               \
     170             :                                                                                \
     171             :         if (avio_open_dyn_buf(&s) < 0)                                         \
     172             :             exit_program(1);                                                           \
     173             :                                                                                \
     174             :         for (p = ofilter->supported_list; *p != none; p++) {                   \
     175             :             get_name(*p);                                                      \
     176             :             avio_printf(s, "%s|", name);                                       \
     177             :         }                                                                      \
     178             :         len = avio_close_dyn_buf(s, &ret);                                     \
     179             :         ret[len - 1] = 0;                                                      \
     180             :         return ret;                                                            \
     181             :     } else                                                                     \
     182             :         return NULL;                                                           \
     183             : }
     184             : 
     185             : //DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, AV_PIX_FMT_NONE,
     186             : //                  GET_PIX_FMT_NAME)
     187             : 
     188        1069 : DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
     189             :                   AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
     190             : 
     191        1069 : DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
     192             :                   GET_SAMPLE_RATE_NAME)
     193             : 
     194        1069 : DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
     195             :                   GET_CH_LAYOUT_NAME)
     196             : 
     197        5403 : int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
     198             : {
     199        5403 :     FilterGraph *fg = av_mallocz(sizeof(*fg));
     200             : 
     201        5403 :     if (!fg)
     202           0 :         exit_program(1);
     203        5403 :     fg->index = nb_filtergraphs;
     204             : 
     205        5403 :     GROW_ARRAY(fg->outputs, fg->nb_outputs);
     206        5403 :     if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
     207           0 :         exit_program(1);
     208        5403 :     fg->outputs[0]->ost   = ost;
     209        5403 :     fg->outputs[0]->graph = fg;
     210        5403 :     fg->outputs[0]->format = -1;
     211             : 
     212        5403 :     ost->filter = fg->outputs[0];
     213             : 
     214        5403 :     GROW_ARRAY(fg->inputs, fg->nb_inputs);
     215        5403 :     if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
     216           0 :         exit_program(1);
     217        5403 :     fg->inputs[0]->ist   = ist;
     218        5403 :     fg->inputs[0]->graph = fg;
     219        5403 :     fg->inputs[0]->format = -1;
     220             : 
     221        5403 :     fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
     222        5403 :     if (!fg->inputs[0]->frame_queue)
     223           0 :         exit_program(1);
     224             : 
     225        5403 :     GROW_ARRAY(ist->filters, ist->nb_filters);
     226        5403 :     ist->filters[ist->nb_filters - 1] = fg->inputs[0];
     227             : 
     228        5403 :     GROW_ARRAY(filtergraphs, nb_filtergraphs);
     229        5403 :     filtergraphs[nb_filtergraphs - 1] = fg;
     230             : 
     231        5403 :     return 0;
     232             : }
     233             : 
     234         129 : static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
     235             : {
     236         129 :     AVFilterContext *ctx = inout->filter_ctx;
     237         129 :     AVFilterPad *pads = in ? ctx->input_pads  : ctx->output_pads;
     238         129 :     int       nb_pads = in ? ctx->nb_inputs   : ctx->nb_outputs;
     239             :     AVIOContext *pb;
     240         129 :     uint8_t *res = NULL;
     241             : 
     242         129 :     if (avio_open_dyn_buf(&pb) < 0)
     243           0 :         exit_program(1);
     244             : 
     245         129 :     avio_printf(pb, "%s", ctx->filter->name);
     246         129 :     if (nb_pads > 1)
     247          43 :         avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));
     248         129 :     avio_w8(pb, 0);
     249         129 :     avio_close_dyn_buf(pb, &res);
     250         129 :     return res;
     251             : }
     252             : 
     253          56 : static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
     254             : {
     255          56 :     InputStream *ist = NULL;
     256          56 :     enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
     257             :     int i;
     258             : 
     259             :     // TODO: support other filter types
     260          56 :     if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
     261           0 :         av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
     262             :                "currently.\n");
     263           0 :         exit_program(1);
     264             :     }
     265             : 
     266          56 :     if (in->name) {
     267             :         AVFormatContext *s;
     268          10 :         AVStream       *st = NULL;
     269             :         char *p;
     270          10 :         int file_idx = strtol(in->name, &p, 0);
     271             : 
     272          10 :         if (file_idx < 0 || file_idx >= nb_input_files) {
     273           0 :             av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
     274             :                    file_idx, fg->graph_desc);
     275           0 :             exit_program(1);
     276             :         }
     277          10 :         s = input_files[file_idx]->ctx;
     278             : 
     279          14 :         for (i = 0; i < s->nb_streams; i++) {
     280          14 :             enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
     281          14 :             if (stream_type != type &&
     282           3 :                 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
     283             :                   type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
     284           2 :                 continue;
     285          12 :             if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) {
     286          10 :                 st = s->streams[i];
     287          10 :                 break;
     288             :             }
     289             :         }
     290          10 :         if (!st) {
     291           0 :             av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
     292             :                    "matches no streams.\n", p, fg->graph_desc);
     293           0 :             exit_program(1);
     294             :         }
     295          10 :         ist = input_streams[input_files[file_idx]->ist_index + st->index];
     296             :     } else {
     297             :         /* find the first unused stream of corresponding type */
     298          64 :         for (i = 0; i < nb_input_streams; i++) {
     299          64 :             ist = input_streams[i];
     300          64 :             if (ist->dec_ctx->codec_type == type && ist->discard)
     301          46 :                 break;
     302             :         }
     303          46 :         if (i == nb_input_streams) {
     304           0 :             av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
     305             :                    "unlabeled input pad %d on filter %s\n", in->pad_idx,
     306           0 :                    in->filter_ctx->name);
     307           0 :             exit_program(1);
     308             :         }
     309             :     }
     310          56 :     av_assert0(ist);
     311             : 
     312          56 :     ist->discard         = 0;
     313          56 :     ist->decoding_needed |= DECODING_FOR_FILTER;
     314          56 :     ist->st->discard = AVDISCARD_NONE;
     315             : 
     316          56 :     GROW_ARRAY(fg->inputs, fg->nb_inputs);
     317          56 :     if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
     318           0 :         exit_program(1);
     319          56 :     fg->inputs[fg->nb_inputs - 1]->ist   = ist;
     320          56 :     fg->inputs[fg->nb_inputs - 1]->graph = fg;
     321          56 :     fg->inputs[fg->nb_inputs - 1]->format = -1;
     322          56 :     fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type;
     323          56 :     fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1);
     324             : 
     325          56 :     fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
     326          56 :     if (!fg->inputs[fg->nb_inputs - 1]->frame_queue)
     327           0 :         exit_program(1);
     328             : 
     329          56 :     GROW_ARRAY(ist->filters, ist->nb_filters);
     330          56 :     ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
     331          56 : }
     332             : 
     333          71 : int init_complex_filtergraph(FilterGraph *fg)
     334             : {
     335             :     AVFilterInOut *inputs, *outputs, *cur;
     336             :     AVFilterGraph *graph;
     337          71 :     int ret = 0;
     338             : 
     339             :     /* this graph is only used for determining the kinds of inputs
     340             :      * and outputs we have, and is discarded on exit from this function */
     341          71 :     graph = avfilter_graph_alloc();
     342          71 :     if (!graph)
     343           0 :         return AVERROR(ENOMEM);
     344          71 :     graph->nb_threads = 1;
     345             : 
     346          71 :     ret = avfilter_graph_parse2(graph, fg->graph_desc, &inputs, &outputs);
     347          71 :     if (ret < 0)
     348           0 :         goto fail;
     349             : 
     350         127 :     for (cur = inputs; cur; cur = cur->next)
     351          56 :         init_input_filter(fg, cur);
     352             : 
     353         215 :     for (cur = outputs; cur;) {
     354          73 :         GROW_ARRAY(fg->outputs, fg->nb_outputs);
     355          73 :         fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]));
     356          73 :         if (!fg->outputs[fg->nb_outputs - 1])
     357           0 :             exit_program(1);
     358             : 
     359          73 :         fg->outputs[fg->nb_outputs - 1]->graph   = fg;
     360          73 :         fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
     361          73 :         fg->outputs[fg->nb_outputs - 1]->type    = avfilter_pad_get_type(cur->filter_ctx->output_pads,
     362             :                                                                          cur->pad_idx);
     363          73 :         fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0);
     364          73 :         cur = cur->next;
     365          73 :         fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
     366             :     }
     367             : 
     368          71 : fail:
     369          71 :     avfilter_inout_free(&inputs);
     370          71 :     avfilter_graph_free(&graph);
     371          71 :     return ret;
     372             : }
     373             : 
     374       11009 : static int insert_trim(int64_t start_time, int64_t duration,
     375             :                        AVFilterContext **last_filter, int *pad_idx,
     376             :                        const char *filter_name)
     377             : {
     378       11009 :     AVFilterGraph *graph = (*last_filter)->graph;
     379             :     AVFilterContext *ctx;
     380             :     const AVFilter *trim;
     381       11009 :     enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
     382       11009 :     const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
     383       11009 :     int ret = 0;
     384             : 
     385       11009 :     if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
     386       10854 :         return 0;
     387             : 
     388         155 :     trim = avfilter_get_by_name(name);
     389         155 :     if (!trim) {
     390           0 :         av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit "
     391             :                "recording time.\n", name);
     392           0 :         return AVERROR_FILTER_NOT_FOUND;
     393             :     }
     394             : 
     395         155 :     ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
     396         155 :     if (!ctx)
     397           0 :         return AVERROR(ENOMEM);
     398             : 
     399         155 :     if (duration != INT64_MAX) {
     400         143 :         ret = av_opt_set_int(ctx, "durationi", duration,
     401             :                                 AV_OPT_SEARCH_CHILDREN);
     402             :     }
     403         155 :     if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
     404          12 :         ret = av_opt_set_int(ctx, "starti", start_time,
     405             :                                 AV_OPT_SEARCH_CHILDREN);
     406             :     }
     407         155 :     if (ret < 0) {
     408           0 :         av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
     409           0 :         return ret;
     410             :     }
     411             : 
     412         155 :     ret = avfilter_init_str(ctx, NULL);
     413         155 :     if (ret < 0)
     414           0 :         return ret;
     415             : 
     416         155 :     ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
     417         155 :     if (ret < 0)
     418           0 :         return ret;
     419             : 
     420         155 :     *last_filter = ctx;
     421         155 :     *pad_idx     = 0;
     422         155 :     return 0;
     423             : }
     424             : 
     425           0 : static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
     426             :                          const char *filter_name, const char *args)
     427             : {
     428           0 :     AVFilterGraph *graph = (*last_filter)->graph;
     429             :     AVFilterContext *ctx;
     430             :     int ret;
     431             : 
     432           0 :     ret = avfilter_graph_create_filter(&ctx,
     433             :                                        avfilter_get_by_name(filter_name),
     434             :                                        filter_name, args, NULL, graph);
     435           0 :     if (ret < 0)
     436           0 :         return ret;
     437             : 
     438           0 :     ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
     439           0 :     if (ret < 0)
     440           0 :         return ret;
     441             : 
     442           0 :     *last_filter = ctx;
     443           0 :     *pad_idx     = 0;
     444           0 :     return 0;
     445             : }
     446             : 
     447        4444 : static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
     448             : {
     449             :     char *pix_fmts;
     450        4444 :     OutputStream *ost = ofilter->ost;
     451        4444 :     OutputFile    *of = output_files[ost->file_index];
     452        4444 :     AVFilterContext *last_filter = out->filter_ctx;
     453        4444 :     int pad_idx = out->pad_idx;
     454             :     int ret;
     455             :     char name[255];
     456             : 
     457        4444 :     snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
     458        4444 :     ret = avfilter_graph_create_filter(&ofilter->filter,
     459             :                                        avfilter_get_by_name("buffersink"),
     460             :                                        name, NULL, NULL, fg->graph);
     461             : 
     462        4444 :     if (ret < 0)
     463           0 :         return ret;
     464             : 
     465        4444 :     if (ofilter->width || ofilter->height) {
     466             :         char args[255];
     467             :         AVFilterContext *filter;
     468         611 :         AVDictionaryEntry *e = NULL;
     469             : 
     470         611 :         snprintf(args, sizeof(args), "%d:%d",
     471             :                  ofilter->width, ofilter->height);
     472             : 
     473        2433 :         while ((e = av_dict_get(ost->sws_dict, "", e,
     474             :                                 AV_DICT_IGNORE_SUFFIX))) {
     475        1211 :             av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
     476             :         }
     477             : 
     478         611 :         snprintf(name, sizeof(name), "scaler_out_%d_%d",
     479             :                  ost->file_index, ost->index);
     480         611 :         if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
     481             :                                                 name, args, NULL, fg->graph)) < 0)
     482           0 :             return ret;
     483         611 :         if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
     484           0 :             return ret;
     485             : 
     486         611 :         last_filter = filter;
     487         611 :         pad_idx = 0;
     488             :     }
     489             : 
     490        4444 :     if ((pix_fmts = choose_pix_fmts(ofilter))) {
     491             :         AVFilterContext *filter;
     492        3449 :         snprintf(name, sizeof(name), "format_out_%d_%d",
     493             :                  ost->file_index, ost->index);
     494        3449 :         ret = avfilter_graph_create_filter(&filter,
     495             :                                            avfilter_get_by_name("format"),
     496             :                                            "format", pix_fmts, NULL, fg->graph);
     497        3449 :         av_freep(&pix_fmts);
     498        3449 :         if (ret < 0)
     499           0 :             return ret;
     500        3449 :         if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
     501           0 :             return ret;
     502             : 
     503        3449 :         last_filter = filter;
     504        3449 :         pad_idx     = 0;
     505             :     }
     506             : 
     507             :     if (ost->frame_rate.num && 0) {
     508             :         AVFilterContext *fps;
     509             :         char args[255];
     510             : 
     511             :         snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
     512             :                  ost->frame_rate.den);
     513             :         snprintf(name, sizeof(name), "fps_out_%d_%d",
     514             :                  ost->file_index, ost->index);
     515             :         ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
     516             :                                            name, args, NULL, fg->graph);
     517             :         if (ret < 0)
     518             :             return ret;
     519             : 
     520             :         ret = avfilter_link(last_filter, pad_idx, fps, 0);
     521             :         if (ret < 0)
     522             :             return ret;
     523             :         last_filter = fps;
     524             :         pad_idx = 0;
     525             :     }
     526             : 
     527        4444 :     snprintf(name, sizeof(name), "trim_out_%d_%d",
     528             :              ost->file_index, ost->index);
     529        4444 :     ret = insert_trim(of->start_time, of->recording_time,
     530             :                       &last_filter, &pad_idx, name);
     531        4444 :     if (ret < 0)
     532           0 :         return ret;
     533             : 
     534             : 
     535        4444 :     if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
     536           0 :         return ret;
     537             : 
     538        4444 :     return 0;
     539             : }
     540             : 
     541        1069 : static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
     542             : {
     543        1069 :     OutputStream *ost = ofilter->ost;
     544        1069 :     OutputFile    *of = output_files[ost->file_index];
     545        1069 :     AVCodecContext *codec  = ost->enc_ctx;
     546        1069 :     AVFilterContext *last_filter = out->filter_ctx;
     547        1069 :     int pad_idx = out->pad_idx;
     548             :     char *sample_fmts, *sample_rates, *channel_layouts;
     549             :     char name[255];
     550             :     int ret;
     551             : 
     552        1069 :     snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
     553        1069 :     ret = avfilter_graph_create_filter(&ofilter->filter,
     554             :                                        avfilter_get_by_name("abuffersink"),
     555             :                                        name, NULL, NULL, fg->graph);
     556        1069 :     if (ret < 0)
     557           0 :         return ret;
     558        1069 :     if ((ret = av_opt_set_int(ofilter->filter, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
     559           0 :         return ret;
     560             : 
     561             : #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do {                 \
     562             :     AVFilterContext *filt_ctx;                                              \
     563             :                                                                             \
     564             :     av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi "            \
     565             :            "similarly to -af " filter_name "=%s.\n", arg);                  \
     566             :                                                                             \
     567             :     ret = avfilter_graph_create_filter(&filt_ctx,                           \
     568             :                                        avfilter_get_by_name(filter_name),   \
     569             :                                        filter_name, arg, NULL, fg->graph);  \
     570             :     if (ret < 0)                                                            \
     571             :         return ret;                                                         \
     572             :                                                                             \
     573             :     ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0);                 \
     574             :     if (ret < 0)                                                            \
     575             :         return ret;                                                         \
     576             :                                                                             \
     577             :     last_filter = filt_ctx;                                                 \
     578             :     pad_idx = 0;                                                            \
     579             : } while (0)
     580        1069 :     if (ost->audio_channels_mapped) {
     581             :         int i;
     582             :         AVBPrint pan_buf;
     583           6 :         av_bprint_init(&pan_buf, 256, 8192);
     584           6 :         av_bprintf(&pan_buf, "0x%"PRIx64,
     585             :                    av_get_default_channel_layout(ost->audio_channels_mapped));
     586          16 :         for (i = 0; i < ost->audio_channels_mapped; i++)
     587          10 :             if (ost->audio_channels_map[i] != -1)
     588           9 :                 av_bprintf(&pan_buf, "|c%d=c%d", i, ost->audio_channels_map[i]);
     589             : 
     590           6 :         AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
     591           6 :         av_bprint_finalize(&pan_buf, NULL);
     592             :     }
     593             : 
     594        1069 :     if (codec->channels && !codec->channel_layout)
     595          12 :         codec->channel_layout = av_get_default_channel_layout(codec->channels);
     596             : 
     597        1069 :     sample_fmts     = choose_sample_fmts(ofilter);
     598        1069 :     sample_rates    = choose_sample_rates(ofilter);
     599        1069 :     channel_layouts = choose_channel_layouts(ofilter);
     600        1069 :     if (sample_fmts || sample_rates || channel_layouts) {
     601             :         AVFilterContext *format;
     602             :         char args[256];
     603        1069 :         args[0] = 0;
     604             : 
     605        1069 :         if (sample_fmts)
     606        1069 :             av_strlcatf(args, sizeof(args), "sample_fmts=%s:",
     607             :                             sample_fmts);
     608        1069 :         if (sample_rates)
     609          47 :             av_strlcatf(args, sizeof(args), "sample_rates=%s:",
     610             :                             sample_rates);
     611        1069 :         if (channel_layouts)
     612          47 :             av_strlcatf(args, sizeof(args), "channel_layouts=%s:",
     613             :                             channel_layouts);
     614             : 
     615        1069 :         av_freep(&sample_fmts);
     616        1069 :         av_freep(&sample_rates);
     617        1069 :         av_freep(&channel_layouts);
     618             : 
     619        1069 :         snprintf(name, sizeof(name), "format_out_%d_%d",
     620             :                  ost->file_index, ost->index);
     621        1069 :         ret = avfilter_graph_create_filter(&format,
     622             :                                            avfilter_get_by_name("aformat"),
     623             :                                            name, args, NULL, fg->graph);
     624        1069 :         if (ret < 0)
     625           0 :             return ret;
     626             : 
     627        1069 :         ret = avfilter_link(last_filter, pad_idx, format, 0);
     628        1069 :         if (ret < 0)
     629           0 :             return ret;
     630             : 
     631        1069 :         last_filter = format;
     632        1069 :         pad_idx = 0;
     633             :     }
     634             : 
     635             :     if (audio_volume != 256 && 0) {
     636             :         char args[256];
     637             : 
     638             :         snprintf(args, sizeof(args), "%f", audio_volume / 256.);
     639             :         AUTO_INSERT_FILTER("-vol", "volume", args);
     640             :     }
     641             : 
     642        1069 :     if (ost->apad && of->shortest) {
     643             :         char args[256];
     644             :         int i;
     645             : 
     646           0 :         for (i=0; i<of->ctx->nb_streams; i++)
     647           0 :             if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
     648           0 :                 break;
     649             : 
     650           0 :         if (i<of->ctx->nb_streams) {
     651           0 :             snprintf(args, sizeof(args), "%s", ost->apad);
     652           0 :             AUTO_INSERT_FILTER("-apad", "apad", args);
     653             :         }
     654             :     }
     655             : 
     656        1069 :     snprintf(name, sizeof(name), "trim for output stream %d:%d",
     657             :              ost->file_index, ost->index);
     658        1069 :     ret = insert_trim(of->start_time, of->recording_time,
     659             :                       &last_filter, &pad_idx, name);
     660        1069 :     if (ret < 0)
     661           0 :         return ret;
     662             : 
     663        1069 :     if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
     664           0 :         return ret;
     665             : 
     666        1069 :     return 0;
     667             : }
     668             : 
     669        5513 : int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
     670             : {
     671        5513 :     if (!ofilter->ost) {
     672           0 :         av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name);
     673           0 :         exit_program(1);
     674             :     }
     675             : 
     676        5513 :     switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
     677        4444 :     case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
     678        1069 :     case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
     679           0 :     default: av_assert0(0);
     680             :     }
     681             : }
     682             : 
     683        5617 : void check_filter_outputs(void)
     684             : {
     685             :     int i;
     686       11091 :     for (i = 0; i < nb_filtergraphs; i++) {
     687             :         int n;
     688       10950 :         for (n = 0; n < filtergraphs[i]->nb_outputs; n++) {
     689        5476 :             OutputFilter *output = filtergraphs[i]->outputs[n];
     690        5476 :             if (!output->ost) {
     691           0 :                 av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", output->name);
     692           0 :                 exit_program(1);
     693             :             }
     694             :         }
     695             :     }
     696        5617 : }
     697             : 
     698           2 : static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
     699             : {
     700           2 :     AVFormatContext *avf = input_files[ist->file_index]->ctx;
     701             :     int i, w, h;
     702             : 
     703             :     /* Compute the size of the canvas for the subtitles stream.
     704             :        If the subtitles codecpar has set a size, use it. Otherwise use the
     705             :        maximum dimensions of the video streams in the same file. */
     706           2 :     w = ifilter->width;
     707           2 :     h = ifilter->height;
     708           2 :     if (!(w && h)) {
     709           8 :         for (i = 0; i < avf->nb_streams; i++) {
     710           6 :             if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
     711           1 :                 w = FFMAX(w, avf->streams[i]->codecpar->width);
     712           1 :                 h = FFMAX(h, avf->streams[i]->codecpar->height);
     713             :             }
     714             :         }
     715           2 :         if (!(w && h)) {
     716           1 :             w = FFMAX(w, 720);
     717           1 :             h = FFMAX(h, 576);
     718             :         }
     719           2 :         av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h);
     720             :     }
     721           2 :     ist->sub2video.w = ifilter->width  = w;
     722           2 :     ist->sub2video.h = ifilter->height = h;
     723             : 
     724           2 :     ifilter->width  = ist->dec_ctx->width  ? ist->dec_ctx->width  : ist->sub2video.w;
     725           2 :     ifilter->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h;
     726             : 
     727             :     /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
     728             :        palettes for all rectangles are identical or compatible */
     729           2 :     ifilter->format = AV_PIX_FMT_RGB32;
     730             : 
     731           2 :     ist->sub2video.frame = av_frame_alloc();
     732           2 :     if (!ist->sub2video.frame)
     733           0 :         return AVERROR(ENOMEM);
     734           2 :     ist->sub2video.last_pts = INT64_MIN;
     735           2 :     return 0;
     736             : }
     737             : 
     738        4423 : static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
     739             :                                         AVFilterInOut *in)
     740             : {
     741             :     AVFilterContext *last_filter;
     742        4423 :     const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
     743        4423 :     InputStream *ist = ifilter->ist;
     744        4423 :     InputFile     *f = input_files[ist->file_index];
     745        8823 :     AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
     746        4400 :                                          ist->st->time_base;
     747        4423 :     AVRational fr = ist->framerate;
     748             :     AVRational sar;
     749             :     AVBPrint args;
     750             :     char name[255];
     751        4423 :     int ret, pad_idx = 0;
     752        4423 :     int64_t tsoffset = 0;
     753        4423 :     AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();
     754             : 
     755        4423 :     if (!par)
     756           0 :         return AVERROR(ENOMEM);
     757        4423 :     memset(par, 0, sizeof(*par));
     758        4423 :     par->format = AV_PIX_FMT_NONE;
     759             : 
     760        4423 :     if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
     761           0 :         av_log(NULL, AV_LOG_ERROR, "Cannot connect video filter to audio input\n");
     762           0 :         ret = AVERROR(EINVAL);
     763           0 :         goto fail;
     764             :     }
     765             : 
     766        4423 :     if (!fr.num)
     767        4400 :         fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
     768             : 
     769        4423 :     if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
     770           2 :         ret = sub2video_prepare(ist, ifilter);
     771           2 :         if (ret < 0)
     772           0 :             goto fail;
     773             :     }
     774             : 
     775        4423 :     sar = ifilter->sample_aspect_ratio;
     776        4423 :     if(!sar.den)
     777           2 :         sar = (AVRational){0,1};
     778        4423 :     av_bprint_init(&args, 0, 1);
     779        4423 :     av_bprintf(&args,
     780             :              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
     781             :              "pixel_aspect=%d/%d:sws_param=flags=%d",
     782             :              ifilter->width, ifilter->height, ifilter->format,
     783             :              tb.num, tb.den, sar.num, sar.den,
     784        4423 :              SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
     785        4423 :     if (fr.num && fr.den)
     786        4421 :         av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
     787        4423 :     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
     788        4423 :              ist->file_index, ist->st->index);
     789             : 
     790             : 
     791        8846 :     if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
     792        4423 :                                             args.str, NULL, fg->graph)) < 0)
     793           0 :         goto fail;
     794        4423 :     par->hw_frames_ctx = ifilter->hw_frames_ctx;
     795        4423 :     ret = av_buffersrc_parameters_set(ifilter->filter, par);
     796        4423 :     if (ret < 0)
     797           0 :         goto fail;
     798        4423 :     av_freep(&par);
     799        4423 :     last_filter = ifilter->filter;
     800             : 
     801        4423 :     if (ist->autorotate) {
     802        4423 :         double theta = get_rotation(ist->st);
     803             : 
     804        4423 :         if (fabs(theta - 90) < 1.0) {
     805           0 :             ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
     806        4423 :         } else if (fabs(theta - 180) < 1.0) {
     807           0 :             ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
     808           0 :             if (ret < 0)
     809           0 :                 return ret;
     810           0 :             ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
     811        4423 :         } else if (fabs(theta - 270) < 1.0) {
     812           0 :             ret = insert_filter(&last_filter, &pad_idx, "transpose", "cclock");
     813        4423 :         } else if (fabs(theta) > 1.0) {
     814             :             char rotate_buf[64];
     815           0 :             snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
     816           0 :             ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
     817             :         }
     818        4423 :         if (ret < 0)
     819           0 :             return ret;
     820             :     }
     821             : 
     822        4423 :     if (do_deinterlace) {
     823             :         AVFilterContext *yadif;
     824             : 
     825           0 :         snprintf(name, sizeof(name), "deinterlace_in_%d_%d",
     826           0 :                  ist->file_index, ist->st->index);
     827           0 :         if ((ret = avfilter_graph_create_filter(&yadif,
     828             :                                                 avfilter_get_by_name("yadif"),
     829             :                                                 name, "", NULL,
     830             :                                                 fg->graph)) < 0)
     831           0 :             return ret;
     832             : 
     833           0 :         if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
     834           0 :             return ret;
     835             : 
     836           0 :         last_filter = yadif;
     837             :     }
     838             : 
     839        4423 :     snprintf(name, sizeof(name), "trim_in_%d_%d",
     840        4423 :              ist->file_index, ist->st->index);
     841        4423 :     if (copy_ts) {
     842           0 :         tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
     843           0 :         if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
     844           0 :             tsoffset += f->ctx->start_time;
     845             :     }
     846        4423 :     ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
     847             :                       AV_NOPTS_VALUE : tsoffset, f->recording_time,
     848             :                       &last_filter, &pad_idx, name);
     849        4423 :     if (ret < 0)
     850           0 :         return ret;
     851             : 
     852        4423 :     if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
     853           0 :         return ret;
     854        4423 :     return 0;
     855           0 : fail:
     856           0 :     av_freep(&par);
     857             : 
     858           0 :     return ret;
     859             : }
     860             : 
     861        1073 : static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
     862             :                                         AVFilterInOut *in)
     863             : {
     864             :     AVFilterContext *last_filter;
     865        1073 :     const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
     866        1073 :     InputStream *ist = ifilter->ist;
     867        1073 :     InputFile     *f = input_files[ist->file_index];
     868             :     AVBPrint args;
     869             :     char name[255];
     870        1073 :     int ret, pad_idx = 0;
     871        1073 :     int64_t tsoffset = 0;
     872             : 
     873        1073 :     if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_AUDIO) {
     874           0 :         av_log(NULL, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n");
     875           0 :         return AVERROR(EINVAL);
     876             :     }
     877             : 
     878        1073 :     av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
     879        1073 :     av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
     880             :              1, ifilter->sample_rate,
     881             :              ifilter->sample_rate,
     882        1073 :              av_get_sample_fmt_name(ifilter->format));
     883        1073 :     if (ifilter->channel_layout)
     884        1070 :         av_bprintf(&args, ":channel_layout=0x%"PRIx64,
     885             :                    ifilter->channel_layout);
     886             :     else
     887           3 :         av_bprintf(&args, ":channels=%d", ifilter->channels);
     888        1073 :     snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
     889        1073 :              ist->file_index, ist->st->index);
     890             : 
     891        2146 :     if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
     892        1073 :                                             name, args.str, NULL,
     893             :                                             fg->graph)) < 0)
     894           0 :         return ret;
     895        1073 :     last_filter = ifilter->filter;
     896             : 
     897             : #define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do {                 \
     898             :     AVFilterContext *filt_ctx;                                              \
     899             :                                                                             \
     900             :     av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi "            \
     901             :            "similarly to -af " filter_name "=%s.\n", arg);                  \
     902             :                                                                             \
     903             :     snprintf(name, sizeof(name), "graph_%d_%s_in_%d_%d",      \
     904             :                 fg->index, filter_name, ist->file_index, ist->st->index);   \
     905             :     ret = avfilter_graph_create_filter(&filt_ctx,                           \
     906             :                                        avfilter_get_by_name(filter_name),   \
     907             :                                        name, arg, NULL, fg->graph);         \
     908             :     if (ret < 0)                                                            \
     909             :         return ret;                                                         \
     910             :                                                                             \
     911             :     ret = avfilter_link(last_filter, 0, filt_ctx, 0);                       \
     912             :     if (ret < 0)                                                            \
     913             :         return ret;                                                         \
     914             :                                                                             \
     915             :     last_filter = filt_ctx;                                                 \
     916             : } while (0)
     917             : 
     918        1073 :     if (audio_sync_method > 0) {
     919           0 :         char args[256] = {0};
     920             : 
     921           0 :         av_strlcatf(args, sizeof(args), "async=%d", audio_sync_method);
     922           0 :         if (audio_drift_threshold != 0.1)
     923           0 :             av_strlcatf(args, sizeof(args), ":min_hard_comp=%f", audio_drift_threshold);
     924           0 :         if (!fg->reconfiguration)
     925           0 :             av_strlcatf(args, sizeof(args), ":first_pts=0");
     926           0 :         AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
     927             :     }
     928             : 
     929             : //     if (ost->audio_channels_mapped) {
     930             : //         int i;
     931             : //         AVBPrint pan_buf;
     932             : //         av_bprint_init(&pan_buf, 256, 8192);
     933             : //         av_bprintf(&pan_buf, "0x%"PRIx64,
     934             : //                    av_get_default_channel_layout(ost->audio_channels_mapped));
     935             : //         for (i = 0; i < ost->audio_channels_mapped; i++)
     936             : //             if (ost->audio_channels_map[i] != -1)
     937             : //                 av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
     938             : //         AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str);
     939             : //         av_bprint_finalize(&pan_buf, NULL);
     940             : //     }
     941             : 
     942        1073 :     if (audio_volume != 256) {
     943             :         char args[256];
     944             : 
     945           0 :         av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Use the volume "
     946             :                "audio filter instead.\n");
     947             : 
     948           0 :         snprintf(args, sizeof(args), "%f", audio_volume / 256.);
     949           0 :         AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
     950             :     }
     951             : 
     952        1073 :     snprintf(name, sizeof(name), "trim for input stream %d:%d",
     953        1073 :              ist->file_index, ist->st->index);
     954        1073 :     if (copy_ts) {
     955           0 :         tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
     956           0 :         if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
     957           0 :             tsoffset += f->ctx->start_time;
     958             :     }
     959        1073 :     ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
     960             :                       AV_NOPTS_VALUE : tsoffset, f->recording_time,
     961             :                       &last_filter, &pad_idx, name);
     962        1073 :     if (ret < 0)
     963           0 :         return ret;
     964             : 
     965        1073 :     if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
     966           0 :         return ret;
     967             : 
     968        1073 :     return 0;
     969             : }
     970             : 
     971        5496 : static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
     972             :                                   AVFilterInOut *in)
     973             : {
     974        5496 :     if (!ifilter->ist->dec) {
     975           0 :         av_log(NULL, AV_LOG_ERROR,
     976             :                "No decoder for stream #%d:%d, filtering impossible\n",
     977           0 :                ifilter->ist->file_index, ifilter->ist->st->index);
     978           0 :         return AVERROR_DECODER_NOT_FOUND;
     979             :     }
     980        5496 :     switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
     981        4423 :     case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
     982        1073 :     case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
     983           0 :     default: av_assert0(0);
     984             :     }
     985             : }
     986             : 
     987        5511 : static void cleanup_filtergraph(FilterGraph *fg)
     988             : {
     989             :     int i;
     990       11024 :     for (i = 0; i < fg->nb_outputs; i++)
     991        5513 :         fg->outputs[i]->filter = (AVFilterContext *)NULL;
     992       11007 :     for (i = 0; i < fg->nb_inputs; i++)
     993        5496 :         fg->inputs[i]->filter = (AVFilterContext *)NULL;
     994        5511 :     avfilter_graph_free(&fg->graph);
     995        5511 : }
     996             : 
     997        5511 : int configure_filtergraph(FilterGraph *fg)
     998             : {
     999             :     AVFilterInOut *inputs, *outputs, *cur;
    1000        5511 :     int ret, i, simple = filtergraph_is_simple(fg);
    1001        5511 :     const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
    1002             :                                       fg->graph_desc;
    1003             : 
    1004        5511 :     cleanup_filtergraph(fg);
    1005        5511 :     if (!(fg->graph = avfilter_graph_alloc()))
    1006           0 :         return AVERROR(ENOMEM);
    1007             : 
    1008        5511 :     if (simple) {
    1009        5440 :         OutputStream *ost = fg->outputs[0]->ost;
    1010             :         char args[512];
    1011        5440 :         AVDictionaryEntry *e = NULL;
    1012             : 
    1013        5440 :         fg->graph->nb_threads = filter_nbthreads;
    1014             : 
    1015        5440 :         args[0] = 0;
    1016       19529 :         while ((e = av_dict_get(ost->sws_dict, "", e,
    1017             :                                 AV_DICT_IGNORE_SUFFIX))) {
    1018        8649 :             av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
    1019             :         }
    1020        5440 :         if (strlen(args))
    1021        5440 :             args[strlen(args)-1] = 0;
    1022        5440 :         fg->graph->scale_sws_opts = av_strdup(args);
    1023             : 
    1024        5440 :         args[0] = 0;
    1025       10929 :         while ((e = av_dict_get(ost->swr_opts, "", e,
    1026             :                                 AV_DICT_IGNORE_SUFFIX))) {
    1027          49 :             av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
    1028             :         }
    1029        5440 :         if (strlen(args))
    1030          49 :             args[strlen(args)-1] = 0;
    1031        5440 :         av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
    1032             : 
    1033        5440 :         args[0] = '\0';
    1034       10886 :         while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
    1035             :                                 AV_DICT_IGNORE_SUFFIX))) {
    1036           6 :             av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
    1037             :         }
    1038        5440 :         if (strlen(args))
    1039           6 :             args[strlen(args) - 1] = '\0';
    1040             : 
    1041        5440 :         e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
    1042        5440 :         if (e)
    1043        3079 :             av_opt_set(fg->graph, "threads", e->value, 0);
    1044             :     } else {
    1045          71 :         fg->graph->nb_threads = filter_complex_nbthreads;
    1046             :     }
    1047             : 
    1048        5511 :     if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
    1049           0 :         goto fail;
    1050             : 
    1051        5511 :     if (filter_hw_device || hw_device_ctx) {
    1052           0 :         AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref
    1053           0 :                                                : hw_device_ctx;
    1054           0 :         for (i = 0; i < fg->graph->nb_filters; i++) {
    1055           0 :             fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device);
    1056           0 :             if (!fg->graph->filters[i]->hw_device_ctx) {
    1057           0 :                 ret = AVERROR(ENOMEM);
    1058           0 :                 goto fail;
    1059             :             }
    1060             :         }
    1061             :     }
    1062             : 
    1063        5511 :     if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
    1064             :         const char *num_inputs;
    1065             :         const char *num_outputs;
    1066           0 :         if (!outputs) {
    1067           0 :             num_outputs = "0";
    1068           0 :         } else if (outputs->next) {
    1069           0 :             num_outputs = ">1";
    1070             :         } else {
    1071           0 :             num_outputs = "1";
    1072             :         }
    1073           0 :         if (!inputs) {
    1074           0 :             num_inputs = "0";
    1075           0 :         } else if (inputs->next) {
    1076           0 :             num_inputs = ">1";
    1077             :         } else {
    1078           0 :             num_inputs = "1";
    1079             :         }
    1080           0 :         av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
    1081             :                "to have exactly 1 input and 1 output."
    1082             :                " However, it had %s input(s) and %s output(s)."
    1083             :                " Please adjust, or use a complex filtergraph (-filter_complex) instead.\n",
    1084             :                graph_desc, num_inputs, num_outputs);
    1085           0 :         ret = AVERROR(EINVAL);
    1086           0 :         goto fail;
    1087             :     }
    1088             : 
    1089       11007 :     for (cur = inputs, i = 0; cur; cur = cur->next, i++)
    1090        5496 :         if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) {
    1091           0 :             avfilter_inout_free(&inputs);
    1092           0 :             avfilter_inout_free(&outputs);
    1093           0 :             goto fail;
    1094             :         }
    1095        5511 :     avfilter_inout_free(&inputs);
    1096             : 
    1097       11024 :     for (cur = outputs, i = 0; cur; cur = cur->next, i++)
    1098        5513 :         configure_output_filter(fg, fg->outputs[i], cur);
    1099        5511 :     avfilter_inout_free(&outputs);
    1100             : 
    1101        5511 :     if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
    1102           0 :         goto fail;
    1103             : 
    1104             :     /* limit the lists of allowed formats to the ones selected, to
    1105             :      * make sure they stay the same if the filtergraph is reconfigured later */
    1106       11024 :     for (i = 0; i < fg->nb_outputs; i++) {
    1107        5513 :         OutputFilter *ofilter = fg->outputs[i];
    1108        5513 :         AVFilterContext *sink = ofilter->filter;
    1109             : 
    1110        5513 :         ofilter->format = av_buffersink_get_format(sink);
    1111             : 
    1112        5513 :         ofilter->width  = av_buffersink_get_w(sink);
    1113        5513 :         ofilter->height = av_buffersink_get_h(sink);
    1114             : 
    1115        5513 :         ofilter->sample_rate    = av_buffersink_get_sample_rate(sink);
    1116        5513 :         ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
    1117             :     }
    1118             : 
    1119        5511 :     fg->reconfiguration = 1;
    1120             : 
    1121       11024 :     for (i = 0; i < fg->nb_outputs; i++) {
    1122        5513 :         OutputStream *ost = fg->outputs[i]->ost;
    1123        5513 :         if (!ost->enc) {
    1124             :             /* identical to the same check in ffmpeg.c, needed because
    1125             :                complex filter graphs are initialized earlier */
    1126           0 :             av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n",
    1127           0 :                      avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index);
    1128           0 :             ret = AVERROR(EINVAL);
    1129           0 :             goto fail;
    1130             :         }
    1131        6582 :         if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
    1132        1069 :             !(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
    1133          85 :             av_buffersink_set_frame_size(ost->filter->filter,
    1134          85 :                                          ost->enc_ctx->frame_size);
    1135             :     }
    1136             : 
    1137       11007 :     for (i = 0; i < fg->nb_inputs; i++) {
    1138       11011 :         while (av_fifo_size(fg->inputs[i]->frame_queue)) {
    1139             :             AVFrame *tmp;
    1140          19 :             av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
    1141          19 :             ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
    1142          19 :             av_frame_free(&tmp);
    1143          19 :             if (ret < 0)
    1144           0 :                 goto fail;
    1145             :         }
    1146             :     }
    1147             : 
    1148             :     /* send the EOFs for the finished inputs */
    1149       11007 :     for (i = 0; i < fg->nb_inputs; i++) {
    1150        5496 :         if (fg->inputs[i]->eof) {
    1151           0 :             ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL);
    1152           0 :             if (ret < 0)
    1153           0 :                 goto fail;
    1154             :         }
    1155             :     }
    1156             : 
    1157             :     /* process queued up subtitle packets */
    1158       11007 :     for (i = 0; i < fg->nb_inputs; i++) {
    1159        5496 :         InputStream *ist = fg->inputs[i]->ist;
    1160        5496 :         if (ist->sub2video.sub_queue && ist->sub2video.frame) {
    1161           0 :             while (av_fifo_size(ist->sub2video.sub_queue)) {
    1162             :                 AVSubtitle tmp;
    1163           0 :                 av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
    1164           0 :                 sub2video_update(ist, &tmp);
    1165           0 :                 avsubtitle_free(&tmp);
    1166             :             }
    1167             :         }
    1168             :     }
    1169             : 
    1170        5511 :     return 0;
    1171             : 
    1172           0 : fail:
    1173           0 :     cleanup_filtergraph(fg);
    1174           0 :     return ret;
    1175             : }
    1176             : 
    1177        5494 : int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
    1178             : {
    1179        5494 :     av_buffer_unref(&ifilter->hw_frames_ctx);
    1180             : 
    1181        5494 :     ifilter->format = frame->format;
    1182             : 
    1183        5494 :     ifilter->width               = frame->width;
    1184        5494 :     ifilter->height              = frame->height;
    1185        5494 :     ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
    1186             : 
    1187        5494 :     ifilter->sample_rate         = frame->sample_rate;
    1188        5494 :     ifilter->channels            = frame->channels;
    1189        5494 :     ifilter->channel_layout      = frame->channel_layout;
    1190             : 
    1191        5494 :     if (frame->hw_frames_ctx) {
    1192           0 :         ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
    1193           0 :         if (!ifilter->hw_frames_ctx)
    1194           0 :             return AVERROR(ENOMEM);
    1195             :     }
    1196             : 
    1197        5494 :     return 0;
    1198             : }
    1199             : 
    1200           0 : int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
    1201             : {
    1202             :     int i;
    1203           0 :     for (i = 0; i < fg->nb_inputs; i++)
    1204           0 :         if (fg->inputs[i]->ist == ist)
    1205           0 :             return 1;
    1206           0 :     return 0;
    1207             : }
    1208             : 
    1209       16446 : int filtergraph_is_simple(FilterGraph *fg)
    1210             : {
    1211       16446 :     return !fg->graph_desc;
    1212             : }

Generated by: LCOV version 1.13