annotate ffmpeg/ffmpeg_filter.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * ffmpeg filter configuration
yading@10 3 *
yading@10 4 * This file is part of FFmpeg.
yading@10 5 *
yading@10 6 * FFmpeg is free software; you can redistribute it and/or
yading@10 7 * modify it under the terms of the GNU Lesser General Public
yading@10 8 * License as published by the Free Software Foundation; either
yading@10 9 * version 2.1 of the License, or (at your option) any later version.
yading@10 10 *
yading@10 11 * FFmpeg is distributed in the hope that it will be useful,
yading@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 14 * Lesser General Public License for more details.
yading@10 15 *
yading@10 16 * You should have received a copy of the GNU Lesser General Public
yading@10 17 * License along with FFmpeg; if not, write to the Free Software
yading@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 19 */
yading@10 20
yading@10 21 #include "ffmpeg.h"
yading@10 22
yading@10 23 #include "libavfilter/avfilter.h"
yading@10 24 #include "libavfilter/buffersink.h"
yading@10 25
yading@10 26 #include "libavresample/avresample.h"
yading@10 27
yading@10 28 #include "libavutil/avassert.h"
yading@10 29 #include "libavutil/avstring.h"
yading@10 30 #include "libavutil/bprint.h"
yading@10 31 #include "libavutil/channel_layout.h"
yading@10 32 #include "libavutil/opt.h"
yading@10 33 #include "libavutil/pixdesc.h"
yading@10 34 #include "libavutil/pixfmt.h"
yading@10 35 #include "libavutil/imgutils.h"
yading@10 36 #include "libavutil/samplefmt.h"
yading@10 37
yading@10 38 enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum AVPixelFormat target)
yading@10 39 {
yading@10 40 if (codec && codec->pix_fmts) {
yading@10 41 const enum AVPixelFormat *p = codec->pix_fmts;
yading@10 42 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
yading@10 43 int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
yading@10 44 enum AVPixelFormat best= AV_PIX_FMT_NONE;
yading@10 45 if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
yading@10 46 if (st->codec->codec_id == AV_CODEC_ID_MJPEG) {
yading@10 47 p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE };
yading@10 48 } else if (st->codec->codec_id == AV_CODEC_ID_LJPEG) {
yading@10 49 p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P,
yading@10 50 AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
yading@10 51 }
yading@10 52 }
yading@10 53 for (; *p != AV_PIX_FMT_NONE; p++) {
yading@10 54 best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
yading@10 55 if (*p == target)
yading@10 56 break;
yading@10 57 }
yading@10 58 if (*p == AV_PIX_FMT_NONE) {
yading@10 59 if (target != AV_PIX_FMT_NONE)
yading@10 60 av_log(NULL, AV_LOG_WARNING,
yading@10 61 "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
yading@10 62 av_get_pix_fmt_name(target),
yading@10 63 codec->name,
yading@10 64 av_get_pix_fmt_name(best));
yading@10 65 return best;
yading@10 66 }
yading@10 67 }
yading@10 68 return target;
yading@10 69 }
yading@10 70
yading@10 71 void choose_sample_fmt(AVStream *st, AVCodec *codec)
yading@10 72 {
yading@10 73 if (codec && codec->sample_fmts) {
yading@10 74 const enum AVSampleFormat *p = codec->sample_fmts;
yading@10 75 for (; *p != -1; p++) {
yading@10 76 if (*p == st->codec->sample_fmt)
yading@10 77 break;
yading@10 78 }
yading@10 79 if (*p == -1) {
yading@10 80 if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
yading@10 81 av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
yading@10 82 if(av_get_sample_fmt_name(st->codec->sample_fmt))
yading@10 83 av_log(NULL, AV_LOG_WARNING,
yading@10 84 "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
yading@10 85 av_get_sample_fmt_name(st->codec->sample_fmt),
yading@10 86 codec->name,
yading@10 87 av_get_sample_fmt_name(codec->sample_fmts[0]));
yading@10 88 st->codec->sample_fmt = codec->sample_fmts[0];
yading@10 89 }
yading@10 90 }
yading@10 91 }
yading@10 92
yading@10 93 static char *choose_pix_fmts(OutputStream *ost)
yading@10 94 {
yading@10 95 if (ost->keep_pix_fmt) {
yading@10 96 if (ost->filter)
yading@10 97 avfilter_graph_set_auto_convert(ost->filter->graph->graph,
yading@10 98 AVFILTER_AUTO_CONVERT_NONE);
yading@10 99 if (ost->st->codec->pix_fmt == AV_PIX_FMT_NONE)
yading@10 100 return NULL;
yading@10 101 return av_strdup(av_get_pix_fmt_name(ost->st->codec->pix_fmt));
yading@10 102 }
yading@10 103 if (ost->st->codec->pix_fmt != AV_PIX_FMT_NONE) {
yading@10 104 return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc, ost->st->codec->pix_fmt)));
yading@10 105 } else if (ost->enc && ost->enc->pix_fmts) {
yading@10 106 const enum AVPixelFormat *p;
yading@10 107 AVIOContext *s = NULL;
yading@10 108 uint8_t *ret;
yading@10 109 int len;
yading@10 110
yading@10 111 if (avio_open_dyn_buf(&s) < 0)
yading@10 112 exit(1);
yading@10 113
yading@10 114 p = ost->enc->pix_fmts;
yading@10 115 if (ost->st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
yading@10 116 if (ost->st->codec->codec_id == AV_CODEC_ID_MJPEG) {
yading@10 117 p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE };
yading@10 118 } else if (ost->st->codec->codec_id == AV_CODEC_ID_LJPEG) {
yading@10 119 p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P,
yading@10 120 AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
yading@10 121 }
yading@10 122 }
yading@10 123
yading@10 124 for (; *p != AV_PIX_FMT_NONE; p++) {
yading@10 125 const char *name = av_get_pix_fmt_name(*p);
yading@10 126 avio_printf(s, "%s|", name);
yading@10 127 }
yading@10 128 len = avio_close_dyn_buf(s, &ret);
yading@10 129 ret[len - 1] = 0;
yading@10 130 return ret;
yading@10 131 } else
yading@10 132 return NULL;
yading@10 133 }
yading@10 134
yading@10 135 /* Define a function for building a string containing a list of
yading@10 136 * allowed formats. */
yading@10 137 #define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name) \
yading@10 138 static char *choose_ ## var ## s(OutputStream *ost) \
yading@10 139 { \
yading@10 140 if (ost->st->codec->var != none) { \
yading@10 141 get_name(ost->st->codec->var); \
yading@10 142 return av_strdup(name); \
yading@10 143 } else if (ost->enc && ost->enc->supported_list) { \
yading@10 144 const type *p; \
yading@10 145 AVIOContext *s = NULL; \
yading@10 146 uint8_t *ret; \
yading@10 147 int len; \
yading@10 148 \
yading@10 149 if (avio_open_dyn_buf(&s) < 0) \
yading@10 150 exit(1); \
yading@10 151 \
yading@10 152 for (p = ost->enc->supported_list; *p != none; p++) { \
yading@10 153 get_name(*p); \
yading@10 154 avio_printf(s, "%s|", name); \
yading@10 155 } \
yading@10 156 len = avio_close_dyn_buf(s, &ret); \
yading@10 157 ret[len - 1] = 0; \
yading@10 158 return ret; \
yading@10 159 } else \
yading@10 160 return NULL; \
yading@10 161 }
yading@10 162
yading@10 163 // DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
yading@10 164 // GET_PIX_FMT_NAME)
yading@10 165
yading@10 166 DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
yading@10 167 AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
yading@10 168
yading@10 169 DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
yading@10 170 GET_SAMPLE_RATE_NAME)
yading@10 171
yading@10 172 DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
yading@10 173 GET_CH_LAYOUT_NAME)
yading@10 174
yading@10 175 FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
yading@10 176 {
yading@10 177 FilterGraph *fg = av_mallocz(sizeof(*fg));
yading@10 178
yading@10 179 if (!fg)
yading@10 180 exit(1);
yading@10 181 fg->index = nb_filtergraphs;
yading@10 182
yading@10 183 GROW_ARRAY(fg->outputs, fg->nb_outputs);
yading@10 184 if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
yading@10 185 exit(1);
yading@10 186 fg->outputs[0]->ost = ost;
yading@10 187 fg->outputs[0]->graph = fg;
yading@10 188
yading@10 189 ost->filter = fg->outputs[0];
yading@10 190
yading@10 191 GROW_ARRAY(fg->inputs, fg->nb_inputs);
yading@10 192 if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
yading@10 193 exit(1);
yading@10 194 fg->inputs[0]->ist = ist;
yading@10 195 fg->inputs[0]->graph = fg;
yading@10 196
yading@10 197 GROW_ARRAY(ist->filters, ist->nb_filters);
yading@10 198 ist->filters[ist->nb_filters - 1] = fg->inputs[0];
yading@10 199
yading@10 200 GROW_ARRAY(filtergraphs, nb_filtergraphs);
yading@10 201 filtergraphs[nb_filtergraphs - 1] = fg;
yading@10 202
yading@10 203 return fg;
yading@10 204 }
yading@10 205
yading@10 206 static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
yading@10 207 {
yading@10 208 InputStream *ist = NULL;
yading@10 209 enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
yading@10 210 int i;
yading@10 211
yading@10 212 // TODO: support other filter types
yading@10 213 if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
yading@10 214 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
yading@10 215 "currently.\n");
yading@10 216 exit(1);
yading@10 217 }
yading@10 218
yading@10 219 if (in->name) {
yading@10 220 AVFormatContext *s;
yading@10 221 AVStream *st = NULL;
yading@10 222 char *p;
yading@10 223 int file_idx = strtol(in->name, &p, 0);
yading@10 224
yading@10 225 if (file_idx < 0 || file_idx >= nb_input_files) {
yading@10 226 av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
yading@10 227 file_idx, fg->graph_desc);
yading@10 228 exit(1);
yading@10 229 }
yading@10 230 s = input_files[file_idx]->ctx;
yading@10 231
yading@10 232 for (i = 0; i < s->nb_streams; i++) {
yading@10 233 enum AVMediaType stream_type = s->streams[i]->codec->codec_type;
yading@10 234 if (stream_type != type &&
yading@10 235 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
yading@10 236 type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
yading@10 237 continue;
yading@10 238 if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) {
yading@10 239 st = s->streams[i];
yading@10 240 break;
yading@10 241 }
yading@10 242 }
yading@10 243 if (!st) {
yading@10 244 av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
yading@10 245 "matches no streams.\n", p, fg->graph_desc);
yading@10 246 exit(1);
yading@10 247 }
yading@10 248 ist = input_streams[input_files[file_idx]->ist_index + st->index];
yading@10 249 } else {
yading@10 250 /* find the first unused stream of corresponding type */
yading@10 251 for (i = 0; i < nb_input_streams; i++) {
yading@10 252 ist = input_streams[i];
yading@10 253 if (ist->st->codec->codec_type == type && ist->discard)
yading@10 254 break;
yading@10 255 }
yading@10 256 if (i == nb_input_streams) {
yading@10 257 av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
yading@10 258 "unlabeled input pad %d on filter %s\n", in->pad_idx,
yading@10 259 in->filter_ctx->name);
yading@10 260 exit(1);
yading@10 261 }
yading@10 262 }
yading@10 263 av_assert0(ist);
yading@10 264
yading@10 265 ist->discard = 0;
yading@10 266 ist->decoding_needed++;
yading@10 267 ist->st->discard = AVDISCARD_NONE;
yading@10 268
yading@10 269 GROW_ARRAY(fg->inputs, fg->nb_inputs);
yading@10 270 if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
yading@10 271 exit(1);
yading@10 272 fg->inputs[fg->nb_inputs - 1]->ist = ist;
yading@10 273 fg->inputs[fg->nb_inputs - 1]->graph = fg;
yading@10 274
yading@10 275 GROW_ARRAY(ist->filters, ist->nb_filters);
yading@10 276 ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
yading@10 277 }
yading@10 278
yading@10 279 static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
yading@10 280 {
yading@10 281 char *pix_fmts;
yading@10 282 OutputStream *ost = ofilter->ost;
yading@10 283 AVCodecContext *codec = ost->st->codec;
yading@10 284 AVFilterContext *last_filter = out->filter_ctx;
yading@10 285 int pad_idx = out->pad_idx;
yading@10 286 int ret;
yading@10 287 char name[255];
yading@10 288
yading@10 289 snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
yading@10 290 ret = avfilter_graph_create_filter(&ofilter->filter,
yading@10 291 avfilter_get_by_name("buffersink"),
yading@10 292 name, NULL, NULL, fg->graph);
yading@10 293
yading@10 294 if (ret < 0)
yading@10 295 return ret;
yading@10 296
yading@10 297 if (codec->width || codec->height) {
yading@10 298 char args[255];
yading@10 299 AVFilterContext *filter;
yading@10 300
yading@10 301 snprintf(args, sizeof(args), "%d:%d:flags=0x%X",
yading@10 302 codec->width,
yading@10 303 codec->height,
yading@10 304 (unsigned)ost->sws_flags);
yading@10 305 snprintf(name, sizeof(name), "scaler for output stream %d:%d",
yading@10 306 ost->file_index, ost->index);
yading@10 307 if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
yading@10 308 name, args, NULL, fg->graph)) < 0)
yading@10 309 return ret;
yading@10 310 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
yading@10 311 return ret;
yading@10 312
yading@10 313 last_filter = filter;
yading@10 314 pad_idx = 0;
yading@10 315 }
yading@10 316
yading@10 317 if ((pix_fmts = choose_pix_fmts(ost))) {
yading@10 318 AVFilterContext *filter;
yading@10 319 snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
yading@10 320 ost->file_index, ost->index);
yading@10 321 if ((ret = avfilter_graph_create_filter(&filter,
yading@10 322 avfilter_get_by_name("format"),
yading@10 323 "format", pix_fmts, NULL,
yading@10 324 fg->graph)) < 0)
yading@10 325 return ret;
yading@10 326 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
yading@10 327 return ret;
yading@10 328
yading@10 329 last_filter = filter;
yading@10 330 pad_idx = 0;
yading@10 331 av_freep(&pix_fmts);
yading@10 332 }
yading@10 333
yading@10 334 if (ost->frame_rate.num && 0) {
yading@10 335 AVFilterContext *fps;
yading@10 336 char args[255];
yading@10 337
yading@10 338 snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
yading@10 339 ost->frame_rate.den);
yading@10 340 snprintf(name, sizeof(name), "fps for output stream %d:%d",
yading@10 341 ost->file_index, ost->index);
yading@10 342 ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
yading@10 343 name, args, NULL, fg->graph);
yading@10 344 if (ret < 0)
yading@10 345 return ret;
yading@10 346
yading@10 347 ret = avfilter_link(last_filter, pad_idx, fps, 0);
yading@10 348 if (ret < 0)
yading@10 349 return ret;
yading@10 350 last_filter = fps;
yading@10 351 pad_idx = 0;
yading@10 352 }
yading@10 353
yading@10 354 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
yading@10 355 return ret;
yading@10 356
yading@10 357 return 0;
yading@10 358 }
yading@10 359
yading@10 360 static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
yading@10 361 {
yading@10 362 OutputStream *ost = ofilter->ost;
yading@10 363 AVCodecContext *codec = ost->st->codec;
yading@10 364 AVFilterContext *last_filter = out->filter_ctx;
yading@10 365 int pad_idx = out->pad_idx;
yading@10 366 char *sample_fmts, *sample_rates, *channel_layouts;
yading@10 367 char name[255];
yading@10 368 int ret;
yading@10 369
yading@10 370 snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
yading@10 371 ret = avfilter_graph_create_filter(&ofilter->filter,
yading@10 372 avfilter_get_by_name("abuffersink"),
yading@10 373 name, NULL, NULL, fg->graph);
yading@10 374 if (ret < 0)
yading@10 375 return ret;
yading@10 376 if ((ret = av_opt_set_int(ofilter->filter, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
yading@10 377 return ret;
yading@10 378
yading@10 379 #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
yading@10 380 AVFilterContext *filt_ctx; \
yading@10 381 \
yading@10 382 av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
yading@10 383 "similarly to -af " filter_name "=%s.\n", arg); \
yading@10 384 \
yading@10 385 ret = avfilter_graph_create_filter(&filt_ctx, \
yading@10 386 avfilter_get_by_name(filter_name), \
yading@10 387 filter_name, arg, NULL, fg->graph); \
yading@10 388 if (ret < 0) \
yading@10 389 return ret; \
yading@10 390 \
yading@10 391 ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
yading@10 392 if (ret < 0) \
yading@10 393 return ret; \
yading@10 394 \
yading@10 395 last_filter = filt_ctx; \
yading@10 396 pad_idx = 0; \
yading@10 397 } while (0)
yading@10 398 if (ost->audio_channels_mapped) {
yading@10 399 int i;
yading@10 400 AVBPrint pan_buf;
yading@10 401 av_bprint_init(&pan_buf, 256, 8192);
yading@10 402 av_bprintf(&pan_buf, "0x%"PRIx64,
yading@10 403 av_get_default_channel_layout(ost->audio_channels_mapped));
yading@10 404 for (i = 0; i < ost->audio_channels_mapped; i++)
yading@10 405 if (ost->audio_channels_map[i] != -1)
yading@10 406 av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
yading@10 407
yading@10 408 AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
yading@10 409 av_bprint_finalize(&pan_buf, NULL);
yading@10 410 }
yading@10 411
yading@10 412 if (codec->channels && !codec->channel_layout)
yading@10 413 codec->channel_layout = av_get_default_channel_layout(codec->channels);
yading@10 414
yading@10 415 sample_fmts = choose_sample_fmts(ost);
yading@10 416 sample_rates = choose_sample_rates(ost);
yading@10 417 channel_layouts = choose_channel_layouts(ost);
yading@10 418 if (sample_fmts || sample_rates || channel_layouts) {
yading@10 419 AVFilterContext *format;
yading@10 420 char args[256];
yading@10 421 args[0] = 0;
yading@10 422
yading@10 423 if (sample_fmts)
yading@10 424 av_strlcatf(args, sizeof(args), "sample_fmts=%s:",
yading@10 425 sample_fmts);
yading@10 426 if (sample_rates)
yading@10 427 av_strlcatf(args, sizeof(args), "sample_rates=%s:",
yading@10 428 sample_rates);
yading@10 429 if (channel_layouts)
yading@10 430 av_strlcatf(args, sizeof(args), "channel_layouts=%s:",
yading@10 431 channel_layouts);
yading@10 432
yading@10 433 av_freep(&sample_fmts);
yading@10 434 av_freep(&sample_rates);
yading@10 435 av_freep(&channel_layouts);
yading@10 436
yading@10 437 snprintf(name, sizeof(name), "audio format for output stream %d:%d",
yading@10 438 ost->file_index, ost->index);
yading@10 439 ret = avfilter_graph_create_filter(&format,
yading@10 440 avfilter_get_by_name("aformat"),
yading@10 441 name, args, NULL, fg->graph);
yading@10 442 if (ret < 0)
yading@10 443 return ret;
yading@10 444
yading@10 445 ret = avfilter_link(last_filter, pad_idx, format, 0);
yading@10 446 if (ret < 0)
yading@10 447 return ret;
yading@10 448
yading@10 449 last_filter = format;
yading@10 450 pad_idx = 0;
yading@10 451 }
yading@10 452
yading@10 453 if (audio_volume != 256 && 0) {
yading@10 454 char args[256];
yading@10 455
yading@10 456 snprintf(args, sizeof(args), "%f", audio_volume / 256.);
yading@10 457 AUTO_INSERT_FILTER("-vol", "volume", args);
yading@10 458 }
yading@10 459
yading@10 460 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
yading@10 461 return ret;
yading@10 462
yading@10 463 return 0;
yading@10 464 }
yading@10 465
yading@10 466 #define DESCRIBE_FILTER_LINK(f, inout, in) \
yading@10 467 { \
yading@10 468 AVFilterContext *ctx = inout->filter_ctx; \
yading@10 469 AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; \
yading@10 470 int nb_pads = in ? ctx->input_count : ctx->output_count; \
yading@10 471 AVIOContext *pb; \
yading@10 472 \
yading@10 473 if (avio_open_dyn_buf(&pb) < 0) \
yading@10 474 exit(1); \
yading@10 475 \
yading@10 476 avio_printf(pb, "%s", ctx->filter->name); \
yading@10 477 if (nb_pads > 1) \
yading@10 478 avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\
yading@10 479 avio_w8(pb, 0); \
yading@10 480 avio_close_dyn_buf(pb, &f->name); \
yading@10 481 }
yading@10 482
yading@10 483 int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
yading@10 484 {
yading@10 485 av_freep(&ofilter->name);
yading@10 486 DESCRIBE_FILTER_LINK(ofilter, out, 0);
yading@10 487
yading@10 488 switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
yading@10 489 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
yading@10 490 case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
yading@10 491 default: av_assert0(0);
yading@10 492 }
yading@10 493 }
yading@10 494
yading@10 495 static int sub2video_prepare(InputStream *ist)
yading@10 496 {
yading@10 497 AVFormatContext *avf = input_files[ist->file_index]->ctx;
yading@10 498 int i, w, h;
yading@10 499
yading@10 500 /* Compute the size of the canvas for the subtitles stream.
yading@10 501 If the subtitles codec has set a size, use it. Otherwise use the
yading@10 502 maximum dimensions of the video streams in the same file. */
yading@10 503 w = ist->st->codec->width;
yading@10 504 h = ist->st->codec->height;
yading@10 505 if (!(w && h)) {
yading@10 506 for (i = 0; i < avf->nb_streams; i++) {
yading@10 507 if (avf->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
yading@10 508 w = FFMAX(w, avf->streams[i]->codec->width);
yading@10 509 h = FFMAX(h, avf->streams[i]->codec->height);
yading@10 510 }
yading@10 511 }
yading@10 512 if (!(w && h)) {
yading@10 513 w = FFMAX(w, 720);
yading@10 514 h = FFMAX(h, 576);
yading@10 515 }
yading@10 516 av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h);
yading@10 517 }
yading@10 518 ist->sub2video.w = ist->st->codec->width = ist->resample_width = w;
yading@10 519 ist->sub2video.h = ist->st->codec->height = ist->resample_height = h;
yading@10 520
yading@10 521 /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
yading@10 522 palettes for all rectangles are identical or compatible */
yading@10 523 ist->resample_pix_fmt = ist->st->codec->pix_fmt = AV_PIX_FMT_RGB32;
yading@10 524
yading@10 525 ist->sub2video.frame = av_frame_alloc();
yading@10 526 if (!ist->sub2video.frame)
yading@10 527 return AVERROR(ENOMEM);
yading@10 528 return 0;
yading@10 529 }
yading@10 530
yading@10 531 static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
yading@10 532 AVFilterInOut *in)
yading@10 533 {
yading@10 534 AVFilterContext *first_filter = in->filter_ctx;
yading@10 535 AVFilter *filter = avfilter_get_by_name("buffer");
yading@10 536 InputStream *ist = ifilter->ist;
yading@10 537 AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
yading@10 538 ist->st->time_base;
yading@10 539 AVRational fr = ist->framerate;
yading@10 540 AVRational sar;
yading@10 541 AVBPrint args;
yading@10 542 char name[255];
yading@10 543 int pad_idx = in->pad_idx;
yading@10 544 int ret;
yading@10 545
yading@10 546 if (!fr.num)
yading@10 547 fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
yading@10 548
yading@10 549 if (ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
yading@10 550 ret = sub2video_prepare(ist);
yading@10 551 if (ret < 0)
yading@10 552 return ret;
yading@10 553 }
yading@10 554
yading@10 555 sar = ist->st->sample_aspect_ratio.num ?
yading@10 556 ist->st->sample_aspect_ratio :
yading@10 557 ist->st->codec->sample_aspect_ratio;
yading@10 558 if(!sar.den)
yading@10 559 sar = (AVRational){0,1};
yading@10 560 av_bprint_init(&args, 0, 1);
yading@10 561 av_bprintf(&args,
yading@10 562 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
yading@10 563 "pixel_aspect=%d/%d:sws_param=flags=%d", ist->resample_width,
yading@10 564 ist->resample_height, ist->resample_pix_fmt,
yading@10 565 tb.num, tb.den, sar.num, sar.den,
yading@10 566 SWS_BILINEAR + ((ist->st->codec->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
yading@10 567 if (fr.num && fr.den)
yading@10 568 av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
yading@10 569 snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
yading@10 570 ist->file_index, ist->st->index);
yading@10 571
yading@10 572 if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, name,
yading@10 573 args.str, NULL, fg->graph)) < 0)
yading@10 574 return ret;
yading@10 575
yading@10 576 if (ist->framerate.num) {
yading@10 577 AVFilterContext *setpts;
yading@10 578
yading@10 579 snprintf(name, sizeof(name), "force CFR for input from stream %d:%d",
yading@10 580 ist->file_index, ist->st->index);
yading@10 581 if ((ret = avfilter_graph_create_filter(&setpts,
yading@10 582 avfilter_get_by_name("setpts"),
yading@10 583 name, "N", NULL,
yading@10 584 fg->graph)) < 0)
yading@10 585 return ret;
yading@10 586
yading@10 587 if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
yading@10 588 return ret;
yading@10 589
yading@10 590 first_filter = setpts;
yading@10 591 pad_idx = 0;
yading@10 592 }
yading@10 593
yading@10 594 if (do_deinterlace) {
yading@10 595 AVFilterContext *yadif;
yading@10 596
yading@10 597 snprintf(name, sizeof(name), "deinterlace input from stream %d:%d",
yading@10 598 ist->file_index, ist->st->index);
yading@10 599 if ((ret = avfilter_graph_create_filter(&yadif,
yading@10 600 avfilter_get_by_name("yadif"),
yading@10 601 name, "", NULL,
yading@10 602 fg->graph)) < 0)
yading@10 603 return ret;
yading@10 604
yading@10 605 if ((ret = avfilter_link(yadif, 0, first_filter, pad_idx)) < 0)
yading@10 606 return ret;
yading@10 607
yading@10 608 first_filter = yadif;
yading@10 609 pad_idx = 0;
yading@10 610 }
yading@10 611
yading@10 612 if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
yading@10 613 return ret;
yading@10 614 return 0;
yading@10 615 }
yading@10 616
yading@10 617 static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
yading@10 618 AVFilterInOut *in)
yading@10 619 {
yading@10 620 AVFilterContext *first_filter = in->filter_ctx;
yading@10 621 AVFilter *filter = avfilter_get_by_name("abuffer");
yading@10 622 InputStream *ist = ifilter->ist;
yading@10 623 int pad_idx = in->pad_idx;
yading@10 624 AVBPrint args;
yading@10 625 char name[255];
yading@10 626 int ret;
yading@10 627
yading@10 628 av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
yading@10 629 av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
yading@10 630 1, ist->st->codec->sample_rate,
yading@10 631 ist->st->codec->sample_rate,
yading@10 632 av_get_sample_fmt_name(ist->st->codec->sample_fmt));
yading@10 633 if (ist->st->codec->channel_layout)
yading@10 634 av_bprintf(&args, ":channel_layout=0x%"PRIx64,
yading@10 635 ist->st->codec->channel_layout);
yading@10 636 else
yading@10 637 av_bprintf(&args, ":channels=%d", ist->st->codec->channels);
yading@10 638 snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
yading@10 639 ist->file_index, ist->st->index);
yading@10 640
yading@10 641 if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter,
yading@10 642 name, args.str, NULL,
yading@10 643 fg->graph)) < 0)
yading@10 644 return ret;
yading@10 645
yading@10 646 #define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do { \
yading@10 647 AVFilterContext *filt_ctx; \
yading@10 648 \
yading@10 649 av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
yading@10 650 "similarly to -af " filter_name "=%s.\n", arg); \
yading@10 651 \
yading@10 652 snprintf(name, sizeof(name), "graph %d %s for input stream %d:%d", \
yading@10 653 fg->index, filter_name, ist->file_index, ist->st->index); \
yading@10 654 ret = avfilter_graph_create_filter(&filt_ctx, \
yading@10 655 avfilter_get_by_name(filter_name), \
yading@10 656 name, arg, NULL, fg->graph); \
yading@10 657 if (ret < 0) \
yading@10 658 return ret; \
yading@10 659 \
yading@10 660 ret = avfilter_link(filt_ctx, 0, first_filter, pad_idx); \
yading@10 661 if (ret < 0) \
yading@10 662 return ret; \
yading@10 663 \
yading@10 664 first_filter = filt_ctx; \
yading@10 665 } while (0)
yading@10 666
yading@10 667 if (audio_sync_method > 0) {
yading@10 668 char args[256] = {0};
yading@10 669
yading@10 670 av_strlcatf(args, sizeof(args), "async=%d", audio_sync_method);
yading@10 671 if (audio_drift_threshold != 0.1)
yading@10 672 av_strlcatf(args, sizeof(args), ":min_hard_comp=%f", audio_drift_threshold);
yading@10 673 if (!fg->reconfiguration)
yading@10 674 av_strlcatf(args, sizeof(args), ":first_pts=0");
yading@10 675 AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
yading@10 676 }
yading@10 677
yading@10 678 // if (ost->audio_channels_mapped) {
yading@10 679 // int i;
yading@10 680 // AVBPrint pan_buf;
yading@10 681 // av_bprint_init(&pan_buf, 256, 8192);
yading@10 682 // av_bprintf(&pan_buf, "0x%"PRIx64,
yading@10 683 // av_get_default_channel_layout(ost->audio_channels_mapped));
yading@10 684 // for (i = 0; i < ost->audio_channels_mapped; i++)
yading@10 685 // if (ost->audio_channels_map[i] != -1)
yading@10 686 // av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
yading@10 687 // AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str);
yading@10 688 // av_bprint_finalize(&pan_buf, NULL);
yading@10 689 // }
yading@10 690
yading@10 691 if (audio_volume != 256) {
yading@10 692 char args[256];
yading@10 693
yading@10 694 av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Use the volume "
yading@10 695 "audio filter instead.\n");
yading@10 696
yading@10 697 snprintf(args, sizeof(args), "%f", audio_volume / 256.);
yading@10 698 AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
yading@10 699 }
yading@10 700 if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
yading@10 701 return ret;
yading@10 702
yading@10 703 return 0;
yading@10 704 }
yading@10 705
yading@10 706 static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
yading@10 707 AVFilterInOut *in)
yading@10 708 {
yading@10 709 av_freep(&ifilter->name);
yading@10 710 DESCRIBE_FILTER_LINK(ifilter, in, 1);
yading@10 711
yading@10 712 switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
yading@10 713 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
yading@10 714 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
yading@10 715 default: av_assert0(0);
yading@10 716 }
yading@10 717 }
yading@10 718
yading@10 719 int configure_filtergraph(FilterGraph *fg)
yading@10 720 {
yading@10 721 AVFilterInOut *inputs, *outputs, *cur;
yading@10 722 int ret, i, init = !fg->graph, simple = !fg->graph_desc;
yading@10 723 const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
yading@10 724 fg->graph_desc;
yading@10 725
yading@10 726 avfilter_graph_free(&fg->graph);
yading@10 727 if (!(fg->graph = avfilter_graph_alloc()))
yading@10 728 return AVERROR(ENOMEM);
yading@10 729
yading@10 730 if (simple) {
yading@10 731 OutputStream *ost = fg->outputs[0]->ost;
yading@10 732 char args[512];
yading@10 733 AVDictionaryEntry *e = NULL;
yading@10 734
yading@10 735 snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
yading@10 736 fg->graph->scale_sws_opts = av_strdup(args);
yading@10 737
yading@10 738 args[0] = 0;
yading@10 739 while ((e = av_dict_get(ost->swr_opts, "", e,
yading@10 740 AV_DICT_IGNORE_SUFFIX))) {
yading@10 741 av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
yading@10 742 }
yading@10 743 if (strlen(args))
yading@10 744 args[strlen(args)-1] = 0;
yading@10 745 av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
yading@10 746
yading@10 747 args[0] = '\0';
yading@10 748 while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
yading@10 749 AV_DICT_IGNORE_SUFFIX))) {
yading@10 750 av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
yading@10 751 }
yading@10 752 if (strlen(args))
yading@10 753 args[strlen(args) - 1] = '\0';
yading@10 754 fg->graph->resample_lavr_opts = av_strdup(args);
yading@10 755 }
yading@10 756
yading@10 757 if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
yading@10 758 return ret;
yading@10 759
yading@10 760 if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
yading@10 761 av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "
yading@10 762 "exactly one input and output.\n", graph_desc);
yading@10 763 return AVERROR(EINVAL);
yading@10 764 }
yading@10 765
yading@10 766 for (cur = inputs; !simple && init && cur; cur = cur->next)
yading@10 767 init_input_filter(fg, cur);
yading@10 768
yading@10 769 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
yading@10 770 if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0)
yading@10 771 return ret;
yading@10 772 avfilter_inout_free(&inputs);
yading@10 773
yading@10 774 if (!init || simple) {
yading@10 775 /* we already know the mappings between lavfi outputs and output streams,
yading@10 776 * so we can finish the setup */
yading@10 777 for (cur = outputs, i = 0; cur; cur = cur->next, i++)
yading@10 778 configure_output_filter(fg, fg->outputs[i], cur);
yading@10 779 avfilter_inout_free(&outputs);
yading@10 780
yading@10 781 if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
yading@10 782 return ret;
yading@10 783 } else {
yading@10 784 /* wait until output mappings are processed */
yading@10 785 for (cur = outputs; cur;) {
yading@10 786 GROW_ARRAY(fg->outputs, fg->nb_outputs);
yading@10 787 if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]))))
yading@10 788 exit(1);
yading@10 789 fg->outputs[fg->nb_outputs - 1]->graph = fg;
yading@10 790 fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
yading@10 791 cur = cur->next;
yading@10 792 fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
yading@10 793 }
yading@10 794 }
yading@10 795
yading@10 796 fg->reconfiguration = 1;
yading@10 797 return 0;
yading@10 798 }
yading@10 799
yading@10 800 int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
yading@10 801 {
yading@10 802 int i;
yading@10 803 for (i = 0; i < fg->nb_inputs; i++)
yading@10 804 if (fg->inputs[i]->ist == ist)
yading@10 805 return 1;
yading@10 806 return 0;
yading@10 807 }
yading@10 808