History

avfilter/formats: Factor checking for mergeability out of ff_merge_*

The callers of the ff_merge_*() functions fall into two categories with quite different needs: One caller is can_merge_formats() which only wants to test for mergeability without it merging anything. In order to do so, it duplicates the lists it intends to test and resets their owners so that they are not modified by ff_merge_*(). It also means that it needs to receive the merged list (and not only an int containing whether the lists are mergeable) to properly free it. The other callers want the lists to be actually merged. But given the fact that ff_merge_*() automatically updates the owners of the lists, they only want the information whether the merge succeeded or not; they don't want a link to the new list. Therefore this commit splits these functions in two: ff_merge_*() for the latter callers and ff_can_merge_*() for the former. ff_merge_*() doesn't need to return a pointer to the combined list at all and hence these functions have been modified to return an int, which allows to distinguish between incompability and memory allocation failures. ff_can_merge_*() meanwhile doesn't modify its arguments at all obviating the need for copies. This in turn implies that there is no reason to return a pointer to the new list, as nothing needs to be freed. These functions therefore return an int as well. This allowed to completely remove can_merge_formats() in avfiltergraph.c. Notice that no ff_can_merge_channel_layouts() has been created, because there is currently no caller for this. It could be added if needed.

Andreas Rheinhardt committed 6 years ago

Commit 06754f71 parent 363f9343 files · +120 −144Browse files

Showing the changes to libavfilter/avfiltergraph.c (1 of 3 files). Show all

Unified · Split

