* qatar/master: (26 commits) fate: use diff -b in oneline comparison Add missing version bumps and APIchanges/Changelog entries. lavfi: move buffer management function to a separate file. lavfi: move formats-related functions from default.c to formats.c lavfi: move video-related functions to a separate file. fate: make smjpeg a demux test fate: separate sierra-vmd audio and video tests fate: separate smacker audio and video tests libmp3lame: set supported channel layouts. avconv: automatically insert asyncts when -async is used. avconv: add support for audio filters. lavfi: add asyncts filter. lavfi: add aformat filter lavfi: add an audio buffer sink. lavfi: add an audio buffer source. buffersrc: add av_buffersrc_write_frame(). buffersrc: fix invalid read in uninit if the fifo hasn't been allocated lavfi: rename vsrc_buffer.c to buffersrc.c avfiltergraph: reindent lavfi: add channel layout/sample rate negotiation. ... Conflicts: Changelog doc/APIchanges doc/filters.texi ffmpeg.c ffprobe.c libavcodec/libmp3lame.c libavfilter/Makefile libavfilter/af_aformat.c libavfilter/allfilters.c libavfilter/avfilter.c libavfilter/avfilter.h libavfilter/avfiltergraph.c libavfilter/buffersrc.c libavfilter/defaults.c libavfilter/formats.c libavfilter/src_buffer.c libavfilter/version.h libavfilter/vf_yadif.c libavfilter/vsrc_buffer.c libavfilter/vsrc_buffer.h libavutil/avutil.h tests/fate/audio.mak tests/fate/demux.mak tests/fate/video.mak
Showing the changes to libavfilter/avfiltergraph.c (1 of 52 files). Show all
Unified · Split
| @@ -28,8 +28,10 @@ · 27 unmodified lines | |||
| 28 | #include "libavutil/pixdesc.h" | 28 | #include "libavutil/pixdesc.h" |
| 29 | #include "avfilter.h" | 29 | #include "avfilter.h" |
| 30 | #include "avfiltergraph.h" | 30 | #include "avfiltergraph.h" |
| 31 | #include "formats.h" | ||
| 31 | #include "internal.h" | 32 | #include "internal.h" |
| 32 | 33 | ||
| 34 | #include "libavutil/audioconvert.h" | ||
| 33 | #include "libavutil/log.h" | 35 | #include "libavutil/log.h" |
| 34 | 36 | ||
| 35 | static const AVClass filtergraph_class = { | 37 | static const AVClass filtergraph_class = { |
| @@ -198,10 +200,10 @@ static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link, · 162 unmodified lines | |||
| 198 | 200 | ||
| 199 | if (link->type == AVMEDIA_TYPE_AUDIO && | 201 | if (link->type == AVMEDIA_TYPE_AUDIO && |
| 200 | (((link = filt_ctx-> inputs[0]) && | 202 | (((link = filt_ctx-> inputs[0]) && |
| 201 | (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) || | 203 | (!ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts) || |
| 202 | !avfilter_merge_formats(link->in_packing, link->out_packing))) || | 204 | !avfilter_merge_formats(link->in_packing, link->out_packing))) || |
| 203 | ((link = filt_ctx->outputs[0]) && | 205 | ((link = filt_ctx->outputs[0]) && |
| 204 | (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) || | 206 | (!ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts) || |
| 205 | !avfilter_merge_formats(link->in_packing, link->out_packing)))) | 207 | !avfilter_merge_formats(link->in_packing, link->out_packing)))) |
| 206 | ) { | 208 | ) { |
| 207 | av_log(NULL, AV_LOG_ERROR, | 209 | av_log(NULL, AV_LOG_ERROR, |
| @@ -217,7 +219,10 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines | |||
| 217 | { | 219 | { |
| 218 | int i, j, ret; | 220 | int i, j, ret; |
| 219 | char filt_args[128]; | 221 | char filt_args[128]; |
| 220 | AVFilterFormats *formats, *chlayouts, *packing; | 222 | AVFilterFormats *formats, *packing; |
| 223 | AVFilterChannelLayouts *chlayouts; | ||
| 224 | AVFilterFormats *samplerates; | ||
| 225 | int scaler_count = 0, resampler_count = 0; | ||
| 221 | 226 | ||
| 222 | /* ask all the sub-filters for their supported media formats */ | 227 | /* ask all the sub-filters for their supported media formats */ |
| 223 | for (i = 0; i < graph->filter_count; i++) { | 228 | for (i = 0; i < graph->filter_count; i++) { |
| @@ -233,6 +238,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines | |||
| 233 | 238 | ||
| 234 | for (j = 0; j < filter->input_count; j++) { | 239 | for (j = 0; j < filter->input_count; j++) { |
| 235 | AVFilterLink *link = filter->inputs[j]; | 240 | AVFilterLink *link = filter->inputs[j]; |
| 241 | #if 0 | ||
| 236 | if (!link) continue; | 242 | if (!link) continue; |
| 237 | 243 | ||
| 238 | if (!link->in_formats || !link->out_formats) | 244 | if (!link->in_formats || !link->out_formats) |
| @@ -248,7 +254,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines | |||
| 248 | return ret; | 254 | return ret; |
| 249 | } | 255 | } |
| 250 | else if (link->type == AVMEDIA_TYPE_AUDIO) { | 256 | else if (link->type == AVMEDIA_TYPE_AUDIO) { |
| 251 | if (!link->in_chlayouts || !link->out_chlayouts || | 257 | if (!link->in_channel_layouts || !link->out_channel_layouts || |
| 252 | !link->in_packing || !link->out_packing) | 258 | !link->in_packing || !link->out_packing) |
| 253 | return AVERROR(EINVAL); | 259 | return AVERROR(EINVAL); |
| 254 | 260 | ||
| @@ -256,11 +262,100 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 1 unmodified line | |||
| 256 | * three categories, aconvert will use a common format | 262 | * three categories, aconvert will use a common format |
| 257 | * whenever possible. */ | 263 | * whenever possible. */ |
| 258 | formats = avfilter_merge_formats(link->in_formats, link->out_formats); | 264 | formats = avfilter_merge_formats(link->in_formats, link->out_formats); |
| 259 | chlayouts = avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts); | 265 | chlayouts = ff_merge_channel_layouts(link->in_channel_layouts , link->out_channel_layouts); |
| 266 | samplerates = ff_merge_samplerates (link->in_samplerates, link->out_samplerates); | ||
| 260 | packing = avfilter_merge_formats(link->in_packing, link->out_packing); | 267 | packing = avfilter_merge_formats(link->in_packing, link->out_packing); |
| 261 | if (!formats || !chlayouts || !packing) | 268 | |
| 269 | if (!formats || !chlayouts || !packing || !samplerates) | ||
| 262 | if (ret = insert_conv_filter(graph, link, "aconvert", NULL)) | 270 | if (ret = insert_conv_filter(graph, link, "aconvert", NULL)) |
| 263 | return ret; | 271 | return ret; |
| 272 | #else | ||
| 273 | int convert_needed = 0; | ||
| 274 | |||
| 275 | if (!link) | ||
| 276 | continue; | ||
| 277 | |||
| 278 | if (link->in_formats != link->out_formats && | ||
| 279 | !avfilter_merge_formats(link->in_formats, | ||
| 280 | link->out_formats)) | ||
| 281 | convert_needed = 1; | ||
| 282 | if (link->type == AVMEDIA_TYPE_AUDIO) { | ||
| 283 | if (link->in_channel_layouts != link->out_channel_layouts && | ||
| 284 | !ff_merge_channel_layouts(link->in_channel_layouts, | ||
| 285 | link->out_channel_layouts)) | ||
| 286 | convert_needed = 1; | ||
| 287 | if (link->in_samplerates != link->out_samplerates && | ||
| 288 | !ff_merge_samplerates(link->in_samplerates, | ||
| 289 | link->out_samplerates)) | ||
| 290 | convert_needed = 1; | ||
| 291 | } | ||
| 292 | |||
| 293 | if (convert_needed) { | ||
| 294 | AVFilterContext *convert; | ||
| 295 | AVFilter *filter; | ||
| 296 | AVFilterLink *inlink, *outlink; | ||
| 297 | char scale_args[256]; | ||
| 298 | char inst_name[30]; | ||
| 299 | |||
| 300 | /* couldn't merge format lists. auto-insert conversion filter */ | ||
| 301 | switch (link->type) { | ||
| 302 | case AVMEDIA_TYPE_VIDEO: | ||
| 303 | snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d", | ||
| 304 | scaler_count++); | ||
| 305 | snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts); | ||
| 306 | if ((ret = avfilter_graph_create_filter(&convert, | ||
| 307 | avfilter_get_by_name("scale"), | ||
| 308 | inst_name, scale_args, NULL, | ||
| 309 | graph)) < 0) | ||
| 310 | return ret; | ||
| 311 | break; | ||
| 312 | case AVMEDIA_TYPE_AUDIO: | ||
| 313 | if (!(filter = avfilter_get_by_name("resample"))) { | ||
| 314 | av_log(log_ctx, AV_LOG_ERROR, "'resample' filter " | ||
| 315 | "not present, cannot convert audio formats.\n"); | ||
| 316 | return AVERROR(EINVAL); | ||
| 317 | } | ||
| 318 | |||
| 319 | snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d", | ||
| 320 | resampler_count++); | ||
| 321 | if ((ret = avfilter_graph_create_filter(&convert, | ||
| 322 | avfilter_get_by_name("resample"), | ||
| 323 | inst_name, NULL, NULL, graph)) < 0) | ||
| 324 | return ret; | ||
| 325 | break; | ||
| 326 | default: | ||
| 327 | return AVERROR(EINVAL); | ||
| 328 | } | ||
| 329 | |||
| 330 | if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0) | ||
| 331 | return ret; | ||
| 332 | |||
| 333 | convert->filter->query_formats(convert); | ||
| 334 | inlink = convert->inputs[0]; | ||
| 335 | outlink = convert->outputs[0]; | ||
| 336 | if (!avfilter_merge_formats( inlink->in_formats, inlink->out_formats) || | ||
| 337 | !avfilter_merge_formats(outlink->in_formats, outlink->out_formats)) | ||
| 338 | ret |= AVERROR(ENOSYS); | ||
| 339 | if (inlink->type == AVMEDIA_TYPE_AUDIO && | ||
| 340 | (!ff_merge_samplerates(inlink->in_samplerates, | ||
| 341 | inlink->out_samplerates) || | ||
| 342 | !ff_merge_channel_layouts(inlink->in_channel_layouts, | ||
| 343 | inlink->out_channel_layouts))) | ||
| 344 | ret |= AVERROR(ENOSYS); | ||
| 345 | if (outlink->type == AVMEDIA_TYPE_AUDIO && | ||
| 346 | (!ff_merge_samplerates(outlink->in_samplerates, | ||
| 347 | outlink->out_samplerates) || | ||
| 348 | !ff_merge_channel_layouts(outlink->in_channel_layouts, | ||
| 349 | outlink->out_channel_layouts))) | ||
| 350 | ret |= AVERROR(ENOSYS); | ||
| 351 | |||
| 352 | if (ret < 0) { | ||
| 353 | av_log(log_ctx, AV_LOG_ERROR, | ||
| 354 | "Impossible to convert between the formats supported by the filter " | ||
| 355 | "'%s' and the filter '%s'\n", link->src->name, link->dst->name); | ||
| 356 | return ret; | ||
| 357 | } | ||
| 358 | #endif | ||
| 264 | } | 359 | } |
| 265 | } | 360 | } |
| 266 | } | 361 | } |
| @@ -268,10 +363,10 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 1 unmodified line | |||
| 268 | return 0; | 363 | return 0; |
| 269 | } | 364 | } |
| 270 | 365 | ||
| 271 | static void pick_format(AVFilterLink *link, AVFilterLink *ref) | 366 | static int pick_format(AVFilterLink *link, AVFilterLink *ref) |
| 272 | { | 367 | { |
| 273 | if (!link || !link->in_formats) | 368 | if (!link || !link->in_formats) |
| 274 | return; | 369 | return 0; |
| 275 | 370 | ||
| 276 | if (link->type == AVMEDIA_TYPE_VIDEO) { | 371 | if (link->type == AVMEDIA_TYPE_VIDEO) { |
| 277 | if(ref && ref->type == AVMEDIA_TYPE_VIDEO){ | 372 | if(ref && ref->type == AVMEDIA_TYPE_VIDEO){ |
| @@ -288,50 +383,83 @@ static void pick_format(AVFilterLink *link, AVFilterLink *ref) · 10 unmodified lines | |||
| 288 | 383 | ||
| 289 | link->in_formats->format_count = 1; | 384 | link->in_formats->format_count = 1; |
| 290 | link->format = link->in_formats->formats[0]; | 385 | link->format = link->in_formats->formats[0]; |
| 291 | avfilter_formats_unref(&link->in_formats); | ||
| 292 | avfilter_formats_unref(&link->out_formats); | ||
| 293 | 386 | ||
| 294 | if (link->type == AVMEDIA_TYPE_AUDIO) { | 387 | if (link->type == AVMEDIA_TYPE_AUDIO) { |
| 295 | link->in_chlayouts->format_count = 1; | 388 | if (!link->in_samplerates->format_count) { |
| 296 | link->channel_layout = link->in_chlayouts->formats[0]; | 389 | av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for" |
| 297 | avfilter_formats_unref(&link->in_chlayouts); | 390 | " the link between filters %s and %s.\n", link->src->name, |
| 298 | avfilter_formats_unref(&link->out_chlayouts); | 391 | link->dst->name); |
| 299 | 392 | return AVERROR(EINVAL); | |
| 300 | link->in_packing->format_count = 1; | 393 | } |
| 301 | link->planar = link->in_packing->formats[0] == AVFILTER_PLANAR; | 394 | link->in_samplerates->format_count = 1; |
| 302 | avfilter_formats_unref(&link->in_packing); | 395 | link->sample_rate = link->in_samplerates->formats[0]; |
| 303 | avfilter_formats_unref(&link->out_packing); | 396 | |
| 397 | if (!link->in_channel_layouts->nb_channel_layouts) { | ||
| 398 | av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" | ||
| 399 | "the link between filters %s and %s.\n", link->src->name, | ||
| 400 | link->dst->name); | ||
| 401 | return AVERROR(EINVAL); | ||
| 402 | } | ||
| 403 | link->in_channel_layouts->nb_channel_layouts = 1; | ||
| 404 | link->channel_layout = link->in_channel_layouts->channel_layouts[0]; | ||
| 304 | } | 405 | } |
| 406 | |||
| 407 | avfilter_formats_unref(&link->in_formats); | ||
| 408 | avfilter_formats_unref(&link->out_formats); | ||
| 409 | avfilter_formats_unref(&link->in_samplerates); | ||
| 410 | avfilter_formats_unref(&link->out_samplerates); | ||
| 411 | ff_channel_layouts_unref(&link->in_channel_layouts); | ||
| 412 | ff_channel_layouts_unref(&link->out_channel_layouts); | ||
| 413 | |||
| 414 | return 0; | ||
| 305 | } | 415 | } |
| 306 | 416 | ||
| 417 | #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \ | ||
| 418 | do { \ | ||
| 419 | for (i = 0; i < filter->input_count; i++) { \ | ||
| 420 | AVFilterLink *link = filter->inputs[i]; \ | ||
| 421 | fmt_type fmt; \ | ||
| 422 | \ | ||
| 423 | if (!link->out_ ## list || link->out_ ## list->nb != 1) \ | ||
| 424 | continue; \ | ||
| 425 | fmt = link->out_ ## list->var[0]; \ | ||
| 426 | \ | ||
| 427 | for (j = 0; j < filter->output_count; j++) { \ | ||
| 428 | AVFilterLink *out_link = filter->outputs[j]; \ | ||
| 429 | list_type *fmts; \ | ||
| 430 | \ | ||
| 431 | if (link->type != out_link->type || \ | ||
| 432 | out_link->in_ ## list->nb == 1) \ | ||
| 433 | continue; \ | ||
| 434 | fmts = out_link->in_ ## list; \ | ||
| 435 | \ | ||
| 436 | if (!out_link->in_ ## list->nb) { \ | ||
| 437 | add_format(&out_link->in_ ##list, fmt); \ | ||
| 438 | break; \ | ||
| 439 | } \ | ||
| 440 | \ | ||
| 441 | for (k = 0; k < out_link->in_ ## list->nb; k++) \ | ||
| 442 | if (fmts->var[k] == fmt) { \ | ||
| 443 | fmts->var[0] = fmt; \ | ||
| 444 | fmts->nb = 1; \ | ||
| 445 | ret = 1; \ | ||
| 446 | break; \ | ||
| 447 | } \ | ||
| 448 | } \ | ||
| 449 | } \ | ||
| 450 | } while (0) | ||
| 451 | |||
| 307 | static int reduce_formats_on_filter(AVFilterContext *filter) | 452 | static int reduce_formats_on_filter(AVFilterContext *filter) |
| 308 | { | 453 | { |
| 309 | int i, j, k, ret = 0; | 454 | int i, j, k, ret = 0; |
| 310 | 455 | ||
| 311 | for (i = 0; i < filter->input_count; i++) { | 456 | REDUCE_FORMATS(int, AVFilterFormats, formats, formats, |
| 312 | AVFilterLink *link = filter->inputs[i]; | 457 | format_count, avfilter_add_format); |
| 313 | int format = link->out_formats->formats[0]; | 458 | REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, |
| 314 | 459 | format_count, avfilter_add_format); | |
| 315 | if (link->out_formats->format_count != 1) | 460 | REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts, |
| 316 | continue; | 461 | channel_layouts, nb_channel_layouts, ff_add_channel_layout); |
| 317 | |||
| 318 | for (j = 0; j < filter->output_count; j++) { | ||
| 319 | AVFilterLink *out_link = filter->outputs[j]; | ||
| 320 | AVFilterFormats *fmts = out_link->in_formats; | ||
| 321 | |||
| 322 | if (link->type != out_link->type || | ||
| 323 | out_link->in_formats->format_count == 1) | ||
| 324 | continue; | ||
| 325 | 462 | ||
| 326 | for (k = 0; k < out_link->in_formats->format_count; k++) | ||
| 327 | if (fmts->formats[k] == format) { | ||
| 328 | fmts->formats[0] = format; | ||
| 329 | fmts->format_count = 1; | ||
| 330 | ret = 1; | ||
| 331 | break; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | return ret; | 463 | return ret; |
| 336 | } | 464 | } |
| 337 | 465 | ||
| @@ -347,9 +475,109 @@ static void reduce_formats(AVFilterGraph *graph) · 9 unmodified lines | |||
| 347 | } while (reduced); | 475 | } while (reduced); |
| 348 | } | 476 | } |
| 349 | 477 | ||
| 350 | static void pick_formats(AVFilterGraph *graph) | 478 | static void swap_samplerates_on_filter(AVFilterContext *filter) |
| 479 | { | ||
| 480 | AVFilterLink *link = NULL; | ||
| 481 | int sample_rate; | ||
| 482 | int i, j; | ||
| 483 | |||
| 484 | for (i = 0; i < filter->input_count; i++) { | ||
| 485 | link = filter->inputs[i]; | ||
| 486 | |||
| 487 | if (link->type == AVMEDIA_TYPE_AUDIO && | ||
| 488 | link->out_samplerates->format_count == 1) | ||
| 489 | break; | ||
| 490 | } | ||
| 491 | if (i == filter->input_count) | ||
| 492 | return; | ||
| 493 | |||
| 494 | sample_rate = link->out_samplerates->formats[0]; | ||
| 495 | |||
| 496 | for (i = 0; i < filter->output_count; i++) { | ||
| 497 | AVFilterLink *outlink = filter->outputs[i]; | ||
| 498 | int best_idx, best_diff = INT_MAX; | ||
| 499 | |||
| 500 | if (outlink->type != AVMEDIA_TYPE_AUDIO || | ||
| 501 | outlink->in_samplerates->format_count < 2) | ||
| 502 | continue; | ||
| 503 | |||
| 504 | for (j = 0; j < outlink->in_samplerates->format_count; j++) { | ||
| 505 | int diff = abs(sample_rate - outlink->in_samplerates->formats[j]); | ||
| 506 | |||
| 507 | if (diff < best_diff) { | ||
| 508 | best_diff = diff; | ||
| 509 | best_idx = j; | ||
| 510 | } | ||
| 511 | } | ||
| 512 | FFSWAP(int, outlink->in_samplerates->formats[0], | ||
| 513 | outlink->in_samplerates->formats[best_idx]); | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 517 | static void swap_samplerates(AVFilterGraph *graph) | ||
| 351 | { | 518 | { |
| 519 | int i; | ||
| 520 | |||
| 521 | for (i = 0; i < graph->filter_count; i++) | ||
| 522 | swap_samplerates_on_filter(graph->filters[i]); | ||
| 523 | } | ||
| 524 | |||
| 525 | static void swap_channel_layouts_on_filter(AVFilterContext *filter) | ||
| 526 | { | ||
| 527 | AVFilterLink *link = NULL; | ||
| 528 | uint64_t chlayout; | ||
| 352 | int i, j; | 529 | int i, j; |
| 530 | |||
| 531 | for (i = 0; i < filter->input_count; i++) { | ||
| 532 | link = filter->inputs[i]; | ||
| 533 | |||
| 534 | if (link->type == AVMEDIA_TYPE_AUDIO && | ||
| 535 | link->out_channel_layouts->nb_channel_layouts == 1) | ||
| 536 | break; | ||
| 537 | } | ||
| 538 | if (i == filter->input_count) | ||
| 539 | return; | ||
| 540 | |||
| 541 | chlayout = link->out_channel_layouts->channel_layouts[0]; | ||
| 542 | |||
| 543 | for (i = 0; i < filter->output_count; i++) { | ||
| 544 | AVFilterLink *outlink = filter->outputs[i]; | ||
| 545 | int best_idx, best_score = INT_MIN; | ||
| 546 | |||
| 547 | if (outlink->type != AVMEDIA_TYPE_AUDIO || | ||
| 548 | outlink->in_channel_layouts->nb_channel_layouts < 2) | ||
| 549 | continue; | ||
| 550 | |||
| 551 | for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) { | ||
| 552 | uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j]; | ||
| 553 | int matched_channels = av_get_channel_layout_nb_channels(chlayout & | ||
| 554 | out_chlayout); | ||
| 555 | int extra_channels = av_get_channel_layout_nb_channels(out_chlayout & | ||
| 556 | (~chlayout)); | ||
| 557 | int score = matched_channels - extra_channels; | ||
| 558 | |||
| 559 | if (score > best_score) { | ||
| 560 | best_score = score; | ||
| 561 | best_idx = j; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0], | ||
| 565 | outlink->in_channel_layouts->channel_layouts[best_idx]); | ||
| 566 | } | ||
| 567 | |||
| 568 | } | ||
| 569 | |||
| 570 | static void swap_channel_layouts(AVFilterGraph *graph) | ||
| 571 | { | ||
| 572 | int i; | ||
| 573 | |||
| 574 | for (i = 0; i < graph->filter_count; i++) | ||
| 575 | swap_channel_layouts_on_filter(graph->filters[i]); | ||
| 576 | } | ||
| 577 | |||
| 578 | static int pick_formats(AVFilterGraph *graph) | ||
| 579 | { | ||
| 580 | int i, j, ret; | ||
| 353 | int change; | 581 | int change; |
| 354 | 582 | ||
| 355 | do{ | 583 | do{ |
| @@ -385,13 +613,15 @@ static void pick_formats(AVFilterGraph *graph) · 29 unmodified lines | |||
| 385 | 613 | ||
| 386 | for (i = 0; i < graph->filter_count; i++) { | 614 | for (i = 0; i < graph->filter_count; i++) { |
| 387 | AVFilterContext *filter = graph->filters[i]; | 615 | AVFilterContext *filter = graph->filters[i]; |
| 388 | if (1) { | 616 | |
| 389 | for (j = 0; j < filter->input_count; j++) | 617 | for (j = 0; j < filter->input_count; j++) |
| 390 | pick_format(filter->inputs[j], NULL); | 618 | if ((ret = pick_format(filter->inputs[j], NULL)) < 0) |
| 391 | for (j = 0; j < filter->output_count; j++) | 619 | return ret; |
| 392 | pick_format(filter->outputs[j], NULL); | 620 | for (j = 0; j < filter->output_count; j++) |
| 393 | } | 621 | if ((ret = pick_format(filter->outputs[j], NULL)) < 0) |
| 622 | return ret; | ||
| 394 | } | 623 | } |
| 624 | return 0; | ||
| 395 | } | 625 | } |
| 396 | 626 | ||
| 397 | int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) | 627 | int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) |
| @@ -407,7 +637,13 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines | |||
| 407 | * of format conversion inside filters */ | 637 | * of format conversion inside filters */ |
| 408 | reduce_formats(graph); | 638 | reduce_formats(graph); |
| 409 | 639 | ||
| 410 | pick_formats(graph); | 640 | /* for audio filters, ensure the best sample rate and channel layout |
| 641 | * is selected */ | ||
| 642 | swap_samplerates(graph); | ||
| 643 | swap_channel_layouts(graph); | ||
| 644 | |||
| 645 | if ((ret = pick_formats(graph)) < 0) | ||
| 646 | return ret; | ||
| 411 | 647 | ||
| 412 | return 0; | 648 | return 0; |
| 413 | } | 649 | } |