00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <ctype.h>
00024 #include <string.h>
00025
00026 #include "libavutil/audioconvert.h"
00027 #include "libavutil/avassert.h"
00028 #include "libavutil/pixdesc.h"
00029 #include "libavcodec/avcodec.h"
00030 #include "avfilter.h"
00031 #include "avfiltergraph.h"
00032 #include "formats.h"
00033 #include "internal.h"
00034
00035 #include "libavutil/audioconvert.h"
00036 #include "libavutil/avassert.h"
00037 #include "libavutil/common.h"
00038 #include "libavutil/log.h"
00039
00040 static const AVClass filtergraph_class = {
00041 .class_name = "AVFilterGraph",
00042 .item_name = av_default_item_name,
00043 .version = LIBAVUTIL_VERSION_INT,
00044 .category = AV_CLASS_CATEGORY_FILTER,
00045 };
00046
00047 AVFilterGraph *avfilter_graph_alloc(void)
00048 {
00049 AVFilterGraph *ret = av_mallocz(sizeof(AVFilterGraph));
00050 if (!ret)
00051 return NULL;
00052 ret->av_class = &filtergraph_class;
00053 return ret;
00054 }
00055
00056 void avfilter_graph_free(AVFilterGraph **graph)
00057 {
00058 if (!*graph)
00059 return;
00060 for (; (*graph)->filter_count > 0; (*graph)->filter_count--)
00061 avfilter_free((*graph)->filters[(*graph)->filter_count - 1]);
00062 av_freep(&(*graph)->sink_links);
00063 av_freep(&(*graph)->scale_sws_opts);
00064 av_freep(&(*graph)->filters);
00065 av_freep(graph);
00066 }
00067
00068 int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
00069 {
00070 AVFilterContext **filters = av_realloc(graph->filters,
00071 sizeof(AVFilterContext*) * (graph->filter_count+1));
00072 if (!filters)
00073 return AVERROR(ENOMEM);
00074
00075 graph->filters = filters;
00076 graph->filters[graph->filter_count++] = filter;
00077
00078 return 0;
00079 }
00080
00081 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
00082 const char *name, const char *args, void *opaque,
00083 AVFilterGraph *graph_ctx)
00084 {
00085 int ret;
00086
00087 if ((ret = avfilter_open(filt_ctx, filt, name)) < 0)
00088 goto fail;
00089 if ((ret = avfilter_init_filter(*filt_ctx, args, opaque)) < 0)
00090 goto fail;
00091 if ((ret = avfilter_graph_add_filter(graph_ctx, *filt_ctx)) < 0)
00092 goto fail;
00093 return 0;
00094
00095 fail:
00096 if (*filt_ctx)
00097 avfilter_free(*filt_ctx);
00098 *filt_ctx = NULL;
00099 return ret;
00100 }
00101
00102 void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
00103 {
00104 graph->disable_auto_convert = flags;
00105 }
00106
00115 static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
00116 {
00117 AVFilterContext *filt;
00118 int i, j;
00119
00120 for (i = 0; i < graph->filter_count; i++) {
00121 filt = graph->filters[i];
00122
00123 for (j = 0; j < filt->nb_inputs; j++) {
00124 if (!filt->inputs[j] || !filt->inputs[j]->src) {
00125 av_log(log_ctx, AV_LOG_ERROR,
00126 "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
00127 filt->input_pads[j].name, filt->name, filt->filter->name);
00128 return AVERROR(EINVAL);
00129 }
00130 }
00131
00132 for (j = 0; j < filt->nb_outputs; j++) {
00133 if (!filt->outputs[j] || !filt->outputs[j]->dst) {
00134 av_log(log_ctx, AV_LOG_ERROR,
00135 "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
00136 filt->output_pads[j].name, filt->name, filt->filter->name);
00137 return AVERROR(EINVAL);
00138 }
00139 }
00140 }
00141
00142 return 0;
00143 }
00144
00150 static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
00151 {
00152 AVFilterContext *filt;
00153 int i, ret;
00154
00155 for (i=0; i < graph->filter_count; i++) {
00156 filt = graph->filters[i];
00157
00158 if (!filt->nb_outputs) {
00159 if ((ret = avfilter_config_links(filt)))
00160 return ret;
00161 }
00162 }
00163
00164 return 0;
00165 }
00166
00167 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
00168 {
00169 int i;
00170
00171 for (i = 0; i < graph->filter_count; i++)
00172 if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
00173 return graph->filters[i];
00174
00175 return NULL;
00176 }
00177
00178 static int filter_query_formats(AVFilterContext *ctx)
00179 {
00180 int ret;
00181 AVFilterFormats *formats;
00182 AVFilterChannelLayouts *chlayouts;
00183 AVFilterFormats *samplerates;
00184 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
00185 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
00186 AVMEDIA_TYPE_VIDEO;
00187
00188 if ((ret = ctx->filter->query_formats(ctx)) < 0)
00189 return ret;
00190
00191 formats = ff_all_formats(type);
00192 if (!formats)
00193 return AVERROR(ENOMEM);
00194 ff_set_common_formats(ctx, formats);
00195 if (type == AVMEDIA_TYPE_AUDIO) {
00196 samplerates = ff_all_samplerates();
00197 if (!samplerates)
00198 return AVERROR(ENOMEM);
00199 ff_set_common_samplerates(ctx, samplerates);
00200 chlayouts = ff_all_channel_layouts();
00201 if (!chlayouts)
00202 return AVERROR(ENOMEM);
00203 ff_set_common_channel_layouts(ctx, chlayouts);
00204 }
00205 return 0;
00206 }
00207
00208 static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
00209 const char *filt_name, const char *filt_args)
00210 {
00211 static int auto_count = 0, ret;
00212 char inst_name[32];
00213 AVFilterContext *filt_ctx;
00214
00215 if (graph->disable_auto_convert) {
00216 av_log(NULL, AV_LOG_ERROR,
00217 "The filters '%s' and '%s' do not have a common format "
00218 "and automatic conversion is disabled.\n",
00219 link->src->name, link->dst->name);
00220 return AVERROR(EINVAL);
00221 }
00222
00223 snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
00224 filt_name, auto_count++);
00225
00226 if ((ret = avfilter_graph_create_filter(&filt_ctx,
00227 avfilter_get_by_name(filt_name),
00228 inst_name, filt_args, NULL, graph)) < 0)
00229 return ret;
00230 if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
00231 return ret;
00232
00233 filter_query_formats(filt_ctx);
00234
00235 if ( ((link = filt_ctx-> inputs[0]) &&
00236 !ff_merge_formats(link->in_formats, link->out_formats)) ||
00237 ((link = filt_ctx->outputs[0]) &&
00238 !ff_merge_formats(link->in_formats, link->out_formats))
00239 ) {
00240 av_log(NULL, AV_LOG_ERROR,
00241 "Impossible to convert between the formats supported by the filter "
00242 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
00243 return AVERROR(EINVAL);
00244 }
00245
00246 if (link->type == AVMEDIA_TYPE_AUDIO &&
00247 (((link = filt_ctx-> inputs[0]) &&
00248 !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)) ||
00249 ((link = filt_ctx->outputs[0]) &&
00250 !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)))
00251 ) {
00252 av_log(NULL, AV_LOG_ERROR,
00253 "Impossible to convert between the channel layouts formats supported by the filter "
00254 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
00255 return AVERROR(EINVAL);
00256 }
00257
00258 return 0;
00259 }
00260
00261 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
00262 {
00263 int i, j, ret;
00264 char filt_args[128];
00265 AVFilterFormats *formats;
00266 AVFilterChannelLayouts *chlayouts;
00267 AVFilterFormats *samplerates;
00268 int scaler_count = 0, resampler_count = 0;
00269
00270 for (j = 0; j < 2; j++) {
00271
00272 for (i = 0; i < graph->filter_count; i++) {
00273
00274
00275
00276 if (!graph->filters[i]->nb_inputs == j)
00277 continue;
00278 if (graph->filters[i]->filter->query_formats)
00279 ret = filter_query_formats(graph->filters[i]);
00280 else
00281 ret = ff_default_query_formats(graph->filters[i]);
00282 if (ret < 0)
00283 return ret;
00284 }
00285 }
00286
00287
00288 for (i = 0; i < graph->filter_count; i++) {
00289 AVFilterContext *filter = graph->filters[i];
00290
00291 for (j = 0; j < filter->nb_inputs; j++) {
00292 AVFilterLink *link = filter->inputs[j];
00293 #if 0
00294 if (!link) continue;
00295
00296 if (!link->in_formats || !link->out_formats)
00297 return AVERROR(EINVAL);
00298
00299 if (link->type == AVMEDIA_TYPE_VIDEO &&
00300 !ff_merge_formats(link->in_formats, link->out_formats)) {
00301
00302
00303 snprintf(filt_args, sizeof(filt_args), "0:0:%s",
00304 graph->scale_sws_opts);
00305 if (ret = insert_conv_filter(graph, link, "scale", filt_args))
00306 return ret;
00307 }
00308 else if (link->type == AVMEDIA_TYPE_AUDIO) {
00309 if (!link->in_channel_layouts || !link->out_channel_layouts)
00310 return AVERROR(EINVAL);
00311
00312
00313
00314
00315 formats = ff_merge_formats(link->in_formats, link->out_formats);
00316 chlayouts = ff_merge_channel_layouts(link->in_channel_layouts , link->out_channel_layouts);
00317 samplerates = ff_merge_samplerates (link->in_samplerates, link->out_samplerates);
00318
00319 if (!formats || !chlayouts || !samplerates)
00320 if (ret = insert_conv_filter(graph, link, "aresample", NULL))
00321 return ret;
00322 #else
00323 int convert_needed = 0;
00324
00325 if (!link)
00326 continue;
00327
00328 if (link->in_formats != link->out_formats &&
00329 !ff_merge_formats(link->in_formats,
00330 link->out_formats))
00331 convert_needed = 1;
00332 if (link->type == AVMEDIA_TYPE_AUDIO) {
00333 if (link->in_channel_layouts != link->out_channel_layouts &&
00334 !ff_merge_channel_layouts(link->in_channel_layouts,
00335 link->out_channel_layouts))
00336 convert_needed = 1;
00337 if (link->in_samplerates != link->out_samplerates &&
00338 !ff_merge_samplerates(link->in_samplerates,
00339 link->out_samplerates))
00340 convert_needed = 1;
00341 }
00342
00343 if (convert_needed) {
00344 AVFilterContext *convert;
00345 AVFilter *filter;
00346 AVFilterLink *inlink, *outlink;
00347 char scale_args[256];
00348 char inst_name[30];
00349
00350
00351 switch (link->type) {
00352 case AVMEDIA_TYPE_VIDEO:
00353 if (!(filter = avfilter_get_by_name("scale"))) {
00354 av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
00355 "not present, cannot convert pixel formats.\n");
00356 return AVERROR(EINVAL);
00357 }
00358
00359 snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
00360 scaler_count++);
00361 snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
00362 if ((ret = avfilter_graph_create_filter(&convert, filter,
00363 inst_name, scale_args, NULL,
00364 graph)) < 0)
00365 return ret;
00366 break;
00367 case AVMEDIA_TYPE_AUDIO:
00368 if (!(filter = avfilter_get_by_name("aresample"))) {
00369 av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "
00370 "not present, cannot convert audio formats.\n");
00371 return AVERROR(EINVAL);
00372 }
00373
00374 snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
00375 resampler_count++);
00376 if ((ret = avfilter_graph_create_filter(&convert, filter,
00377 inst_name, NULL, NULL, graph)) < 0)
00378 return ret;
00379 break;
00380 default:
00381 return AVERROR(EINVAL);
00382 }
00383
00384 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
00385 return ret;
00386
00387 filter_query_formats(convert);
00388 inlink = convert->inputs[0];
00389 outlink = convert->outputs[0];
00390 if (!ff_merge_formats( inlink->in_formats, inlink->out_formats) ||
00391 !ff_merge_formats(outlink->in_formats, outlink->out_formats))
00392 ret |= AVERROR(ENOSYS);
00393 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
00394 (!ff_merge_samplerates(inlink->in_samplerates,
00395 inlink->out_samplerates) ||
00396 !ff_merge_channel_layouts(inlink->in_channel_layouts,
00397 inlink->out_channel_layouts)))
00398 ret |= AVERROR(ENOSYS);
00399 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
00400 (!ff_merge_samplerates(outlink->in_samplerates,
00401 outlink->out_samplerates) ||
00402 !ff_merge_channel_layouts(outlink->in_channel_layouts,
00403 outlink->out_channel_layouts)))
00404 ret |= AVERROR(ENOSYS);
00405
00406 if (ret < 0) {
00407 av_log(log_ctx, AV_LOG_ERROR,
00408 "Impossible to convert between the formats supported by the filter "
00409 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
00410 return ret;
00411 }
00412 #endif
00413 }
00414 }
00415 }
00416
00417 return 0;
00418 }
00419
00420 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
00421 {
00422 if (!link || !link->in_formats)
00423 return 0;
00424
00425 if (link->type == AVMEDIA_TYPE_VIDEO) {
00426 if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
00427 int has_alpha= av_pix_fmt_descriptors[ref->format].nb_components % 2 == 0;
00428 enum PixelFormat best= PIX_FMT_NONE;
00429 int i;
00430 for (i=0; i<link->in_formats->format_count; i++) {
00431 enum PixelFormat p = link->in_formats->formats[i];
00432 best= avcodec_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
00433 }
00434 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
00435 av_get_pix_fmt_name(best), link->in_formats->format_count,
00436 av_get_pix_fmt_name(ref->format), has_alpha);
00437 link->in_formats->formats[0] = best;
00438 }
00439 }
00440
00441 link->in_formats->format_count = 1;
00442 link->format = link->in_formats->formats[0];
00443
00444 if (link->type == AVMEDIA_TYPE_AUDIO) {
00445 if (!link->in_samplerates->format_count) {
00446 av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
00447 " the link between filters %s and %s.\n", link->src->name,
00448 link->dst->name);
00449 return AVERROR(EINVAL);
00450 }
00451 link->in_samplerates->format_count = 1;
00452 link->sample_rate = link->in_samplerates->formats[0];
00453
00454 if (!link->in_channel_layouts->nb_channel_layouts) {
00455 av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
00456 "the link between filters %s and %s.\n", link->src->name,
00457 link->dst->name);
00458 return AVERROR(EINVAL);
00459 }
00460 link->in_channel_layouts->nb_channel_layouts = 1;
00461 link->channel_layout = link->in_channel_layouts->channel_layouts[0];
00462 }
00463
00464 ff_formats_unref(&link->in_formats);
00465 ff_formats_unref(&link->out_formats);
00466 ff_formats_unref(&link->in_samplerates);
00467 ff_formats_unref(&link->out_samplerates);
00468 ff_channel_layouts_unref(&link->in_channel_layouts);
00469 ff_channel_layouts_unref(&link->out_channel_layouts);
00470
00471 return 0;
00472 }
00473
00474 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
00475 do { \
00476 for (i = 0; i < filter->nb_inputs; i++) { \
00477 AVFilterLink *link = filter->inputs[i]; \
00478 fmt_type fmt; \
00479 \
00480 if (!link->out_ ## list || link->out_ ## list->nb != 1) \
00481 continue; \
00482 fmt = link->out_ ## list->var[0]; \
00483 \
00484 for (j = 0; j < filter->nb_outputs; j++) { \
00485 AVFilterLink *out_link = filter->outputs[j]; \
00486 list_type *fmts; \
00487 \
00488 if (link->type != out_link->type || \
00489 out_link->in_ ## list->nb == 1) \
00490 continue; \
00491 fmts = out_link->in_ ## list; \
00492 \
00493 if (!out_link->in_ ## list->nb) { \
00494 add_format(&out_link->in_ ##list, fmt); \
00495 break; \
00496 } \
00497 \
00498 for (k = 0; k < out_link->in_ ## list->nb; k++) \
00499 if (fmts->var[k] == fmt) { \
00500 fmts->var[0] = fmt; \
00501 fmts->nb = 1; \
00502 ret = 1; \
00503 break; \
00504 } \
00505 } \
00506 } \
00507 } while (0)
00508
00509 static int reduce_formats_on_filter(AVFilterContext *filter)
00510 {
00511 int i, j, k, ret = 0;
00512
00513 REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
00514 format_count, ff_add_format);
00515 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
00516 format_count, ff_add_format);
00517 REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
00518 channel_layouts, nb_channel_layouts, ff_add_channel_layout);
00519
00520 return ret;
00521 }
00522
00523 static void reduce_formats(AVFilterGraph *graph)
00524 {
00525 int i, reduced;
00526
00527 do {
00528 reduced = 0;
00529
00530 for (i = 0; i < graph->filter_count; i++)
00531 reduced |= reduce_formats_on_filter(graph->filters[i]);
00532 } while (reduced);
00533 }
00534
00535 static void swap_samplerates_on_filter(AVFilterContext *filter)
00536 {
00537 AVFilterLink *link = NULL;
00538 int sample_rate;
00539 int i, j;
00540
00541 for (i = 0; i < filter->nb_inputs; i++) {
00542 link = filter->inputs[i];
00543
00544 if (link->type == AVMEDIA_TYPE_AUDIO &&
00545 link->out_samplerates->format_count == 1)
00546 break;
00547 }
00548 if (i == filter->nb_inputs)
00549 return;
00550
00551 sample_rate = link->out_samplerates->formats[0];
00552
00553 for (i = 0; i < filter->nb_outputs; i++) {
00554 AVFilterLink *outlink = filter->outputs[i];
00555 int best_idx, best_diff = INT_MAX;
00556
00557 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
00558 outlink->in_samplerates->format_count < 2)
00559 continue;
00560
00561 for (j = 0; j < outlink->in_samplerates->format_count; j++) {
00562 int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
00563
00564 if (diff < best_diff) {
00565 best_diff = diff;
00566 best_idx = j;
00567 }
00568 }
00569 FFSWAP(int, outlink->in_samplerates->formats[0],
00570 outlink->in_samplerates->formats[best_idx]);
00571 }
00572 }
00573
00574 static void swap_samplerates(AVFilterGraph *graph)
00575 {
00576 int i;
00577
00578 for (i = 0; i < graph->filter_count; i++)
00579 swap_samplerates_on_filter(graph->filters[i]);
00580 }
00581
00582 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
00583 #define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)
00584 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)
00585 #define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)
00586 #define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)
00587 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
00588 #define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
00589
00590
00591
00592 static const uint64_t ch_subst[][2] = {
00593 { CH_FRONT_PAIR, CH_CENTER_PAIR },
00594 { CH_FRONT_PAIR, CH_WIDE_PAIR },
00595 { CH_FRONT_PAIR, AV_CH_FRONT_CENTER },
00596 { CH_CENTER_PAIR, CH_FRONT_PAIR },
00597 { CH_CENTER_PAIR, CH_WIDE_PAIR },
00598 { CH_CENTER_PAIR, AV_CH_FRONT_CENTER },
00599 { CH_WIDE_PAIR, CH_FRONT_PAIR },
00600 { CH_WIDE_PAIR, CH_CENTER_PAIR },
00601 { CH_WIDE_PAIR, AV_CH_FRONT_CENTER },
00602 { AV_CH_FRONT_CENTER, CH_FRONT_PAIR },
00603 { AV_CH_FRONT_CENTER, CH_CENTER_PAIR },
00604 { AV_CH_FRONT_CENTER, CH_WIDE_PAIR },
00605 { CH_SIDE_PAIR, CH_DIRECT_PAIR },
00606 { CH_SIDE_PAIR, CH_BACK_PAIR },
00607 { CH_SIDE_PAIR, AV_CH_BACK_CENTER },
00608 { CH_BACK_PAIR, CH_DIRECT_PAIR },
00609 { CH_BACK_PAIR, CH_SIDE_PAIR },
00610 { CH_BACK_PAIR, AV_CH_BACK_CENTER },
00611 { AV_CH_BACK_CENTER, CH_BACK_PAIR },
00612 { AV_CH_BACK_CENTER, CH_DIRECT_PAIR },
00613 { AV_CH_BACK_CENTER, CH_SIDE_PAIR },
00614 };
00615
00616 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
00617 {
00618 AVFilterLink *link = NULL;
00619 int i, j, k;
00620
00621 for (i = 0; i < filter->nb_inputs; i++) {
00622 link = filter->inputs[i];
00623
00624 if (link->type == AVMEDIA_TYPE_AUDIO &&
00625 link->out_channel_layouts->nb_channel_layouts == 1)
00626 break;
00627 }
00628 if (i == filter->nb_inputs)
00629 return;
00630
00631 for (i = 0; i < filter->nb_outputs; i++) {
00632 AVFilterLink *outlink = filter->outputs[i];
00633 int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
00634
00635 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
00636 outlink->in_channel_layouts->nb_channel_layouts < 2)
00637 continue;
00638
00639 for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
00640 uint64_t in_chlayout = link->out_channel_layouts->channel_layouts[0];
00641 uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
00642 int in_channels = av_get_channel_layout_nb_channels(in_chlayout);
00643 int out_channels = av_get_channel_layout_nb_channels(out_chlayout);
00644 int count_diff = out_channels - in_channels;
00645 int matched_channels, extra_channels;
00646 int score = 0;
00647
00648
00649 for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
00650 uint64_t cmp0 = ch_subst[k][0];
00651 uint64_t cmp1 = ch_subst[k][1];
00652 if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
00653 (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
00654 in_chlayout &= ~cmp0;
00655 out_chlayout &= ~cmp1;
00656
00657
00658 score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
00659 }
00660 }
00661
00662
00663 if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
00664 (out_chlayout & AV_CH_LOW_FREQUENCY))
00665 score += 10;
00666 in_chlayout &= ~AV_CH_LOW_FREQUENCY;
00667 out_chlayout &= ~AV_CH_LOW_FREQUENCY;
00668
00669 matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
00670 out_chlayout);
00671 extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
00672 (~in_chlayout));
00673 score += 10 * matched_channels - 5 * extra_channels;
00674
00675 if (score > best_score ||
00676 (count_diff < best_count_diff && score == best_score)) {
00677 best_score = score;
00678 best_idx = j;
00679 best_count_diff = count_diff;
00680 }
00681 }
00682 av_assert0(best_idx >= 0);
00683 FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
00684 outlink->in_channel_layouts->channel_layouts[best_idx]);
00685 }
00686
00687 }
00688
00689 static void swap_channel_layouts(AVFilterGraph *graph)
00690 {
00691 int i;
00692
00693 for (i = 0; i < graph->filter_count; i++)
00694 swap_channel_layouts_on_filter(graph->filters[i]);
00695 }
00696
00697 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
00698 {
00699 AVFilterLink *link = NULL;
00700 int format, bps;
00701 int i, j;
00702
00703 for (i = 0; i < filter->nb_inputs; i++) {
00704 link = filter->inputs[i];
00705
00706 if (link->type == AVMEDIA_TYPE_AUDIO &&
00707 link->out_formats->format_count == 1)
00708 break;
00709 }
00710 if (i == filter->nb_inputs)
00711 return;
00712
00713 format = link->out_formats->formats[0];
00714 bps = av_get_bytes_per_sample(format);
00715
00716 for (i = 0; i < filter->nb_outputs; i++) {
00717 AVFilterLink *outlink = filter->outputs[i];
00718 int best_idx = -1, best_score = INT_MIN;
00719
00720 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
00721 outlink->in_formats->format_count < 2)
00722 continue;
00723
00724 for (j = 0; j < outlink->in_formats->format_count; j++) {
00725 int out_format = outlink->in_formats->formats[j];
00726 int out_bps = av_get_bytes_per_sample(out_format);
00727 int score;
00728
00729 if (av_get_packed_sample_fmt(out_format) == format ||
00730 av_get_planar_sample_fmt(out_format) == format) {
00731 best_idx = j;
00732 break;
00733 }
00734
00735
00736 if (bps == 4 && out_bps == 8) {
00737 best_idx = j;
00738 break;
00739 }
00740
00741
00742 score = -abs(out_bps - bps);
00743 if (out_bps >= bps)
00744 score += INT_MAX/2;
00745
00746 if (score > best_score) {
00747 best_score = score;
00748 best_idx = j;
00749 }
00750 }
00751 av_assert0(best_idx >= 0);
00752 FFSWAP(int, outlink->in_formats->formats[0],
00753 outlink->in_formats->formats[best_idx]);
00754 }
00755 }
00756
00757 static void swap_sample_fmts(AVFilterGraph *graph)
00758 {
00759 int i;
00760
00761 for (i = 0; i < graph->filter_count; i++)
00762 swap_sample_fmts_on_filter(graph->filters[i]);
00763
00764 }
00765
00766 static int pick_formats(AVFilterGraph *graph)
00767 {
00768 int i, j, ret;
00769 int change;
00770
00771 do{
00772 change = 0;
00773 for (i = 0; i < graph->filter_count; i++) {
00774 AVFilterContext *filter = graph->filters[i];
00775 if (filter->nb_inputs){
00776 for (j = 0; j < filter->nb_inputs; j++){
00777 if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) {
00778 pick_format(filter->inputs[j], NULL);
00779 change = 1;
00780 }
00781 }
00782 }
00783 if (filter->nb_outputs){
00784 for (j = 0; j < filter->nb_outputs; j++){
00785 if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) {
00786 pick_format(filter->outputs[j], NULL);
00787 change = 1;
00788 }
00789 }
00790 }
00791 if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
00792 for (j = 0; j < filter->nb_outputs; j++) {
00793 if(filter->outputs[j]->format<0) {
00794 pick_format(filter->outputs[j], filter->inputs[0]);
00795 change = 1;
00796 }
00797 }
00798 }
00799 }
00800 }while(change);
00801
00802 for (i = 0; i < graph->filter_count; i++) {
00803 AVFilterContext *filter = graph->filters[i];
00804
00805 for (j = 0; j < filter->nb_inputs; j++)
00806 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
00807 return ret;
00808 for (j = 0; j < filter->nb_outputs; j++)
00809 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
00810 return ret;
00811 }
00812 return 0;
00813 }
00814
00818 static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
00819 {
00820 int ret;
00821
00822
00823 if ((ret = query_formats(graph, log_ctx)) < 0)
00824 return ret;
00825
00826
00827
00828
00829 reduce_formats(graph);
00830
00831
00832
00833 swap_sample_fmts(graph);
00834 swap_samplerates(graph);
00835 swap_channel_layouts(graph);
00836
00837 if ((ret = pick_formats(graph)) < 0)
00838 return ret;
00839
00840 return 0;
00841 }
00842
00843 static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph,
00844 AVClass *log_ctx)
00845 {
00846 unsigned i, j;
00847 int sink_links_count = 0, n = 0;
00848 AVFilterContext *f;
00849 AVFilterLink **sinks;
00850
00851 for (i = 0; i < graph->filter_count; i++) {
00852 f = graph->filters[i];
00853 for (j = 0; j < f->nb_inputs; j++) {
00854 f->inputs[j]->graph = graph;
00855 f->inputs[j]->age_index = -1;
00856 }
00857 for (j = 0; j < f->nb_outputs; j++) {
00858 f->outputs[j]->graph = graph;
00859 f->outputs[j]->age_index= -1;
00860 }
00861 if (!f->nb_outputs) {
00862 if (f->nb_inputs > INT_MAX - sink_links_count)
00863 return AVERROR(EINVAL);
00864 sink_links_count += f->nb_inputs;
00865 }
00866 }
00867 sinks = av_calloc(sink_links_count, sizeof(*sinks));
00868 if (!sinks)
00869 return AVERROR(ENOMEM);
00870 for (i = 0; i < graph->filter_count; i++) {
00871 f = graph->filters[i];
00872 if (!f->nb_outputs) {
00873 for (j = 0; j < f->nb_inputs; j++) {
00874 sinks[n] = f->inputs[j];
00875 f->inputs[j]->age_index = n++;
00876 }
00877 }
00878 }
00879 av_assert0(n == sink_links_count);
00880 graph->sink_links = sinks;
00881 graph->sink_links_count = sink_links_count;
00882 return 0;
00883 }
00884
00885 static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
00886 {
00887 AVFilterContext *f;
00888 int i, j, ret;
00889 int fifo_count = 0;
00890
00891 for (i = 0; i < graph->filter_count; i++) {
00892 f = graph->filters[i];
00893
00894 for (j = 0; j < f->nb_inputs; j++) {
00895 AVFilterLink *link = f->inputs[j];
00896 AVFilterContext *fifo_ctx;
00897 AVFilter *fifo;
00898 char name[32];
00899
00900 if (!link->dstpad->needs_fifo)
00901 continue;
00902
00903 fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
00904 avfilter_get_by_name("fifo") :
00905 avfilter_get_by_name("afifo");
00906
00907 snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
00908
00909 ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
00910 NULL, graph);
00911 if (ret < 0)
00912 return ret;
00913
00914 ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
00915 if (ret < 0)
00916 return ret;
00917 }
00918 }
00919
00920 return 0;
00921 }
00922
00923 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
00924 {
00925 int ret;
00926
00927 if ((ret = graph_check_validity(graphctx, log_ctx)))
00928 return ret;
00929 if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
00930 return ret;
00931 if ((ret = graph_config_formats(graphctx, log_ctx)))
00932 return ret;
00933 if ((ret = graph_config_links(graphctx, log_ctx)))
00934 return ret;
00935 if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
00936 return ret;
00937
00938 return 0;
00939 }
00940
00941 int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
00942 {
00943 int i, r = AVERROR(ENOSYS);
00944
00945 if(!graph)
00946 return r;
00947
00948 if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
00949 r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
00950 if(r != AVERROR(ENOSYS))
00951 return r;
00952 }
00953
00954 if(res_len && res)
00955 res[0]= 0;
00956
00957 for (i = 0; i < graph->filter_count; i++) {
00958 AVFilterContext *filter = graph->filters[i];
00959 if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){
00960 r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
00961 if(r != AVERROR(ENOSYS)) {
00962 if((flags & AVFILTER_CMD_FLAG_ONE) || r<0)
00963 return r;
00964 }
00965 }
00966 }
00967
00968 return r;
00969 }
00970
00971 int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
00972 {
00973 int i;
00974
00975 if(!graph)
00976 return 0;
00977
00978 for (i = 0; i < graph->filter_count; i++) {
00979 AVFilterContext *filter = graph->filters[i];
00980 if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
00981 AVFilterCommand **que = &filter->command_queue, *next;
00982 while(*que && (*que)->time <= ts)
00983 que = &(*que)->next;
00984 next= *que;
00985 *que= av_mallocz(sizeof(AVFilterCommand));
00986 (*que)->command = av_strdup(command);
00987 (*que)->arg = av_strdup(arg);
00988 (*que)->time = ts;
00989 (*que)->flags = flags;
00990 (*que)->next = next;
00991 if(flags & AVFILTER_CMD_FLAG_ONE)
00992 return 0;
00993 }
00994 }
00995
00996 return 0;
00997 }
00998
00999 static void heap_bubble_up(AVFilterGraph *graph,
01000 AVFilterLink *link, int index)
01001 {
01002 AVFilterLink **links = graph->sink_links;
01003
01004 while (index) {
01005 int parent = (index - 1) >> 1;
01006 if (links[parent]->current_pts >= link->current_pts)
01007 break;
01008 links[index] = links[parent];
01009 links[index]->age_index = index;
01010 index = parent;
01011 }
01012 links[index] = link;
01013 link->age_index = index;
01014 }
01015
01016 static void heap_bubble_down(AVFilterGraph *graph,
01017 AVFilterLink *link, int index)
01018 {
01019 AVFilterLink **links = graph->sink_links;
01020
01021 while (1) {
01022 int child = 2 * index + 1;
01023 if (child >= graph->sink_links_count)
01024 break;
01025 if (child + 1 < graph->sink_links_count &&
01026 links[child + 1]->current_pts < links[child]->current_pts)
01027 child++;
01028 if (link->current_pts < links[child]->current_pts)
01029 break;
01030 links[index] = links[child];
01031 links[index]->age_index = index;
01032 index = child;
01033 }
01034 links[index] = link;
01035 link->age_index = index;
01036 }
01037
01038 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
01039 {
01040 heap_bubble_up (graph, link, link->age_index);
01041 heap_bubble_down(graph, link, link->age_index);
01042 }
01043
01044
01045 int avfilter_graph_request_oldest(AVFilterGraph *graph)
01046 {
01047 while (graph->sink_links_count) {
01048 AVFilterLink *oldest = graph->sink_links[0];
01049 int r = ff_request_frame(oldest);
01050 if (r != AVERROR_EOF)
01051 return r;
01052 av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
01053 oldest->dst ? oldest->dst->name : "unknown",
01054 oldest->dstpad ? oldest->dstpad->name : "unknown");
01055
01056 if (oldest->age_index < --graph->sink_links_count)
01057 heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
01058 oldest->age_index);
01059 oldest->age_index = -1;
01060 }
01061 return AVERROR_EOF;
01062 }