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
372372 return 1;
373373 }
374374
375−static 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−
388−static 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−
430375 /**
431376 * Perform one round of query_formats() and merging formats lists on the
432377 * filter graph.
@@ -473,45 +418,40 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 40 unmodified lines
473418
474419 if (link->in_formats != link->out_formats
475420 && link->in_formats && link->out_formats)
476− if (!can_merge_formats(link->in_formats, link->out_formats,
477− link->type, 0))
421+ if (!ff_can_merge_formats(link->in_formats, link->out_formats,
422+ link->type))
478423 convert_needed = 1;
479424 if (link->type == AVMEDIA_TYPE_AUDIO) {
480425 if (link->in_samplerates != link->out_samplerates
481426 && link->in_samplerates && link->out_samplerates)
482− if (!can_merge_formats(link->in_samplerates,
483− link->out_samplerates,
484− 0, 1))
427+ if (!ff_can_merge_samplerates(link->in_samplerates,
428+ link->out_samplerates))
485429 convert_needed = 1;
486430 }
487431
488−#define MERGE_DISPATCH(field, statement) \
432+#define CHECKED_MERGE(field, ...) ((ret = ff_merge_ ## field(__VA_ARGS__)) <= 0)
433+#define MERGE_DISPATCH(field, ...) \
489434 if (!(link->in_ ## field && link->out_ ## field)) { \
490435 count_delayed++; \
491436 } else if (link->in_ ## field == link->out_ ## field) { \
492437 count_already_merged++; \
493438 } else if (!convert_needed) { \
494439 count_merged++; \
495− statement \
440+ if (CHECKED_MERGE(field, __VA_ARGS__)) { \
441+ if (ret < 0) \
442+ return ret; \
443+ convert_needed = 1; \
444+ } \
496445 }
497446
498447 if (link->type == AVMEDIA_TYPE_AUDIO) {
499− MERGE_DISPATCH(channel_layouts,
500− if (!ff_merge_channel_layouts(link->in_channel_layouts,
501− link->out_channel_layouts))
502− convert_needed = 1;
503− )
504− MERGE_DISPATCH(samplerates,
505− if (!ff_merge_samplerates(link->in_samplerates,
506− link->out_samplerates))
507− convert_needed = 1;
508− )
448+ MERGE_DISPATCH(channel_layouts, link->in_channel_layouts,
449+ link->out_channel_layouts)
450+ MERGE_DISPATCH(samplerates, link->in_samplerates,
451+ link->out_samplerates)
509452 }
510− MERGE_DISPATCH(formats,
511− if (!ff_merge_formats(link->in_formats, link->out_formats,
512− link->type))
513− convert_needed = 1;
514− )
453+ MERGE_DISPATCH(formats, link->in_formats,
454+ link->out_formats, link->type)
515455 #undef MERGE_DISPATCH
516456
517457 if (convert_needed) {
@@ -585,27 +525,26 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 67 unmodified lines
585525 av_assert0(outlink-> in_channel_layouts->refcount > 0);
586526 av_assert0(outlink->out_channel_layouts->refcount > 0);
587527 }
588− if (!ff_merge_formats( inlink->in_formats, inlink->out_formats, inlink->type) ||
589− !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
590− ret = AVERROR(ENOSYS);
591− if (inlink->type == AVMEDIA_TYPE_AUDIO &&
592− (!ff_merge_samplerates(inlink->in_samplerates,
593− inlink->out_samplerates) ||
594− !ff_merge_channel_layouts(inlink->in_channel_layouts,
595− inlink->out_channel_layouts)))
596− ret = AVERROR(ENOSYS);
597− if (outlink->type == AVMEDIA_TYPE_AUDIO &&
598− (!ff_merge_samplerates(outlink->in_samplerates,
599− outlink->out_samplerates) ||
600− !ff_merge_channel_layouts(outlink->in_channel_layouts,
601− outlink->out_channel_layouts)))
602− ret = AVERROR(ENOSYS);
603−
604− if (ret < 0) {
528+ if (CHECKED_MERGE(formats, inlink->in_formats,
529+ inlink->out_formats, inlink->type) ||
530+ CHECKED_MERGE(formats, outlink->in_formats,
531+ outlink->out_formats, outlink->type) ||
532+ inlink->type == AVMEDIA_TYPE_AUDIO &&
533+ (CHECKED_MERGE(samplerates, inlink->in_samplerates,
534+ inlink->out_samplerates) ||
535+ CHECKED_MERGE(channel_layouts, inlink->in_channel_layouts,
536+ inlink->out_channel_layouts)) ||
537+ outlink->type == AVMEDIA_TYPE_AUDIO &&
538+ (CHECKED_MERGE(samplerates, outlink->in_samplerates,
539+ outlink->out_samplerates) ||
540+ CHECKED_MERGE(channel_layouts, outlink->in_channel_layouts,
541+ outlink->out_channel_layouts))) {
542+ if (ret < 0)
543+ return ret;
605544 av_log(log_ctx, AV_LOG_ERROR,
606545 "Impossible to convert between the formats supported by the filter "
607546 "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
608− return ret;
547+ return AVERROR(ENOSYS);
609548 }
610549 }
611550 }

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