|
|
@@ -360,6 +360,47 @@ static int formats_declared(AVFilterContext *f) |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg) |
|
|
|
{ |
|
|
|
AVFilterFormats *a = av_memdup(arg, sizeof(*arg)); |
|
|
|
if (a) { |
|
|
|
a->refcount = 0; |
|
|
|
a->refs = NULL; |
|
|
|
a->formats = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats); |
|
|
|
if (!a->formats && arg->formats) |
|
|
|
av_freep(&a); |
|
|
|
} |
|
|
|
return a; |
|
|
|
} |
|
|
|
|
|
|
|
static int can_merge_formats(AVFilterFormats *a_arg, |
|
|
|
AVFilterFormats *b_arg, |
|
|
|
enum AVMediaType type, |
|
|
|
int is_sample_rate) |
|
|
|
{ |
|
|
|
AVFilterFormats *a, *b, *ret; |
|
|
|
if (a == b) |
|
|
|
return 1; |
|
|
|
a = clone_filter_formats(a_arg); |
|
|
|
b = clone_filter_formats(b_arg); |
|
|
|
if (is_sample_rate) { |
|
|
|
ret = ff_merge_samplerates(a, b); |
|
|
|
} else { |
|
|
|
ret = ff_merge_formats(a, b, type); |
|
|
|
} |
|
|
|
if (ret) { |
|
|
|
av_freep(&ret->formats); |
|
|
|
av_freep(&ret); |
|
|
|
return 1; |
|
|
|
} else { |
|
|
|
av_freep(&a->formats); |
|
|
|
av_freep(&b->formats); |
|
|
|
av_freep(&a); |
|
|
|
av_freep(&b); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Perform one round of query_formats() and merging formats lists on the |
|
|
|
* filter graph. |
|
|
@@ -404,20 +445,30 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) |
|
|
|
if (!link) |
|
|
|
continue; |
|
|
|
|
|
|
|
if (link->in_formats != link->out_formats |
|
|
|
&& link->in_formats && link->out_formats) |
|
|
|
if (!can_merge_formats(link->in_formats, link->out_formats, |
|
|
|
link->type, 0)) |
|
|
|
convert_needed = 1; |
|
|
|
if (link->type == AVMEDIA_TYPE_AUDIO) { |
|
|
|
if (link->in_samplerates != link->out_samplerates |
|
|
|
&& link->in_samplerates && link->out_samplerates) |
|
|
|
if (!can_merge_formats(link->in_samplerates, |
|
|
|
link->out_samplerates, |
|
|
|
0, 1)) |
|
|
|
convert_needed = 1; |
|
|
|
} |
|
|
|
|
|
|
|
#define MERGE_DISPATCH(field, statement) \ |
|
|
|
if (!(link->in_ ## field && link->out_ ## field)) { \ |
|
|
|
count_delayed++; \ |
|
|
|
} else if (link->in_ ## field == link->out_ ## field) { \ |
|
|
|
count_already_merged++; \ |
|
|
|
} else { \ |
|
|
|
} else if (!convert_needed) { \ |
|
|
|
count_merged++; \ |
|
|
|
statement \ |
|
|
|
} |
|
|
|
MERGE_DISPATCH(formats, |
|
|
|
if (!ff_merge_formats(link->in_formats, link->out_formats, |
|
|
|
link->type)) |
|
|
|
convert_needed = 1; |
|
|
|
) |
|
|
|
|
|
|
|
if (link->type == AVMEDIA_TYPE_AUDIO) { |
|
|
|
MERGE_DISPATCH(channel_layouts, |
|
|
|
if (!ff_merge_channel_layouts(link->in_channel_layouts, |
|
|
@@ -430,6 +481,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) |
|
|
|
convert_needed = 1; |
|
|
|
) |
|
|
|
} |
|
|
|
MERGE_DISPATCH(formats, |
|
|
|
if (!ff_merge_formats(link->in_formats, link->out_formats, |
|
|
|
link->type)) |
|
|
|
convert_needed = 1; |
|
|
|
) |
|
|
|
#undef MERGE_DISPATCH |
|
|
|
|
|
|
|
if (convert_needed) { |
|
|
|