annotate ffmpeg/libavfilter/avfiltergraph.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 * filter graphs
yading@10 3 * Copyright (c) 2008 Vitor Sessak
yading@10 4 * Copyright (c) 2007 Bobby Bingham
yading@10 5 *
yading@10 6 * This file is part of FFmpeg.
yading@10 7 *
yading@10 8 * FFmpeg is free software; you can redistribute it and/or
yading@10 9 * modify it under the terms of the GNU Lesser General Public
yading@10 10 * License as published by the Free Software Foundation; either
yading@10 11 * version 2.1 of the License, or (at your option) any later version.
yading@10 12 *
yading@10 13 * FFmpeg is distributed in the hope that it will be useful,
yading@10 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 16 * Lesser General Public License for more details.
yading@10 17 *
yading@10 18 * You should have received a copy of the GNU Lesser General Public
yading@10 19 * License along with FFmpeg; if not, write to the Free Software
yading@10 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 21 */
yading@10 22
yading@10 23 #include <string.h>
yading@10 24
yading@10 25 #include "libavutil/avassert.h"
yading@10 26 #include "libavutil/avstring.h"
yading@10 27 #include "libavutil/bprint.h"
yading@10 28 #include "libavutil/channel_layout.h"
yading@10 29 #include "libavutil/opt.h"
yading@10 30 #include "libavutil/pixdesc.h"
yading@10 31 #include "libavcodec/avcodec.h" // avcodec_find_best_pix_fmt_of_2()
yading@10 32 #include "avfilter.h"
yading@10 33 #include "formats.h"
yading@10 34 #include "internal.h"
yading@10 35
yading@10 36 #define OFFSET(x) offsetof(AVFilterGraph,x)
yading@10 37
yading@10 38 static const AVOption options[]={
yading@10 39 {"scale_sws_opts" , "default scale filter options" , OFFSET(scale_sws_opts) , AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, 0 },
yading@10 40 {"aresample_swr_opts" , "default aresample filter options" , OFFSET(aresample_swr_opts) , AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, 0 },
yading@10 41 {0}
yading@10 42 };
yading@10 43
yading@10 44
yading@10 45 static const AVClass filtergraph_class = {
yading@10 46 .class_name = "AVFilterGraph",
yading@10 47 .item_name = av_default_item_name,
yading@10 48 .option = options,
yading@10 49 .version = LIBAVUTIL_VERSION_INT,
yading@10 50 .category = AV_CLASS_CATEGORY_FILTER,
yading@10 51 };
yading@10 52
yading@10 53 AVFilterGraph *avfilter_graph_alloc(void)
yading@10 54 {
yading@10 55 AVFilterGraph *ret = av_mallocz(sizeof(*ret));
yading@10 56 if (!ret)
yading@10 57 return NULL;
yading@10 58 ret->av_class = &filtergraph_class;
yading@10 59 return ret;
yading@10 60 }
yading@10 61
yading@10 62 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
yading@10 63 {
yading@10 64 int i;
yading@10 65 for (i = 0; i < graph->nb_filters; i++) {
yading@10 66 if (graph->filters[i] == filter) {
yading@10 67 FFSWAP(AVFilterContext*, graph->filters[i],
yading@10 68 graph->filters[graph->nb_filters - 1]);
yading@10 69 graph->nb_filters--;
yading@10 70 return;
yading@10 71 }
yading@10 72 }
yading@10 73 }
yading@10 74
yading@10 75 void avfilter_graph_free(AVFilterGraph **graph)
yading@10 76 {
yading@10 77 if (!*graph)
yading@10 78 return;
yading@10 79
yading@10 80 while ((*graph)->nb_filters)
yading@10 81 avfilter_free((*graph)->filters[0]);
yading@10 82
yading@10 83 av_freep(&(*graph)->sink_links);
yading@10 84 av_freep(&(*graph)->scale_sws_opts);
yading@10 85 av_freep(&(*graph)->aresample_swr_opts);
yading@10 86 av_freep(&(*graph)->resample_lavr_opts);
yading@10 87 av_freep(&(*graph)->filters);
yading@10 88 av_freep(graph);
yading@10 89 }
yading@10 90
yading@10 91 #if FF_API_AVFILTER_OPEN
yading@10 92 int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
yading@10 93 {
yading@10 94 AVFilterContext **filters = av_realloc(graph->filters,
yading@10 95 sizeof(*filters) * (graph->nb_filters + 1));
yading@10 96 if (!filters)
yading@10 97 return AVERROR(ENOMEM);
yading@10 98
yading@10 99 graph->filters = filters;
yading@10 100 graph->filters[graph->nb_filters++] = filter;
yading@10 101
yading@10 102 #if FF_API_FOO_COUNT
yading@10 103 graph->filter_count_unused = graph->nb_filters;
yading@10 104 #endif
yading@10 105
yading@10 106 filter->graph = graph;
yading@10 107
yading@10 108 return 0;
yading@10 109 }
yading@10 110 #endif
yading@10 111
yading@10 112 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
yading@10 113 const char *name, const char *args, void *opaque,
yading@10 114 AVFilterGraph *graph_ctx)
yading@10 115 {
yading@10 116 int ret;
yading@10 117
yading@10 118 *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
yading@10 119 if (!*filt_ctx)
yading@10 120 return AVERROR(ENOMEM);
yading@10 121
yading@10 122 ret = avfilter_init_str(*filt_ctx, args);
yading@10 123 if (ret < 0)
yading@10 124 goto fail;
yading@10 125
yading@10 126 return 0;
yading@10 127
yading@10 128 fail:
yading@10 129 if (*filt_ctx)
yading@10 130 avfilter_free(*filt_ctx);
yading@10 131 *filt_ctx = NULL;
yading@10 132 return ret;
yading@10 133 }
yading@10 134
yading@10 135 void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
yading@10 136 {
yading@10 137 graph->disable_auto_convert = flags;
yading@10 138 }
yading@10 139
yading@10 140 AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
yading@10 141 const AVFilter *filter,
yading@10 142 const char *name)
yading@10 143 {
yading@10 144 AVFilterContext **filters, *s;
yading@10 145
yading@10 146 s = ff_filter_alloc(filter, name);
yading@10 147 if (!s)
yading@10 148 return NULL;
yading@10 149
yading@10 150 filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
yading@10 151 if (!filters) {
yading@10 152 avfilter_free(s);
yading@10 153 return NULL;
yading@10 154 }
yading@10 155
yading@10 156 graph->filters = filters;
yading@10 157 graph->filters[graph->nb_filters++] = s;
yading@10 158
yading@10 159 #if FF_API_FOO_COUNT
yading@10 160 graph->filter_count_unused = graph->nb_filters;
yading@10 161 #endif
yading@10 162
yading@10 163 s->graph = graph;
yading@10 164
yading@10 165 return s;
yading@10 166 }
yading@10 167
yading@10 168 /**
yading@10 169 * Check for the validity of graph.
yading@10 170 *
yading@10 171 * A graph is considered valid if all its input and output pads are
yading@10 172 * connected.
yading@10 173 *
yading@10 174 * @return 0 in case of success, a negative value otherwise
yading@10 175 */
yading@10 176 static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
yading@10 177 {
yading@10 178 AVFilterContext *filt;
yading@10 179 int i, j;
yading@10 180
yading@10 181 for (i = 0; i < graph->nb_filters; i++) {
yading@10 182 const AVFilterPad *pad;
yading@10 183 filt = graph->filters[i];
yading@10 184
yading@10 185 for (j = 0; j < filt->nb_inputs; j++) {
yading@10 186 if (!filt->inputs[j] || !filt->inputs[j]->src) {
yading@10 187 pad = &filt->input_pads[j];
yading@10 188 av_log(log_ctx, AV_LOG_ERROR,
yading@10 189 "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n",
yading@10 190 pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
yading@10 191 return AVERROR(EINVAL);
yading@10 192 }
yading@10 193 }
yading@10 194
yading@10 195 for (j = 0; j < filt->nb_outputs; j++) {
yading@10 196 if (!filt->outputs[j] || !filt->outputs[j]->dst) {
yading@10 197 pad = &filt->output_pads[j];
yading@10 198 av_log(log_ctx, AV_LOG_ERROR,
yading@10 199 "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n",
yading@10 200 pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
yading@10 201 return AVERROR(EINVAL);
yading@10 202 }
yading@10 203 }
yading@10 204 }
yading@10 205
yading@10 206 return 0;
yading@10 207 }
yading@10 208
yading@10 209 /**
yading@10 210 * Configure all the links of graphctx.
yading@10 211 *
yading@10 212 * @return 0 in case of success, a negative value otherwise
yading@10 213 */
yading@10 214 static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
yading@10 215 {
yading@10 216 AVFilterContext *filt;
yading@10 217 int i, ret;
yading@10 218
yading@10 219 for (i = 0; i < graph->nb_filters; i++) {
yading@10 220 filt = graph->filters[i];
yading@10 221
yading@10 222 if (!filt->nb_outputs) {
yading@10 223 if ((ret = avfilter_config_links(filt)))
yading@10 224 return ret;
yading@10 225 }
yading@10 226 }
yading@10 227
yading@10 228 return 0;
yading@10 229 }
yading@10 230
yading@10 231 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
yading@10 232 {
yading@10 233 int i;
yading@10 234
yading@10 235 for (i = 0; i < graph->nb_filters; i++)
yading@10 236 if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
yading@10 237 return graph->filters[i];
yading@10 238
yading@10 239 return NULL;
yading@10 240 }
yading@10 241
yading@10 242 static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l)
yading@10 243 {
yading@10 244 if (!l)
yading@10 245 return;
yading@10 246 if (l->nb_channel_layouts) {
yading@10 247 if (l->all_layouts || l->all_counts)
yading@10 248 av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n");
yading@10 249 l->all_layouts = l->all_counts = 0;
yading@10 250 } else {
yading@10 251 if (l->all_counts && !l->all_layouts)
yading@10 252 av_log(log, AV_LOG_WARNING, "All counts without all layouts\n");
yading@10 253 l->all_layouts = 1;
yading@10 254 }
yading@10 255 }
yading@10 256
yading@10 257 static int filter_query_formats(AVFilterContext *ctx)
yading@10 258 {
yading@10 259 int ret, i;
yading@10 260 AVFilterFormats *formats;
yading@10 261 AVFilterChannelLayouts *chlayouts;
yading@10 262 AVFilterFormats *samplerates;
yading@10 263 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
yading@10 264 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
yading@10 265 AVMEDIA_TYPE_VIDEO;
yading@10 266
yading@10 267 if ((ret = ctx->filter->query_formats(ctx)) < 0) {
yading@10 268 if (ret != AVERROR(EAGAIN))
yading@10 269 av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
yading@10 270 ctx->name, av_err2str(ret));
yading@10 271 return ret;
yading@10 272 }
yading@10 273
yading@10 274 for (i = 0; i < ctx->nb_inputs; i++)
yading@10 275 sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
yading@10 276 for (i = 0; i < ctx->nb_outputs; i++)
yading@10 277 sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
yading@10 278
yading@10 279 formats = ff_all_formats(type);
yading@10 280 if (!formats)
yading@10 281 return AVERROR(ENOMEM);
yading@10 282 ff_set_common_formats(ctx, formats);
yading@10 283 if (type == AVMEDIA_TYPE_AUDIO) {
yading@10 284 samplerates = ff_all_samplerates();
yading@10 285 if (!samplerates)
yading@10 286 return AVERROR(ENOMEM);
yading@10 287 ff_set_common_samplerates(ctx, samplerates);
yading@10 288 chlayouts = ff_all_channel_layouts();
yading@10 289 if (!chlayouts)
yading@10 290 return AVERROR(ENOMEM);
yading@10 291 ff_set_common_channel_layouts(ctx, chlayouts);
yading@10 292 }
yading@10 293 return 0;
yading@10 294 }
yading@10 295
yading@10 296 static int formats_declared(AVFilterContext *f)
yading@10 297 {
yading@10 298 int i;
yading@10 299
yading@10 300 for (i = 0; i < f->nb_inputs; i++) {
yading@10 301 if (!f->inputs[i]->out_formats)
yading@10 302 return 0;
yading@10 303 if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
yading@10 304 !(f->inputs[i]->out_samplerates &&
yading@10 305 f->inputs[i]->out_channel_layouts))
yading@10 306 return 0;
yading@10 307 }
yading@10 308 for (i = 0; i < f->nb_outputs; i++) {
yading@10 309 if (!f->outputs[i]->in_formats)
yading@10 310 return 0;
yading@10 311 if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
yading@10 312 !(f->outputs[i]->in_samplerates &&
yading@10 313 f->outputs[i]->in_channel_layouts))
yading@10 314 return 0;
yading@10 315 }
yading@10 316 return 1;
yading@10 317 }
yading@10 318
yading@10 319 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
yading@10 320 {
yading@10 321 int i, j, ret;
yading@10 322 int scaler_count = 0, resampler_count = 0;
yading@10 323 int count_queried = 0, count_merged = 0, count_already_merged = 0,
yading@10 324 count_delayed = 0;
yading@10 325
yading@10 326 for (i = 0; i < graph->nb_filters; i++) {
yading@10 327 AVFilterContext *f = graph->filters[i];
yading@10 328 if (formats_declared(f))
yading@10 329 continue;
yading@10 330 if (f->filter->query_formats)
yading@10 331 ret = filter_query_formats(f);
yading@10 332 else
yading@10 333 ret = ff_default_query_formats(f);
yading@10 334 if (ret < 0 && ret != AVERROR(EAGAIN))
yading@10 335 return ret;
yading@10 336 count_queried++;
yading@10 337 }
yading@10 338
yading@10 339 /* go through and merge as many format lists as possible */
yading@10 340 for (i = 0; i < graph->nb_filters; i++) {
yading@10 341 AVFilterContext *filter = graph->filters[i];
yading@10 342
yading@10 343 for (j = 0; j < filter->nb_inputs; j++) {
yading@10 344 AVFilterLink *link = filter->inputs[j];
yading@10 345 int convert_needed = 0;
yading@10 346
yading@10 347 if (!link)
yading@10 348 continue;
yading@10 349
yading@10 350 #define MERGE_DISPATCH(field, statement) \
yading@10 351 if (!(link->in_ ## field && link->out_ ## field)) { \
yading@10 352 count_delayed++; \
yading@10 353 } else if (link->in_ ## field == link->out_ ## field) { \
yading@10 354 count_already_merged++; \
yading@10 355 } else { \
yading@10 356 count_merged++; \
yading@10 357 statement \
yading@10 358 }
yading@10 359 MERGE_DISPATCH(formats,
yading@10 360 if (!ff_merge_formats(link->in_formats, link->out_formats,
yading@10 361 link->type))
yading@10 362 convert_needed = 1;
yading@10 363 )
yading@10 364 if (link->type == AVMEDIA_TYPE_AUDIO) {
yading@10 365 MERGE_DISPATCH(channel_layouts,
yading@10 366 if (!ff_merge_channel_layouts(link->in_channel_layouts,
yading@10 367 link->out_channel_layouts))
yading@10 368 convert_needed = 1;
yading@10 369 )
yading@10 370 MERGE_DISPATCH(samplerates,
yading@10 371 if (!ff_merge_samplerates(link->in_samplerates,
yading@10 372 link->out_samplerates))
yading@10 373 convert_needed = 1;
yading@10 374 )
yading@10 375 }
yading@10 376 #undef MERGE_DISPATCH
yading@10 377
yading@10 378 if (convert_needed) {
yading@10 379 AVFilterContext *convert;
yading@10 380 AVFilter *filter;
yading@10 381 AVFilterLink *inlink, *outlink;
yading@10 382 char scale_args[256];
yading@10 383 char inst_name[30];
yading@10 384
yading@10 385 /* couldn't merge format lists. auto-insert conversion filter */
yading@10 386 switch (link->type) {
yading@10 387 case AVMEDIA_TYPE_VIDEO:
yading@10 388 if (!(filter = avfilter_get_by_name("scale"))) {
yading@10 389 av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
yading@10 390 "not present, cannot convert pixel formats.\n");
yading@10 391 return AVERROR(EINVAL);
yading@10 392 }
yading@10 393
yading@10 394 snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
yading@10 395 scaler_count++);
yading@10 396 av_strlcpy(scale_args, "0:0", sizeof(scale_args));
yading@10 397 if (graph->scale_sws_opts) {
yading@10 398 av_strlcat(scale_args, ":", sizeof(scale_args));
yading@10 399 av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args));
yading@10 400 }
yading@10 401 if ((ret = avfilter_graph_create_filter(&convert, filter,
yading@10 402 inst_name, scale_args, NULL,
yading@10 403 graph)) < 0)
yading@10 404 return ret;
yading@10 405 break;
yading@10 406 case AVMEDIA_TYPE_AUDIO:
yading@10 407 if (!(filter = avfilter_get_by_name("aresample"))) {
yading@10 408 av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "
yading@10 409 "not present, cannot convert audio formats.\n");
yading@10 410 return AVERROR(EINVAL);
yading@10 411 }
yading@10 412
yading@10 413 snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
yading@10 414 resampler_count++);
yading@10 415 scale_args[0] = '\0';
yading@10 416 if (graph->aresample_swr_opts)
yading@10 417 snprintf(scale_args, sizeof(scale_args), "%s",
yading@10 418 graph->aresample_swr_opts);
yading@10 419 if ((ret = avfilter_graph_create_filter(&convert, filter,
yading@10 420 inst_name, graph->aresample_swr_opts,
yading@10 421 NULL, graph)) < 0)
yading@10 422 return ret;
yading@10 423 break;
yading@10 424 default:
yading@10 425 return AVERROR(EINVAL);
yading@10 426 }
yading@10 427
yading@10 428 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
yading@10 429 return ret;
yading@10 430
yading@10 431 filter_query_formats(convert);
yading@10 432 inlink = convert->inputs[0];
yading@10 433 outlink = convert->outputs[0];
yading@10 434 if (!ff_merge_formats( inlink->in_formats, inlink->out_formats, inlink->type) ||
yading@10 435 !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
yading@10 436 ret |= AVERROR(ENOSYS);
yading@10 437 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
yading@10 438 (!ff_merge_samplerates(inlink->in_samplerates,
yading@10 439 inlink->out_samplerates) ||
yading@10 440 !ff_merge_channel_layouts(inlink->in_channel_layouts,
yading@10 441 inlink->out_channel_layouts)))
yading@10 442 ret |= AVERROR(ENOSYS);
yading@10 443 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
yading@10 444 (!ff_merge_samplerates(outlink->in_samplerates,
yading@10 445 outlink->out_samplerates) ||
yading@10 446 !ff_merge_channel_layouts(outlink->in_channel_layouts,
yading@10 447 outlink->out_channel_layouts)))
yading@10 448 ret |= AVERROR(ENOSYS);
yading@10 449
yading@10 450 if (ret < 0) {
yading@10 451 av_log(log_ctx, AV_LOG_ERROR,
yading@10 452 "Impossible to convert between the formats supported by the filter "
yading@10 453 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
yading@10 454 return ret;
yading@10 455 }
yading@10 456 }
yading@10 457 }
yading@10 458 }
yading@10 459
yading@10 460 av_log(graph, AV_LOG_DEBUG, "query_formats: "
yading@10 461 "%d queried, %d merged, %d already done, %d delayed\n",
yading@10 462 count_queried, count_merged, count_already_merged, count_delayed);
yading@10 463 if (count_delayed) {
yading@10 464 AVBPrint bp;
yading@10 465
yading@10 466 if (count_queried || count_merged)
yading@10 467 return AVERROR(EAGAIN);
yading@10 468 av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
yading@10 469 for (i = 0; i < graph->nb_filters; i++)
yading@10 470 if (!formats_declared(graph->filters[i]))
yading@10 471 av_bprintf(&bp, "%s%s", bp.len ? ", " : "",
yading@10 472 graph->filters[i]->name);
yading@10 473 av_log(graph, AV_LOG_ERROR,
yading@10 474 "The following filters could not choose their formats: %s\n"
yading@10 475 "Consider inserting the (a)format filter near their input or "
yading@10 476 "output.\n", bp.str);
yading@10 477 return AVERROR(EIO);
yading@10 478 }
yading@10 479 return 0;
yading@10 480 }
yading@10 481
yading@10 482 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
yading@10 483 {
yading@10 484 if (!link || !link->in_formats)
yading@10 485 return 0;
yading@10 486
yading@10 487 if (link->type == AVMEDIA_TYPE_VIDEO) {
yading@10 488 if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
yading@10 489 int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
yading@10 490 enum AVPixelFormat best= AV_PIX_FMT_NONE;
yading@10 491 int i;
yading@10 492 for (i=0; i<link->in_formats->format_count; i++) {
yading@10 493 enum AVPixelFormat p = link->in_formats->formats[i];
yading@10 494 best= avcodec_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
yading@10 495 }
yading@10 496 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
yading@10 497 av_get_pix_fmt_name(best), link->in_formats->format_count,
yading@10 498 av_get_pix_fmt_name(ref->format), has_alpha);
yading@10 499 link->in_formats->formats[0] = best;
yading@10 500 }
yading@10 501 }
yading@10 502
yading@10 503 link->in_formats->format_count = 1;
yading@10 504 link->format = link->in_formats->formats[0];
yading@10 505
yading@10 506 if (link->type == AVMEDIA_TYPE_AUDIO) {
yading@10 507 if (!link->in_samplerates->format_count) {
yading@10 508 av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
yading@10 509 " the link between filters %s and %s.\n", link->src->name,
yading@10 510 link->dst->name);
yading@10 511 return AVERROR(EINVAL);
yading@10 512 }
yading@10 513 link->in_samplerates->format_count = 1;
yading@10 514 link->sample_rate = link->in_samplerates->formats[0];
yading@10 515
yading@10 516 if (link->in_channel_layouts->all_layouts) {
yading@10 517 av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
yading@10 518 " the link between filters %s and %s.\n", link->src->name,
yading@10 519 link->dst->name);
yading@10 520 return AVERROR(EINVAL);
yading@10 521 }
yading@10 522 link->in_channel_layouts->nb_channel_layouts = 1;
yading@10 523 link->channel_layout = link->in_channel_layouts->channel_layouts[0];
yading@10 524 if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout)))
yading@10 525 link->channel_layout = 0;
yading@10 526 else
yading@10 527 link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
yading@10 528 }
yading@10 529
yading@10 530 ff_formats_unref(&link->in_formats);
yading@10 531 ff_formats_unref(&link->out_formats);
yading@10 532 ff_formats_unref(&link->in_samplerates);
yading@10 533 ff_formats_unref(&link->out_samplerates);
yading@10 534 ff_channel_layouts_unref(&link->in_channel_layouts);
yading@10 535 ff_channel_layouts_unref(&link->out_channel_layouts);
yading@10 536
yading@10 537 return 0;
yading@10 538 }
yading@10 539
yading@10 540 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
yading@10 541 do { \
yading@10 542 for (i = 0; i < filter->nb_inputs; i++) { \
yading@10 543 AVFilterLink *link = filter->inputs[i]; \
yading@10 544 fmt_type fmt; \
yading@10 545 \
yading@10 546 if (!link->out_ ## list || link->out_ ## list->nb != 1) \
yading@10 547 continue; \
yading@10 548 fmt = link->out_ ## list->var[0]; \
yading@10 549 \
yading@10 550 for (j = 0; j < filter->nb_outputs; j++) { \
yading@10 551 AVFilterLink *out_link = filter->outputs[j]; \
yading@10 552 list_type *fmts; \
yading@10 553 \
yading@10 554 if (link->type != out_link->type || \
yading@10 555 out_link->in_ ## list->nb == 1) \
yading@10 556 continue; \
yading@10 557 fmts = out_link->in_ ## list; \
yading@10 558 \
yading@10 559 if (!out_link->in_ ## list->nb) { \
yading@10 560 add_format(&out_link->in_ ##list, fmt); \
yading@10 561 break; \
yading@10 562 } \
yading@10 563 \
yading@10 564 for (k = 0; k < out_link->in_ ## list->nb; k++) \
yading@10 565 if (fmts->var[k] == fmt) { \
yading@10 566 fmts->var[0] = fmt; \
yading@10 567 fmts->nb = 1; \
yading@10 568 ret = 1; \
yading@10 569 break; \
yading@10 570 } \
yading@10 571 } \
yading@10 572 } \
yading@10 573 } while (0)
yading@10 574
yading@10 575 static int reduce_formats_on_filter(AVFilterContext *filter)
yading@10 576 {
yading@10 577 int i, j, k, ret = 0;
yading@10 578
yading@10 579 REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
yading@10 580 format_count, ff_add_format);
yading@10 581 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
yading@10 582 format_count, ff_add_format);
yading@10 583
yading@10 584 /* reduce channel layouts */
yading@10 585 for (i = 0; i < filter->nb_inputs; i++) {
yading@10 586 AVFilterLink *inlink = filter->inputs[i];
yading@10 587 uint64_t fmt;
yading@10 588
yading@10 589 if (!inlink->out_channel_layouts ||
yading@10 590 inlink->out_channel_layouts->nb_channel_layouts != 1)
yading@10 591 continue;
yading@10 592 fmt = inlink->out_channel_layouts->channel_layouts[0];
yading@10 593
yading@10 594 for (j = 0; j < filter->nb_outputs; j++) {
yading@10 595 AVFilterLink *outlink = filter->outputs[j];
yading@10 596 AVFilterChannelLayouts *fmts;
yading@10 597
yading@10 598 fmts = outlink->in_channel_layouts;
yading@10 599 if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
yading@10 600 continue;
yading@10 601
yading@10 602 if (fmts->all_layouts) {
yading@10 603 /* Turn the infinite list into a singleton */
yading@10 604 fmts->all_layouts = fmts->all_counts = 0;
yading@10 605 ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
yading@10 606 break;
yading@10 607 }
yading@10 608
yading@10 609 for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
yading@10 610 if (fmts->channel_layouts[k] == fmt) {
yading@10 611 fmts->channel_layouts[0] = fmt;
yading@10 612 fmts->nb_channel_layouts = 1;
yading@10 613 ret = 1;
yading@10 614 break;
yading@10 615 }
yading@10 616 }
yading@10 617 }
yading@10 618 }
yading@10 619
yading@10 620 return ret;
yading@10 621 }
yading@10 622
yading@10 623 static void reduce_formats(AVFilterGraph *graph)
yading@10 624 {
yading@10 625 int i, reduced;
yading@10 626
yading@10 627 do {
yading@10 628 reduced = 0;
yading@10 629
yading@10 630 for (i = 0; i < graph->nb_filters; i++)
yading@10 631 reduced |= reduce_formats_on_filter(graph->filters[i]);
yading@10 632 } while (reduced);
yading@10 633 }
yading@10 634
yading@10 635 static void swap_samplerates_on_filter(AVFilterContext *filter)
yading@10 636 {
yading@10 637 AVFilterLink *link = NULL;
yading@10 638 int sample_rate;
yading@10 639 int i, j;
yading@10 640
yading@10 641 for (i = 0; i < filter->nb_inputs; i++) {
yading@10 642 link = filter->inputs[i];
yading@10 643
yading@10 644 if (link->type == AVMEDIA_TYPE_AUDIO &&
yading@10 645 link->out_samplerates->format_count == 1)
yading@10 646 break;
yading@10 647 }
yading@10 648 if (i == filter->nb_inputs)
yading@10 649 return;
yading@10 650
yading@10 651 sample_rate = link->out_samplerates->formats[0];
yading@10 652
yading@10 653 for (i = 0; i < filter->nb_outputs; i++) {
yading@10 654 AVFilterLink *outlink = filter->outputs[i];
yading@10 655 int best_idx, best_diff = INT_MAX;
yading@10 656
yading@10 657 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
yading@10 658 outlink->in_samplerates->format_count < 2)
yading@10 659 continue;
yading@10 660
yading@10 661 for (j = 0; j < outlink->in_samplerates->format_count; j++) {
yading@10 662 int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
yading@10 663
yading@10 664 if (diff < best_diff) {
yading@10 665 best_diff = diff;
yading@10 666 best_idx = j;
yading@10 667 }
yading@10 668 }
yading@10 669 FFSWAP(int, outlink->in_samplerates->formats[0],
yading@10 670 outlink->in_samplerates->formats[best_idx]);
yading@10 671 }
yading@10 672 }
yading@10 673
yading@10 674 static void swap_samplerates(AVFilterGraph *graph)
yading@10 675 {
yading@10 676 int i;
yading@10 677
yading@10 678 for (i = 0; i < graph->nb_filters; i++)
yading@10 679 swap_samplerates_on_filter(graph->filters[i]);
yading@10 680 }
yading@10 681
yading@10 682 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
yading@10 683 #define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)
yading@10 684 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)
yading@10 685 #define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)
yading@10 686 #define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)
yading@10 687 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
yading@10 688 #define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
yading@10 689
yading@10 690 /* allowable substitutions for channel pairs when comparing layouts,
yading@10 691 * ordered by priority for both values */
yading@10 692 static const uint64_t ch_subst[][2] = {
yading@10 693 { CH_FRONT_PAIR, CH_CENTER_PAIR },
yading@10 694 { CH_FRONT_PAIR, CH_WIDE_PAIR },
yading@10 695 { CH_FRONT_PAIR, AV_CH_FRONT_CENTER },
yading@10 696 { CH_CENTER_PAIR, CH_FRONT_PAIR },
yading@10 697 { CH_CENTER_PAIR, CH_WIDE_PAIR },
yading@10 698 { CH_CENTER_PAIR, AV_CH_FRONT_CENTER },
yading@10 699 { CH_WIDE_PAIR, CH_FRONT_PAIR },
yading@10 700 { CH_WIDE_PAIR, CH_CENTER_PAIR },
yading@10 701 { CH_WIDE_PAIR, AV_CH_FRONT_CENTER },
yading@10 702 { AV_CH_FRONT_CENTER, CH_FRONT_PAIR },
yading@10 703 { AV_CH_FRONT_CENTER, CH_CENTER_PAIR },
yading@10 704 { AV_CH_FRONT_CENTER, CH_WIDE_PAIR },
yading@10 705 { CH_SIDE_PAIR, CH_DIRECT_PAIR },
yading@10 706 { CH_SIDE_PAIR, CH_BACK_PAIR },
yading@10 707 { CH_SIDE_PAIR, AV_CH_BACK_CENTER },
yading@10 708 { CH_BACK_PAIR, CH_DIRECT_PAIR },
yading@10 709 { CH_BACK_PAIR, CH_SIDE_PAIR },
yading@10 710 { CH_BACK_PAIR, AV_CH_BACK_CENTER },
yading@10 711 { AV_CH_BACK_CENTER, CH_BACK_PAIR },
yading@10 712 { AV_CH_BACK_CENTER, CH_DIRECT_PAIR },
yading@10 713 { AV_CH_BACK_CENTER, CH_SIDE_PAIR },
yading@10 714 };
yading@10 715
yading@10 716 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
yading@10 717 {
yading@10 718 AVFilterLink *link = NULL;
yading@10 719 int i, j, k;
yading@10 720
yading@10 721 for (i = 0; i < filter->nb_inputs; i++) {
yading@10 722 link = filter->inputs[i];
yading@10 723
yading@10 724 if (link->type == AVMEDIA_TYPE_AUDIO &&
yading@10 725 link->out_channel_layouts->nb_channel_layouts == 1)
yading@10 726 break;
yading@10 727 }
yading@10 728 if (i == filter->nb_inputs)
yading@10 729 return;
yading@10 730
yading@10 731 for (i = 0; i < filter->nb_outputs; i++) {
yading@10 732 AVFilterLink *outlink = filter->outputs[i];
yading@10 733 int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
yading@10 734
yading@10 735 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
yading@10 736 outlink->in_channel_layouts->nb_channel_layouts < 2)
yading@10 737 continue;
yading@10 738
yading@10 739 for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
yading@10 740 uint64_t in_chlayout = link->out_channel_layouts->channel_layouts[0];
yading@10 741 uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
yading@10 742 int in_channels = av_get_channel_layout_nb_channels(in_chlayout);
yading@10 743 int out_channels = av_get_channel_layout_nb_channels(out_chlayout);
yading@10 744 int count_diff = out_channels - in_channels;
yading@10 745 int matched_channels, extra_channels;
yading@10 746 int score = 100000;
yading@10 747
yading@10 748 if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) {
yading@10 749 /* Compute score in case the input or output layout encodes
yading@10 750 a channel count; in this case the score is not altered by
yading@10 751 the computation afterwards, as in_chlayout and
yading@10 752 out_chlayout have both been set to 0 */
yading@10 753 if (FF_LAYOUT2COUNT(in_chlayout))
yading@10 754 in_channels = FF_LAYOUT2COUNT(in_chlayout);
yading@10 755 if (FF_LAYOUT2COUNT(out_chlayout))
yading@10 756 out_channels = FF_LAYOUT2COUNT(out_chlayout);
yading@10 757 score -= 10000 + FFABS(out_channels - in_channels) +
yading@10 758 (in_channels > out_channels ? 10000 : 0);
yading@10 759 in_chlayout = out_chlayout = 0;
yading@10 760 /* Let the remaining computation run, even if the score
yading@10 761 value is not altered */
yading@10 762 }
yading@10 763
yading@10 764 /* channel substitution */
yading@10 765 for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
yading@10 766 uint64_t cmp0 = ch_subst[k][0];
yading@10 767 uint64_t cmp1 = ch_subst[k][1];
yading@10 768 if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
yading@10 769 (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
yading@10 770 in_chlayout &= ~cmp0;
yading@10 771 out_chlayout &= ~cmp1;
yading@10 772 /* add score for channel match, minus a deduction for
yading@10 773 having to do the substitution */
yading@10 774 score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
yading@10 775 }
yading@10 776 }
yading@10 777
yading@10 778 /* no penalty for LFE channel mismatch */
yading@10 779 if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
yading@10 780 (out_chlayout & AV_CH_LOW_FREQUENCY))
yading@10 781 score += 10;
yading@10 782 in_chlayout &= ~AV_CH_LOW_FREQUENCY;
yading@10 783 out_chlayout &= ~AV_CH_LOW_FREQUENCY;
yading@10 784
yading@10 785 matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
yading@10 786 out_chlayout);
yading@10 787 extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
yading@10 788 (~in_chlayout));
yading@10 789 score += 10 * matched_channels - 5 * extra_channels;
yading@10 790
yading@10 791 if (score > best_score ||
yading@10 792 (count_diff < best_count_diff && score == best_score)) {
yading@10 793 best_score = score;
yading@10 794 best_idx = j;
yading@10 795 best_count_diff = count_diff;
yading@10 796 }
yading@10 797 }
yading@10 798 av_assert0(best_idx >= 0);
yading@10 799 FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
yading@10 800 outlink->in_channel_layouts->channel_layouts[best_idx]);
yading@10 801 }
yading@10 802
yading@10 803 }
yading@10 804
yading@10 805 static void swap_channel_layouts(AVFilterGraph *graph)
yading@10 806 {
yading@10 807 int i;
yading@10 808
yading@10 809 for (i = 0; i < graph->nb_filters; i++)
yading@10 810 swap_channel_layouts_on_filter(graph->filters[i]);
yading@10 811 }
yading@10 812
yading@10 813 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
yading@10 814 {
yading@10 815 AVFilterLink *link = NULL;
yading@10 816 int format, bps;
yading@10 817 int i, j;
yading@10 818
yading@10 819 for (i = 0; i < filter->nb_inputs; i++) {
yading@10 820 link = filter->inputs[i];
yading@10 821
yading@10 822 if (link->type == AVMEDIA_TYPE_AUDIO &&
yading@10 823 link->out_formats->format_count == 1)
yading@10 824 break;
yading@10 825 }
yading@10 826 if (i == filter->nb_inputs)
yading@10 827 return;
yading@10 828
yading@10 829 format = link->out_formats->formats[0];
yading@10 830 bps = av_get_bytes_per_sample(format);
yading@10 831
yading@10 832 for (i = 0; i < filter->nb_outputs; i++) {
yading@10 833 AVFilterLink *outlink = filter->outputs[i];
yading@10 834 int best_idx = -1, best_score = INT_MIN;
yading@10 835
yading@10 836 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
yading@10 837 outlink->in_formats->format_count < 2)
yading@10 838 continue;
yading@10 839
yading@10 840 for (j = 0; j < outlink->in_formats->format_count; j++) {
yading@10 841 int out_format = outlink->in_formats->formats[j];
yading@10 842 int out_bps = av_get_bytes_per_sample(out_format);
yading@10 843 int score;
yading@10 844
yading@10 845 if (av_get_packed_sample_fmt(out_format) == format ||
yading@10 846 av_get_planar_sample_fmt(out_format) == format) {
yading@10 847 best_idx = j;
yading@10 848 break;
yading@10 849 }
yading@10 850
yading@10 851 /* for s32 and float prefer double to prevent loss of information */
yading@10 852 if (bps == 4 && out_bps == 8) {
yading@10 853 best_idx = j;
yading@10 854 break;
yading@10 855 }
yading@10 856
yading@10 857 /* prefer closest higher or equal bps */
yading@10 858 score = -abs(out_bps - bps);
yading@10 859 if (out_bps >= bps)
yading@10 860 score += INT_MAX/2;
yading@10 861
yading@10 862 if (score > best_score) {
yading@10 863 best_score = score;
yading@10 864 best_idx = j;
yading@10 865 }
yading@10 866 }
yading@10 867 av_assert0(best_idx >= 0);
yading@10 868 FFSWAP(int, outlink->in_formats->formats[0],
yading@10 869 outlink->in_formats->formats[best_idx]);
yading@10 870 }
yading@10 871 }
yading@10 872
yading@10 873 static void swap_sample_fmts(AVFilterGraph *graph)
yading@10 874 {
yading@10 875 int i;
yading@10 876
yading@10 877 for (i = 0; i < graph->nb_filters; i++)
yading@10 878 swap_sample_fmts_on_filter(graph->filters[i]);
yading@10 879
yading@10 880 }
yading@10 881
yading@10 882 static int pick_formats(AVFilterGraph *graph)
yading@10 883 {
yading@10 884 int i, j, ret;
yading@10 885 int change;
yading@10 886
yading@10 887 do{
yading@10 888 change = 0;
yading@10 889 for (i = 0; i < graph->nb_filters; i++) {
yading@10 890 AVFilterContext *filter = graph->filters[i];
yading@10 891 if (filter->nb_inputs){
yading@10 892 for (j = 0; j < filter->nb_inputs; j++){
yading@10 893 if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) {
yading@10 894 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
yading@10 895 return ret;
yading@10 896 change = 1;
yading@10 897 }
yading@10 898 }
yading@10 899 }
yading@10 900 if (filter->nb_outputs){
yading@10 901 for (j = 0; j < filter->nb_outputs; j++){
yading@10 902 if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) {
yading@10 903 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
yading@10 904 return ret;
yading@10 905 change = 1;
yading@10 906 }
yading@10 907 }
yading@10 908 }
yading@10 909 if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
yading@10 910 for (j = 0; j < filter->nb_outputs; j++) {
yading@10 911 if(filter->outputs[j]->format<0) {
yading@10 912 if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
yading@10 913 return ret;
yading@10 914 change = 1;
yading@10 915 }
yading@10 916 }
yading@10 917 }
yading@10 918 }
yading@10 919 }while(change);
yading@10 920
yading@10 921 for (i = 0; i < graph->nb_filters; i++) {
yading@10 922 AVFilterContext *filter = graph->filters[i];
yading@10 923
yading@10 924 for (j = 0; j < filter->nb_inputs; j++)
yading@10 925 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
yading@10 926 return ret;
yading@10 927 for (j = 0; j < filter->nb_outputs; j++)
yading@10 928 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
yading@10 929 return ret;
yading@10 930 }
yading@10 931 return 0;
yading@10 932 }
yading@10 933
yading@10 934 /**
yading@10 935 * Configure the formats of all the links in the graph.
yading@10 936 */
yading@10 937 static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
yading@10 938 {
yading@10 939 int ret;
yading@10 940
yading@10 941 /* find supported formats from sub-filters, and merge along links */
yading@10 942 while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
yading@10 943 av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
yading@10 944 if (ret < 0)
yading@10 945 return ret;
yading@10 946
yading@10 947 /* Once everything is merged, it's possible that we'll still have
yading@10 948 * multiple valid media format choices. We try to minimize the amount
yading@10 949 * of format conversion inside filters */
yading@10 950 reduce_formats(graph);
yading@10 951
yading@10 952 /* for audio filters, ensure the best format, sample rate and channel layout
yading@10 953 * is selected */
yading@10 954 swap_sample_fmts(graph);
yading@10 955 swap_samplerates(graph);
yading@10 956 swap_channel_layouts(graph);
yading@10 957
yading@10 958 if ((ret = pick_formats(graph)) < 0)
yading@10 959 return ret;
yading@10 960
yading@10 961 return 0;
yading@10 962 }
yading@10 963
yading@10 964 static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph,
yading@10 965 AVClass *log_ctx)
yading@10 966 {
yading@10 967 unsigned i, j;
yading@10 968 int sink_links_count = 0, n = 0;
yading@10 969 AVFilterContext *f;
yading@10 970 AVFilterLink **sinks;
yading@10 971
yading@10 972 for (i = 0; i < graph->nb_filters; i++) {
yading@10 973 f = graph->filters[i];
yading@10 974 for (j = 0; j < f->nb_inputs; j++) {
yading@10 975 f->inputs[j]->graph = graph;
yading@10 976 f->inputs[j]->age_index = -1;
yading@10 977 }
yading@10 978 for (j = 0; j < f->nb_outputs; j++) {
yading@10 979 f->outputs[j]->graph = graph;
yading@10 980 f->outputs[j]->age_index= -1;
yading@10 981 }
yading@10 982 if (!f->nb_outputs) {
yading@10 983 if (f->nb_inputs > INT_MAX - sink_links_count)
yading@10 984 return AVERROR(EINVAL);
yading@10 985 sink_links_count += f->nb_inputs;
yading@10 986 }
yading@10 987 }
yading@10 988 sinks = av_calloc(sink_links_count, sizeof(*sinks));
yading@10 989 if (!sinks)
yading@10 990 return AVERROR(ENOMEM);
yading@10 991 for (i = 0; i < graph->nb_filters; i++) {
yading@10 992 f = graph->filters[i];
yading@10 993 if (!f->nb_outputs) {
yading@10 994 for (j = 0; j < f->nb_inputs; j++) {
yading@10 995 sinks[n] = f->inputs[j];
yading@10 996 f->inputs[j]->age_index = n++;
yading@10 997 }
yading@10 998 }
yading@10 999 }
yading@10 1000 av_assert0(n == sink_links_count);
yading@10 1001 graph->sink_links = sinks;
yading@10 1002 graph->sink_links_count = sink_links_count;
yading@10 1003 return 0;
yading@10 1004 }
yading@10 1005
yading@10 1006 static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
yading@10 1007 {
yading@10 1008 AVFilterContext *f;
yading@10 1009 int i, j, ret;
yading@10 1010 int fifo_count = 0;
yading@10 1011
yading@10 1012 for (i = 0; i < graph->nb_filters; i++) {
yading@10 1013 f = graph->filters[i];
yading@10 1014
yading@10 1015 for (j = 0; j < f->nb_inputs; j++) {
yading@10 1016 AVFilterLink *link = f->inputs[j];
yading@10 1017 AVFilterContext *fifo_ctx;
yading@10 1018 AVFilter *fifo;
yading@10 1019 char name[32];
yading@10 1020
yading@10 1021 if (!link->dstpad->needs_fifo)
yading@10 1022 continue;
yading@10 1023
yading@10 1024 fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
yading@10 1025 avfilter_get_by_name("fifo") :
yading@10 1026 avfilter_get_by_name("afifo");
yading@10 1027
yading@10 1028 snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
yading@10 1029
yading@10 1030 ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
yading@10 1031 NULL, graph);
yading@10 1032 if (ret < 0)
yading@10 1033 return ret;
yading@10 1034
yading@10 1035 ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
yading@10 1036 if (ret < 0)
yading@10 1037 return ret;
yading@10 1038 }
yading@10 1039 }
yading@10 1040
yading@10 1041 return 0;
yading@10 1042 }
yading@10 1043
yading@10 1044 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
yading@10 1045 {
yading@10 1046 int ret;
yading@10 1047
yading@10 1048 if ((ret = graph_check_validity(graphctx, log_ctx)))
yading@10 1049 return ret;
yading@10 1050 if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
yading@10 1051 return ret;
yading@10 1052 if ((ret = graph_config_formats(graphctx, log_ctx)))
yading@10 1053 return ret;
yading@10 1054 if ((ret = graph_config_links(graphctx, log_ctx)))
yading@10 1055 return ret;
yading@10 1056 if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
yading@10 1057 return ret;
yading@10 1058
yading@10 1059 return 0;
yading@10 1060 }
yading@10 1061
yading@10 1062 int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
yading@10 1063 {
yading@10 1064 int i, r = AVERROR(ENOSYS);
yading@10 1065
yading@10 1066 if(!graph)
yading@10 1067 return r;
yading@10 1068
yading@10 1069 if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
yading@10 1070 r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
yading@10 1071 if(r != AVERROR(ENOSYS))
yading@10 1072 return r;
yading@10 1073 }
yading@10 1074
yading@10 1075 if(res_len && res)
yading@10 1076 res[0]= 0;
yading@10 1077
yading@10 1078 for (i = 0; i < graph->nb_filters; i++) {
yading@10 1079 AVFilterContext *filter = graph->filters[i];
yading@10 1080 if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){
yading@10 1081 r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
yading@10 1082 if(r != AVERROR(ENOSYS)) {
yading@10 1083 if((flags & AVFILTER_CMD_FLAG_ONE) || r<0)
yading@10 1084 return r;
yading@10 1085 }
yading@10 1086 }
yading@10 1087 }
yading@10 1088
yading@10 1089 return r;
yading@10 1090 }
yading@10 1091
yading@10 1092 int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
yading@10 1093 {
yading@10 1094 int i;
yading@10 1095
yading@10 1096 if(!graph)
yading@10 1097 return 0;
yading@10 1098
yading@10 1099 for (i = 0; i < graph->nb_filters; i++) {
yading@10 1100 AVFilterContext *filter = graph->filters[i];
yading@10 1101 if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
yading@10 1102 AVFilterCommand **queue = &filter->command_queue, *next;
yading@10 1103 while (*queue && (*queue)->time <= ts)
yading@10 1104 queue = &(*queue)->next;
yading@10 1105 next = *queue;
yading@10 1106 *queue = av_mallocz(sizeof(AVFilterCommand));
yading@10 1107 (*queue)->command = av_strdup(command);
yading@10 1108 (*queue)->arg = av_strdup(arg);
yading@10 1109 (*queue)->time = ts;
yading@10 1110 (*queue)->flags = flags;
yading@10 1111 (*queue)->next = next;
yading@10 1112 if(flags & AVFILTER_CMD_FLAG_ONE)
yading@10 1113 return 0;
yading@10 1114 }
yading@10 1115 }
yading@10 1116
yading@10 1117 return 0;
yading@10 1118 }
yading@10 1119
yading@10 1120 static void heap_bubble_up(AVFilterGraph *graph,
yading@10 1121 AVFilterLink *link, int index)
yading@10 1122 {
yading@10 1123 AVFilterLink **links = graph->sink_links;
yading@10 1124
yading@10 1125 while (index) {
yading@10 1126 int parent = (index - 1) >> 1;
yading@10 1127 if (links[parent]->current_pts >= link->current_pts)
yading@10 1128 break;
yading@10 1129 links[index] = links[parent];
yading@10 1130 links[index]->age_index = index;
yading@10 1131 index = parent;
yading@10 1132 }
yading@10 1133 links[index] = link;
yading@10 1134 link->age_index = index;
yading@10 1135 }
yading@10 1136
yading@10 1137 static void heap_bubble_down(AVFilterGraph *graph,
yading@10 1138 AVFilterLink *link, int index)
yading@10 1139 {
yading@10 1140 AVFilterLink **links = graph->sink_links;
yading@10 1141
yading@10 1142 while (1) {
yading@10 1143 int child = 2 * index + 1;
yading@10 1144 if (child >= graph->sink_links_count)
yading@10 1145 break;
yading@10 1146 if (child + 1 < graph->sink_links_count &&
yading@10 1147 links[child + 1]->current_pts < links[child]->current_pts)
yading@10 1148 child++;
yading@10 1149 if (link->current_pts < links[child]->current_pts)
yading@10 1150 break;
yading@10 1151 links[index] = links[child];
yading@10 1152 links[index]->age_index = index;
yading@10 1153 index = child;
yading@10 1154 }
yading@10 1155 links[index] = link;
yading@10 1156 link->age_index = index;
yading@10 1157 }
yading@10 1158
yading@10 1159 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
yading@10 1160 {
yading@10 1161 heap_bubble_up (graph, link, link->age_index);
yading@10 1162 heap_bubble_down(graph, link, link->age_index);
yading@10 1163 }
yading@10 1164
yading@10 1165
yading@10 1166 int avfilter_graph_request_oldest(AVFilterGraph *graph)
yading@10 1167 {
yading@10 1168 while (graph->sink_links_count) {
yading@10 1169 AVFilterLink *oldest = graph->sink_links[0];
yading@10 1170 int r = ff_request_frame(oldest);
yading@10 1171 if (r != AVERROR_EOF)
yading@10 1172 return r;
yading@10 1173 av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
yading@10 1174 oldest->dst ? oldest->dst->name : "unknown",
yading@10 1175 oldest->dstpad ? oldest->dstpad->name : "unknown");
yading@10 1176 /* EOF: remove the link from the heap */
yading@10 1177 if (oldest->age_index < --graph->sink_links_count)
yading@10 1178 heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
yading@10 1179 oldest->age_index);
yading@10 1180 oldest->age_index = -1;
yading@10 1181 }
yading@10 1182 return AVERROR_EOF;
yading@10 1183 }