LCOV - code coverage report
Current view: top level - src - ffmpeg_filter.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 427 601 71.0 %
Date: 2017-01-28 02:43:52 Functions: 22 24 91.7 %

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

Generated by: LCOV version 1.12