This prevents the unneeded insertion of multiple aresample filters in some cases The format merging is moved to avoid having to call the channel layout merge twice. The channel layout merge code uses different structures and is not compatible with the added dry run wrappers.
Unified · Split
| @@ -360,6 +360,47 @@ static int formats_declared(AVFilterContext *f) · 359 unmodified lines | ||
| 360 | 360 | return 1; |
| 361 | 361 | } |
| 362 | 362 | |
| 363 | +static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg) | |
| 364 | +{ | |
| 365 | + AVFilterFormats *a = av_memdup(arg, sizeof(*arg)); | |
| 366 | + if (a) { | |
| 367 | + a->refcount = 0; | |
| 368 | + a->refs = NULL; | |
| 369 | + a->formats = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats); | |
| 370 | + if (!a->formats && arg->formats) | |
| 371 | + av_freep(&a); | |
| 372 | + } | |
| 373 | + return a; | |
| 374 | +} | |
| 375 | + | |
| 376 | +static int can_merge_formats(AVFilterFormats *a_arg, | |
| 377 | + AVFilterFormats *b_arg, | |
| 378 | + enum AVMediaType type, | |
| 379 | + int is_sample_rate) | |
| 380 | +{ | |
| 381 | + AVFilterFormats *a, *b, *ret; | |
| 382 | + if (a == b) | |
| 383 | + return 1; | |
| 384 | + a = clone_filter_formats(a_arg); | |
| 385 | + b = clone_filter_formats(b_arg); | |
| 386 | + if (is_sample_rate) { | |
| 387 | + ret = ff_merge_samplerates(a, b); | |
| 388 | + } else { | |
| 389 | + ret = ff_merge_formats(a, b, type); | |
| 390 | + } | |
| 391 | + if (ret) { | |
| 392 | + av_freep(&ret->formats); | |
| 393 | + av_freep(&ret); | |
| 394 | + return 1; | |
| 395 | + } else { | |
| 396 | + av_freep(&a->formats); | |
| 397 | + av_freep(&b->formats); | |
| 398 | + av_freep(&a); | |
| 399 | + av_freep(&b); | |
| 400 | + return 0; | |
| 401 | + } | |
| 402 | +} | |
| 403 | + | |
| 363 | 404 | /** |
| 364 | 405 | * Perform one round of query_formats() and merging formats lists on the |
| 365 | 406 | * filter graph. |
| @@ -404,20 +445,30 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 38 unmodified lines | ||
| 404 | 445 | if (!link) |
| 405 | 446 | continue; |
| 406 | 447 | |
| 448 | + if (link->in_formats != link->out_formats | |
| 449 | + && link->in_formats && link->out_formats) | |
| 450 | + if (!can_merge_formats(link->in_formats, link->out_formats, | |
| 451 | + link->type, 0)) | |
| 452 | + convert_needed = 1; | |
| 453 | + if (link->type == AVMEDIA_TYPE_AUDIO) { | |
| 454 | + if (link->in_samplerates != link->out_samplerates | |
| 455 | + && link->in_samplerates && link->out_samplerates) | |
| 456 | + if (!can_merge_formats(link->in_samplerates, | |
| 457 | + link->out_samplerates, | |
| 458 | + 0, 1)) | |
| 459 | + convert_needed = 1; | |
| 460 | + } | |
| 461 | + | |
| 407 | 462 | #define MERGE_DISPATCH(field, statement) \ |
| 408 | 463 | if (!(link->in_ ## field && link->out_ ## field)) { \ |
| 409 | 464 | count_delayed++; \ |
| 410 | 465 | } else if (link->in_ ## field == link->out_ ## field) { \ |
| 411 | 466 | count_already_merged++; \ |
| 412 | − } else { \ | |
| 467 | + } else if (!convert_needed) { \ | |
| 413 | 468 | count_merged++; \ |
| 414 | 469 | statement \ |
| 415 | 470 | } |
| 416 | − MERGE_DISPATCH(formats, | |
| 417 | − if (!ff_merge_formats(link->in_formats, link->out_formats, | |
| 418 | − link->type)) | |
| 419 | − convert_needed = 1; | |
| 420 | − ) | |
| 471 | + | |
| 421 | 472 | if (link->type == AVMEDIA_TYPE_AUDIO) { |
| 422 | 473 | MERGE_DISPATCH(channel_layouts, |
| 423 | 474 | if (!ff_merge_channel_layouts(link->in_channel_layouts, |
| @@ -430,6 +481,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 6 unmodified lines | ||
| 430 | 481 | convert_needed = 1; |
| 431 | 482 | ) |
| 432 | 483 | } |
| 484 | + MERGE_DISPATCH(formats, | |
| 485 | + if (!ff_merge_formats(link->in_formats, link->out_formats, | |
| 486 | + link->type)) | |
| 487 | + convert_needed = 1; | |
| 488 | + ) | |
| 433 | 489 | #undef MERGE_DISPATCH |
| 434 | 490 | |
| 435 | 491 | if (convert_needed) { |