libavfilter/avfiltergraph.c+34−95
@@ -372,61 +372,6 @@ static int formats_declared(AVFilterContext *f) · 371 unmodified lines
372 return 1;372 return 1;
373}373}
374 374
375static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg)
376{
377 AVFilterFormats *a = av_memdup(arg, sizeof(*arg));
378 if (a) {
379 a->refcount = 0;
380 a->refs = NULL;
381 a->formats = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats);
382 if (!a->formats && arg->formats)
383 av_freep(&a);
384 }
385 return a;
386}
387
388static int can_merge_formats(AVFilterFormats *a_arg,
389 AVFilterFormats *b_arg,
390 enum AVMediaType type,
391 int is_sample_rate)
392{
393 AVFilterFormats *a, *b, *ret;
394 if (a_arg == b_arg)
395 return 1;
396 a = clone_filter_formats(a_arg);
397 b = clone_filter_formats(b_arg);
398
399 if (!a || !b) {
400 if (a)
401 av_freep(&a->formats);
402 if (b)
403 av_freep(&b->formats);
404
405 av_freep(&a);
406 av_freep(&b);
407
408 return 0;
409 }
410
411 if (is_sample_rate) {
412 ret = ff_merge_samplerates(a, b);
413 } else {
414 ret = ff_merge_formats(a, b, type);
415 }
416 if (ret) {
417 av_freep(&ret->formats);
418 av_freep(&ret->refs);
419 av_freep(&ret);
420 return 1;
421 } else {
422 av_freep(&a->formats);
423 av_freep(&b->formats);
424 av_freep(&a);
425 av_freep(&b);
426 return 0;
427 }
428}
429
430/**375/**
431 * Perform one round of query_formats() and merging formats lists on the376 * Perform one round of query_formats() and merging formats lists on the
432 * filter graph.377 * filter graph.
@@ -473,45 +418,40 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 40 unmodified lines
473 418
474 if (link->in_formats != link->out_formats419 if (link->in_formats != link->out_formats
475 && link->in_formats && link->out_formats)420 && link->in_formats && link->out_formats)
476 if (!can_merge_formats(link->in_formats, link->out_formats,421 if (!ff_can_merge_formats(link->in_formats, link->out_formats,
477 link->type, 0))422 link->type))
478 convert_needed = 1;423 convert_needed = 1;
479 if (link->type == AVMEDIA_TYPE_AUDIO) {424 if (link->type == AVMEDIA_TYPE_AUDIO) {
480 if (link->in_samplerates != link->out_samplerates425 if (link->in_samplerates != link->out_samplerates
481 && link->in_samplerates && link->out_samplerates)426 && link->in_samplerates && link->out_samplerates)
482 if (!can_merge_formats(link->in_samplerates,427 if (!ff_can_merge_samplerates(link->in_samplerates,
483 link->out_samplerates,428 link->out_samplerates))
484 0, 1))
485 convert_needed = 1;429 convert_needed = 1;
486 }430 }
487 431
488#define MERGE_DISPATCH(field, statement) \432#define CHECKED_MERGE(field, ...) ((ret = ff_merge_ ## field(__VA_ARGS__)) <= 0)
433#define MERGE_DISPATCH(field, ...) \
489 if (!(link->in_ ## field && link->out_ ## field)) { \434 if (!(link->in_ ## field && link->out_ ## field)) { \
490 count_delayed++; \435 count_delayed++; \
491 } else if (link->in_ ## field == link->out_ ## field) { \436 } else if (link->in_ ## field == link->out_ ## field) { \
492 count_already_merged++; \437 count_already_merged++; \
493 } else if (!convert_needed) { \438 } else if (!convert_needed) { \
494 count_merged++; \439 count_merged++; \
495 statement \440 if (CHECKED_MERGE(field, __VA_ARGS__)) { \
441 if (ret < 0) \
442 return ret; \
443 convert_needed = 1; \
444 } \
496 }445 }
497 446
498 if (link->type == AVMEDIA_TYPE_AUDIO) {447 if (link->type == AVMEDIA_TYPE_AUDIO) {
499 MERGE_DISPATCH(channel_layouts,448 MERGE_DISPATCH(channel_layouts, link->in_channel_layouts,
500 if (!ff_merge_channel_layouts(link->in_channel_layouts,449 link->out_channel_layouts)
501 link->out_channel_layouts))450 MERGE_DISPATCH(samplerates, link->in_samplerates,
502 convert_needed = 1;451 link->out_samplerates)
503 )
504 MERGE_DISPATCH(samplerates,
505 if (!ff_merge_samplerates(link->in_samplerates,
506 link->out_samplerates))
507 convert_needed = 1;
508 )
509 }452 }
510 MERGE_DISPATCH(formats,453 MERGE_DISPATCH(formats, link->in_formats,
511 if (!ff_merge_formats(link->in_formats, link->out_formats,454 link->out_formats, link->type)
512 link->type))
513 convert_needed = 1;
514 )
515#undef MERGE_DISPATCH455#undef MERGE_DISPATCH
516 456
517 if (convert_needed) {457 if (convert_needed) {
@@ -585,27 +525,26 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 67 unmodified lines
585 av_assert0(outlink-> in_channel_layouts->refcount > 0);525 av_assert0(outlink-> in_channel_layouts->refcount > 0);
586 av_assert0(outlink->out_channel_layouts->refcount > 0);526 av_assert0(outlink->out_channel_layouts->refcount > 0);
587 }527 }
588 if (!ff_merge_formats( inlink->in_formats, inlink->out_formats, inlink->type) ||528 if (CHECKED_MERGE(formats, inlink->in_formats,
589 !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))529 inlink->out_formats, inlink->type) ||
590 ret = AVERROR(ENOSYS);530 CHECKED_MERGE(formats, outlink->in_formats,
591 if (inlink->type == AVMEDIA_TYPE_AUDIO &&531 outlink->out_formats, outlink->type) ||
592 (!ff_merge_samplerates(inlink->in_samplerates,532 inlink->type == AVMEDIA_TYPE_AUDIO &&
593 inlink->out_samplerates) ||533 (CHECKED_MERGE(samplerates, inlink->in_samplerates,
594 !ff_merge_channel_layouts(inlink->in_channel_layouts,534 inlink->out_samplerates) ||
595 inlink->out_channel_layouts)))535 CHECKED_MERGE(channel_layouts, inlink->in_channel_layouts,
596 ret = AVERROR(ENOSYS);536 inlink->out_channel_layouts)) ||
597 if (outlink->type == AVMEDIA_TYPE_AUDIO &&537 outlink->type == AVMEDIA_TYPE_AUDIO &&
598 (!ff_merge_samplerates(outlink->in_samplerates,538 (CHECKED_MERGE(samplerates, outlink->in_samplerates,
599 outlink->out_samplerates) ||539 outlink->out_samplerates) ||
600 !ff_merge_channel_layouts(outlink->in_channel_layouts,540 CHECKED_MERGE(channel_layouts, outlink->in_channel_layouts,
601 outlink->out_channel_layouts)))541 outlink->out_channel_layouts))) {
602 ret = AVERROR(ENOSYS);542 if (ret < 0)
603 543 return ret;
604 if (ret < 0) {
605 av_log(log_ctx, AV_LOG_ERROR,544 av_log(log_ctx, AV_LOG_ERROR,
606 "Impossible to convert between the formats supported by the filter "545 "Impossible to convert between the formats supported by the filter "
607 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);546 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
608 return ret;547 return AVERROR(ENOSYS);
609 }548 }
610 }549 }
611 }550 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t