+#define FORMATS_CHANGEREF(oldref, newref) \
+do { \
+ int idx = -1; \
+ \
+ FIND_REF_INDEX(oldref, idx); \
+ \
+ if (idx >= 0) { \
+ (*oldref)->refs[idx] = newref; \
+ *newref = *oldref; \
+ *oldref = NULL; \
+ } \
+} while (0)
+
+void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
+ AVFilterChannelLayouts **newref)
+{
+ FORMATS_CHANGEREF(oldref, newref);
+}
+
+void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
+{
+ FORMATS_CHANGEREF(oldref, newref);
+}
+
+#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
+{ \
+ int count = 0, i; \
+ \
+ for (i = 0; i < ctx->nb_inputs; i++) { \
+ if (ctx->inputs[i]) { \
+ ref(fmts, &ctx->inputs[i]->out_fmts); \
+ count++; \
+ } \
+ } \
+ for (i = 0; i < ctx->nb_outputs; i++) { \
+ if (ctx->outputs[i]) { \
+ ref(fmts, &ctx->outputs[i]->in_fmts); \
+ count++; \
+ } \
+ } \
+ \
+ if (!count) { \
+ av_freep(&fmts->list); \
+ av_freep(&fmts->refs); \
+ av_freep(&fmts); \
+ } \
+}
+
+void ff_set_common_channel_layouts(AVFilterContext *ctx,
+ AVFilterChannelLayouts *layouts)
+{
+ SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
+ ff_channel_layouts_ref, channel_layouts);
+}
+
+void ff_set_common_samplerates(AVFilterContext *ctx,
+ AVFilterFormats *samplerates)
+{
+ SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
+ ff_formats_ref, formats);
+}
+
+/**
+ * A helper for query_formats() which sets all links to the same list of
+ * formats. If there are no links hooked to this filter, the list of formats is
+ * freed.
+ */
+void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+ SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
+ ff_formats_ref, formats);