aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/avfiltergraph.c
diff options
context:
space:
mode:
authorNicolas George <george@nsup.org>2021-07-24 17:06:53 +0200
committerNicolas George <george@nsup.org>2021-08-14 09:17:45 +0200
commit86d3dd5627b5c8c179aa48c7e4834a69371a14e6 (patch)
tree5287b075f7c97a7a9296a3d6898491a5d8768fa9 /libavfilter/avfiltergraph.c
parent1d8e1afc009f2a916f672fc57f4971504bb13fb3 (diff)
downloadffmpeg-86d3dd5627b5c8c179aa48c7e4834a69371a14e6.tar.gz
lavfi/formats: put merge functions in structures.
It makes the code clearer and will allow adding new stages of negotiation easier.
Diffstat (limited to 'libavfilter/avfiltergraph.c')
-rw-r--r--libavfilter/avfiltergraph.c96
1 files changed, 42 insertions, 54 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 148eeba91a..8342e21769 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -456,48 +456,41 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
for (j = 0; j < filter->nb_inputs; j++) {
AVFilterLink *link = filter->inputs[j];
+ const AVFilterNegotiation *neg;
+ unsigned neg_step;
int convert_needed = 0;
if (!link)
continue;
- if (link->incfg.formats != link->outcfg.formats
- && link->incfg.formats && link->outcfg.formats)
- if (!ff_can_merge_formats(link->incfg.formats, link->outcfg.formats,
- link->type))
+ neg = ff_filter_get_negotiation(link);
+ av_assert0(neg);
+ for (neg_step = 1; neg_step < neg->nb; neg_step++) {
+ const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
+ void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
+ void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
+ if (a && b && a != b && !m->can_merge(a, b)) {
convert_needed = 1;
- if (link->type == AVMEDIA_TYPE_AUDIO) {
- if (link->incfg.samplerates != link->outcfg.samplerates
- && link->incfg.samplerates && link->outcfg.samplerates)
- if (!ff_can_merge_samplerates(link->incfg.samplerates,
- link->outcfg.samplerates))
- convert_needed = 1;
- }
-
-#define CHECKED_MERGE(field, ...) ((ret = ff_merge_ ## field(__VA_ARGS__)) <= 0)
-#define MERGE_DISPATCH(field, ...) \
- if (!(link->incfg.field && link->outcfg.field)) { \
- count_delayed++; \
- } else if (link->incfg.field == link->outcfg.field) { \
- count_already_merged++; \
- } else if (!convert_needed) { \
- count_merged++; \
- if (CHECKED_MERGE(field, __VA_ARGS__)) { \
- if (ret < 0) \
- return ret; \
- convert_needed = 1; \
- } \
+ break;
+ }
}
-
- if (link->type == AVMEDIA_TYPE_AUDIO) {
- MERGE_DISPATCH(channel_layouts, link->incfg.channel_layouts,
- link->outcfg.channel_layouts)
- MERGE_DISPATCH(samplerates, link->incfg.samplerates,
- link->outcfg.samplerates)
+ for (neg_step = 0; neg_step < neg->nb; neg_step++) {
+ const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
+ void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
+ void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
+ if (!(a && b)) {
+ count_delayed++;
+ } else if (a == b) {
+ count_already_merged++;
+ } else if (!convert_needed) {
+ count_merged++;
+ ret = m->merge(a, b);
+ if (ret < 0)
+ return ret;
+ if (!ret)
+ convert_needed = 1;
+ }
}
- MERGE_DISPATCH(formats, link->incfg.formats,
- link->outcfg.formats, link->type)
-#undef MERGE_DISPATCH
if (convert_needed) {
AVFilterContext *convert;
@@ -570,26 +563,21 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
}
- if (CHECKED_MERGE(formats, inlink->incfg.formats,
- inlink->outcfg.formats, inlink->type) ||
- CHECKED_MERGE(formats, outlink->incfg.formats,
- outlink->outcfg.formats, outlink->type) ||
- inlink->type == AVMEDIA_TYPE_AUDIO &&
- (CHECKED_MERGE(samplerates, inlink->incfg.samplerates,
- inlink->outcfg.samplerates) ||
- CHECKED_MERGE(channel_layouts, inlink->incfg.channel_layouts,
- inlink->outcfg.channel_layouts)) ||
- outlink->type == AVMEDIA_TYPE_AUDIO &&
- (CHECKED_MERGE(samplerates, outlink->incfg.samplerates,
- outlink->outcfg.samplerates) ||
- CHECKED_MERGE(channel_layouts, outlink->incfg.channel_layouts,
- outlink->outcfg.channel_layouts))) {
- if (ret < 0)
- return ret;
- av_log(log_ctx, AV_LOG_ERROR,
- "Impossible to convert between the formats supported by the filter "
- "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
- return AVERROR(ENOSYS);
+ for (neg_step = 0; neg_step < neg->nb; neg_step++) {
+ const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
+ void *ia = FF_FIELD_AT(void *, m->offset, inlink->incfg);
+ void *ib = FF_FIELD_AT(void *, m->offset, inlink->outcfg);
+ void *oa = FF_FIELD_AT(void *, m->offset, outlink->incfg);
+ void *ob = FF_FIELD_AT(void *, m->offset, outlink->outcfg);
+ if ((ret = m->merge(ia, ib)) <= 0 ||
+ (ret = m->merge(oa, ob)) <= 0) {
+ if (ret < 0)
+ return ret;
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Impossible to convert between the formats supported by the filter "
+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+ return AVERROR(ENOSYS);
+ }
}
}
}