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

Generated by: LCOV version 1.13