diff mbox series

[FFmpeg-devel,004/218] avfilter: Replace query_formats callback with union of list and callback

Message ID PR3PR03MB666512A57AA573C44A8E22338FAA9@PR3PR03MB6665.eurprd03.prod.outlook.com
State Accepted
Headers show
Series [FFmpeg-devel,001/218] avfilter/f_reverse: Don't use redundant query_formats function
Related show

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Andreas Rheinhardt Sept. 30, 2021, 1:39 p.m. UTC
If one looks at the many query_formats callbacks in existence,
one will immediately recognize that there is one type of default
callback for video and a slightly different default callback for
audio: It is "return ff_set_common_formats_from_list(ctx, pix_fmts);"
for video with a filter-specific pix_fmts list. For audio, it is
the same with a filter-specific sample_fmts list together with
ff_set_common_all_samplerates() and ff_set_common_all_channel_counts().

This commit allows to remove the boilerplate query_formats callbacks
by replacing said callback with a union consisting the old callback
and pointers for pixel and sample format arrays. For the not uncommon
case in which these lists only contain a single entry (besides the
sentinel) enum AVPixelFormat and enum AVSampleFormat fields are also
added to the union to store them directly in the AVFilter,
thereby avoiding a relocation.

The state of said union will be contained in a new, dedicated AVFilter
field (the nb_inputs and nb_outputs fields have been shrunk to uint8_t
in order to create a hole for this new field; this is no problem, as
the maximum of all the nb_inputs is four; for nb_outputs it is only
two).

The state's default value coincides with the earlier default of
query_formats being unset, namely that the filter accepts all formats
(and also sample rates and channel counts/layouts for audio)
provided that these properties agree coincide for all inputs and
outputs.

By using different union members for audio and video filters
the type-unsafety of using the same functions for audio and video
lists will furthermore be more confined to formats.c than before.

When the new fields are used, they will also avoid allocations:
Currently something nearly equivalent to ff_default_query_formats()
is called after every successful call to a query_formats callback;
yet in the common case that the newly allocated AVFilterFormats
are not used at all (namely if there are no free links) these newly
allocated AVFilterFormats are freed again without ever being used.
Filters no longer using the callback will not exhibit this any more.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
This patchset here aims to remove boilerplate code from the
query-formats API. Despite touching lots of filters, there should be
only very few conflicts (if at all) with Nicolas' earlier patch [1].
The reason for this is that the filters touched here typically only
use ff_set_common_* functions, which are unaffected by his change.

I will not send everything; those who wish to do so can take a look
at [2].

[1]: https://patchwork.ffmpeg.org/project/ffmpeg/patch/20210820090907.249707-1-george@nsup.org/
[2]: https://github.com/mkver/FFmpeg/commits/query_formats3

 libavfilter/aeval.c                 |  4 +--
 libavfilter/af_acontrast.c          |  2 +-
 libavfilter/af_acrossover.c         |  2 +-
 libavfilter/af_acrusher.c           |  2 +-
 libavfilter/af_adeclick.c           |  4 +--
 libavfilter/af_adecorrelate.c       |  2 +-
 libavfilter/af_adelay.c             |  2 +-
 libavfilter/af_adenorm.c            |  2 +-
 libavfilter/af_aderivative.c        |  4 +--
 libavfilter/af_aecho.c              |  2 +-
 libavfilter/af_aemphasis.c          |  2 +-
 libavfilter/af_aexciter.c           |  2 +-
 libavfilter/af_afade.c              |  4 +--
 libavfilter/af_afftdn.c             |  2 +-
 libavfilter/af_afftfilt.c           |  2 +-
 libavfilter/af_afir.c               |  2 +-
 libavfilter/af_aformat.c            |  2 +-
 libavfilter/af_afreqshift.c         |  4 +--
 libavfilter/af_afwtdn.c             |  2 +-
 libavfilter/af_agate.c              |  4 +--
 libavfilter/af_aiir.c               |  2 +-
 libavfilter/af_alimiter.c           |  2 +-
 libavfilter/af_amerge.c             |  2 +-
 libavfilter/af_amix.c               |  2 +-
 libavfilter/af_amultiply.c          |  2 +-
 libavfilter/af_anequalizer.c        |  2 +-
 libavfilter/af_anlmdn.c             |  2 +-
 libavfilter/af_anlms.c              |  2 +-
 libavfilter/af_aphaser.c            |  2 +-
 libavfilter/af_apsyclip.c           |  2 +-
 libavfilter/af_apulsator.c          |  2 +-
 libavfilter/af_aresample.c          |  2 +-
 libavfilter/af_arnndn.c             |  2 +-
 libavfilter/af_asetrate.c           |  2 +-
 libavfilter/af_asoftclip.c          |  2 +-
 libavfilter/af_asr.c                |  2 +-
 libavfilter/af_astats.c             |  2 +-
 libavfilter/af_asubboost.c          |  2 +-
 libavfilter/af_asupercut.c          |  8 ++---
 libavfilter/af_atempo.c             |  2 +-
 libavfilter/af_atilt.c              |  2 +-
 libavfilter/af_axcorrelate.c        |  2 +-
 libavfilter/af_biquads.c            |  2 +-
 libavfilter/af_bs2b.c               |  2 +-
 libavfilter/af_channelmap.c         |  2 +-
 libavfilter/af_channelsplit.c       |  2 +-
 libavfilter/af_chorus.c             |  2 +-
 libavfilter/af_compand.c            |  2 +-
 libavfilter/af_compensationdelay.c  |  2 +-
 libavfilter/af_crossfeed.c          |  2 +-
 libavfilter/af_crystalizer.c        |  2 +-
 libavfilter/af_dcshift.c            |  2 +-
 libavfilter/af_deesser.c            |  2 +-
 libavfilter/af_drmeter.c            |  2 +-
 libavfilter/af_dynaudnorm.c         |  2 +-
 libavfilter/af_earwax.c             |  2 +-
 libavfilter/af_extrastereo.c        |  2 +-
 libavfilter/af_firequalizer.c       |  2 +-
 libavfilter/af_flanger.c            |  2 +-
 libavfilter/af_haas.c               |  2 +-
 libavfilter/af_hdcd.c               |  2 +-
 libavfilter/af_headphone.c          |  2 +-
 libavfilter/af_join.c               |  2 +-
 libavfilter/af_ladspa.c             |  2 +-
 libavfilter/af_loudnorm.c           |  2 +-
 libavfilter/af_lv2.c                |  2 +-
 libavfilter/af_mcompand.c           |  2 +-
 libavfilter/af_pan.c                |  2 +-
 libavfilter/af_replaygain.c         |  2 +-
 libavfilter/af_rubberband.c         |  2 +-
 libavfilter/af_sidechaincompress.c  |  4 +--
 libavfilter/af_silencedetect.c      |  2 +-
 libavfilter/af_silenceremove.c      |  2 +-
 libavfilter/af_sofalizer.c          |  2 +-
 libavfilter/af_speechnorm.c         |  2 +-
 libavfilter/af_stereotools.c        |  2 +-
 libavfilter/af_stereowiden.c        |  2 +-
 libavfilter/af_superequalizer.c     |  2 +-
 libavfilter/af_surround.c           |  2 +-
 libavfilter/af_tremolo.c            |  2 +-
 libavfilter/af_vibrato.c            |  2 +-
 libavfilter/af_volume.c             |  2 +-
 libavfilter/af_volumedetect.c       |  2 +-
 libavfilter/asrc_afirsrc.c          |  2 +-
 libavfilter/asrc_anoisesrc.c        |  2 +-
 libavfilter/asrc_anullsrc.c         |  2 +-
 libavfilter/asrc_flite.c            |  2 +-
 libavfilter/asrc_hilbert.c          |  2 +-
 libavfilter/asrc_sinc.c             |  2 +-
 libavfilter/asrc_sine.c             |  2 +-
 libavfilter/avf_abitscope.c         |  2 +-
 libavfilter/avf_ahistogram.c        |  2 +-
 libavfilter/avf_aphasemeter.c       |  2 +-
 libavfilter/avf_avectorscope.c      |  2 +-
 libavfilter/avf_concat.c            |  2 +-
 libavfilter/avf_showcqt.c           |  2 +-
 libavfilter/avf_showfreqs.c         |  2 +-
 libavfilter/avf_showspatial.c       |  2 +-
 libavfilter/avf_showspectrum.c      |  4 +--
 libavfilter/avf_showvolume.c        |  2 +-
 libavfilter/avf_showwaves.c         |  4 +--
 libavfilter/avfilter.h              | 52 +++++++++++++++++++++++++----
 libavfilter/avfiltergraph.c         |  4 +--
 libavfilter/buffersink.c            |  4 +--
 libavfilter/buffersrc.c             |  4 +--
 libavfilter/f_drawgraph.c           |  4 +--
 libavfilter/f_ebur128.c             |  2 +-
 libavfilter/f_graphmonitor.c        |  4 +--
 libavfilter/f_select.c              |  2 +-
 libavfilter/f_streamselect.c        |  4 +--
 libavfilter/formats.c               | 36 +++++++++++++++++---
 libavfilter/internal.h              | 39 ++++++++++++++++++++++
 libavfilter/src_movie.c             |  4 +--
 libavfilter/tests/filtfmts.c        |  4 +--
 libavfilter/vaf_spectrumsynth.c     |  2 +-
 libavfilter/vf_alphamerge.c         |  2 +-
 libavfilter/vf_amplify.c            |  2 +-
 libavfilter/vf_atadenoise.c         |  2 +-
 libavfilter/vf_avgblur.c            |  2 +-
 libavfilter/vf_avgblur_opencl.c     |  4 +--
 libavfilter/vf_avgblur_vulkan.c     |  2 +-
 libavfilter/vf_bbox.c               |  2 +-
 libavfilter/vf_bilateral.c          |  2 +-
 libavfilter/vf_bitplanenoise.c      |  2 +-
 libavfilter/vf_blackdetect.c        |  2 +-
 libavfilter/vf_blackframe.c         |  2 +-
 libavfilter/vf_blend.c              |  4 +--
 libavfilter/vf_bm3d.c               |  2 +-
 libavfilter/vf_boxblur.c            |  2 +-
 libavfilter/vf_bwdif.c              |  2 +-
 libavfilter/vf_cas.c                |  2 +-
 libavfilter/vf_chromaber_vulkan.c   |  2 +-
 libavfilter/vf_chromakey.c          |  4 +--
 libavfilter/vf_chromanr.c           |  2 +-
 libavfilter/vf_chromashift.c        |  4 +--
 libavfilter/vf_ciescope.c           |  2 +-
 libavfilter/vf_codecview.c          |  2 +-
 libavfilter/vf_colorbalance.c       |  2 +-
 libavfilter/vf_colorchannelmixer.c  |  2 +-
 libavfilter/vf_colorconstancy.c     |  2 +-
 libavfilter/vf_colorcontrast.c      |  2 +-
 libavfilter/vf_colorcorrect.c       |  2 +-
 libavfilter/vf_colorize.c           |  2 +-
 libavfilter/vf_colorkey.c           |  4 +--
 libavfilter/vf_colorkey_opencl.c    |  2 +-
 libavfilter/vf_colorlevels.c        |  2 +-
 libavfilter/vf_colormatrix.c        |  2 +-
 libavfilter/vf_colorspace.c         |  2 +-
 libavfilter/vf_colortemperature.c   |  2 +-
 libavfilter/vf_convolution.c        | 12 +++----
 libavfilter/vf_convolution_opencl.c |  8 ++---
 libavfilter/vf_convolve.c           |  4 +--
 libavfilter/vf_copy.c               |  2 +-
 libavfilter/vf_coreimage.m          |  4 +--
 libavfilter/vf_cover_rect.c         |  2 +-
 libavfilter/vf_crop.c               |  2 +-
 libavfilter/vf_cropdetect.c         |  2 +-
 libavfilter/vf_curves.c             |  2 +-
 libavfilter/vf_datascope.c          |  6 ++--
 libavfilter/vf_dblur.c              |  2 +-
 libavfilter/vf_dctdnoiz.c           |  2 +-
 libavfilter/vf_deband.c             |  2 +-
 libavfilter/vf_deblock.c            |  2 +-
 libavfilter/vf_decimate.c           |  2 +-
 libavfilter/vf_dedot.c              |  2 +-
 libavfilter/vf_deflicker.c          |  2 +-
 libavfilter/vf_deinterlace_qsv.c    |  2 +-
 libavfilter/vf_deinterlace_vaapi.c  |  2 +-
 libavfilter/vf_delogo.c             |  2 +-
 libavfilter/vf_derain.c             |  2 +-
 libavfilter/vf_deshake.c            |  2 +-
 libavfilter/vf_deshake_opencl.c     |  2 +-
 libavfilter/vf_despill.c            |  2 +-
 libavfilter/vf_detelecine.c         |  2 +-
 libavfilter/vf_displace.c           |  2 +-
 libavfilter/vf_dnn_classify.c       |  2 +-
 libavfilter/vf_dnn_detect.c         |  2 +-
 libavfilter/vf_dnn_processing.c     |  2 +-
 libavfilter/vf_drawbox.c            |  4 +--
 libavfilter/vf_drawtext.c           |  2 +-
 libavfilter/vf_edgedetect.c         |  2 +-
 libavfilter/vf_elbg.c               |  2 +-
 libavfilter/vf_entropy.c            |  2 +-
 libavfilter/vf_epx.c                |  2 +-
 libavfilter/vf_eq.c                 |  2 +-
 libavfilter/vf_estdif.c             |  2 +-
 libavfilter/vf_exposure.c           |  2 +-
 libavfilter/vf_extractplanes.c      |  4 +--
 libavfilter/vf_fade.c               |  2 +-
 libavfilter/vf_fftdnoiz.c           |  2 +-
 libavfilter/vf_fftfilt.c            |  2 +-
 libavfilter/vf_fieldhint.c          |  2 +-
 libavfilter/vf_fieldmatch.c         |  2 +-
 libavfilter/vf_fieldorder.c         |  2 +-
 libavfilter/vf_fillborders.c        |  2 +-
 libavfilter/vf_find_rect.c          |  2 +-
 libavfilter/vf_floodfill.c          |  2 +-
 libavfilter/vf_format.c             |  8 ++---
 libavfilter/vf_framepack.c          |  2 +-
 libavfilter/vf_framerate.c          |  2 +-
 libavfilter/vf_freezedetect.c       |  2 +-
 libavfilter/vf_frei0r.c             |  4 +--
 libavfilter/vf_fspp.c               |  2 +-
 libavfilter/vf_gblur.c              |  2 +-
 libavfilter/vf_geq.c                |  2 +-
 libavfilter/vf_gradfun.c            |  2 +-
 libavfilter/vf_grayworld.c          |  2 +-
 libavfilter/vf_guided.c             |  2 +-
 libavfilter/vf_hflip.c              |  2 +-
 libavfilter/vf_histeq.c             |  2 +-
 libavfilter/vf_histogram.c          |  4 +--
 libavfilter/vf_hqdn3d.c             |  2 +-
 libavfilter/vf_hqx.c                |  2 +-
 libavfilter/vf_hsvkey.c             |  4 +--
 libavfilter/vf_hue.c                |  2 +-
 libavfilter/vf_hwdownload.c         |  2 +-
 libavfilter/vf_hwmap.c              |  2 +-
 libavfilter/vf_hwupload.c           |  2 +-
 libavfilter/vf_hwupload_cuda.c      |  4 +--
 libavfilter/vf_hysteresis.c         |  2 +-
 libavfilter/vf_identity.c           |  4 +--
 libavfilter/vf_idet.c               |  2 +-
 libavfilter/vf_il.c                 |  2 +-
 libavfilter/vf_kerndeint.c          |  2 +-
 libavfilter/vf_lagfun.c             |  2 +-
 libavfilter/vf_lenscorrection.c     |  2 +-
 libavfilter/vf_lensfun.c            |  2 +-
 libavfilter/vf_libopencv.c          |  2 +-
 libavfilter/vf_libvmaf.c            |  2 +-
 libavfilter/vf_limiter.c            |  2 +-
 libavfilter/vf_lumakey.c            |  2 +-
 libavfilter/vf_lut.c                |  2 +-
 libavfilter/vf_lut2.c               |  4 +--
 libavfilter/vf_lut3d.c              |  6 ++--
 libavfilter/vf_maskedclamp.c        |  2 +-
 libavfilter/vf_maskedmerge.c        |  2 +-
 libavfilter/vf_maskedminmax.c       |  4 +--
 libavfilter/vf_maskedthreshold.c    |  2 +-
 libavfilter/vf_maskfun.c            |  2 +-
 libavfilter/vf_mcdeint.c            |  2 +-
 libavfilter/vf_median.c             |  2 +-
 libavfilter/vf_mergeplanes.c        |  2 +-
 libavfilter/vf_mestimate.c          |  2 +-
 libavfilter/vf_midequalizer.c       |  2 +-
 libavfilter/vf_minterpolate.c       |  2 +-
 libavfilter/vf_misc_vaapi.c         |  4 +--
 libavfilter/vf_mix.c                |  4 +--
 libavfilter/vf_monochrome.c         |  2 +-
 libavfilter/vf_morpho.c             |  2 +-
 libavfilter/vf_mpdecimate.c         |  2 +-
 libavfilter/vf_neighbor.c           |  2 +-
 libavfilter/vf_neighbor_opencl.c    |  4 +--
 libavfilter/vf_nlmeans.c            |  2 +-
 libavfilter/vf_nlmeans_opencl.c     |  2 +-
 libavfilter/vf_nnedi.c              |  2 +-
 libavfilter/vf_noise.c              |  2 +-
 libavfilter/vf_normalize.c          |  2 +-
 libavfilter/vf_ocr.c                |  2 +-
 libavfilter/vf_overlay.c            |  2 +-
 libavfilter/vf_overlay_cuda.c       |  2 +-
 libavfilter/vf_overlay_opencl.c     |  2 +-
 libavfilter/vf_overlay_qsv.c        |  2 +-
 libavfilter/vf_overlay_vulkan.c     |  2 +-
 libavfilter/vf_owdenoise.c          |  2 +-
 libavfilter/vf_pad.c                |  2 +-
 libavfilter/vf_pad_opencl.c         |  2 +-
 libavfilter/vf_palettegen.c         |  2 +-
 libavfilter/vf_paletteuse.c         |  2 +-
 libavfilter/vf_perspective.c        |  2 +-
 libavfilter/vf_phase.c              |  2 +-
 libavfilter/vf_photosensitivity.c   |  2 +-
 libavfilter/vf_pp.c                 |  2 +-
 libavfilter/vf_pp7.c                |  2 +-
 libavfilter/vf_premultiply.c        |  4 +--
 libavfilter/vf_procamp_vaapi.c      |  2 +-
 libavfilter/vf_program_opencl.c     |  4 +--
 libavfilter/vf_pseudocolor.c        |  2 +-
 libavfilter/vf_psnr.c               |  2 +-
 libavfilter/vf_pullup.c             |  2 +-
 libavfilter/vf_readeia608.c         |  2 +-
 libavfilter/vf_readvitc.c           |  2 +-
 libavfilter/vf_remap.c              |  2 +-
 libavfilter/vf_removegrain.c        |  2 +-
 libavfilter/vf_removelogo.c         |  2 +-
 libavfilter/vf_repeatfields.c       |  2 +-
 libavfilter/vf_rotate.c             |  2 +-
 libavfilter/vf_sab.c                |  2 +-
 libavfilter/vf_scale.c              |  4 +--
 libavfilter/vf_scale_cuda.c         |  3 +-
 libavfilter/vf_scale_npp.c          |  3 +-
 libavfilter/vf_scale_qsv.c          |  3 +-
 libavfilter/vf_scale_vaapi.c        |  2 +-
 libavfilter/vf_scale_vulkan.c       |  2 +-
 libavfilter/vf_scdet.c              |  2 +-
 libavfilter/vf_scroll.c             |  2 +-
 libavfilter/vf_selectivecolor.c     |  2 +-
 libavfilter/vf_shear.c              |  2 +-
 libavfilter/vf_showpalette.c        |  2 +-
 libavfilter/vf_shufflepixels.c      |  2 +-
 libavfilter/vf_shuffleplanes.c      |  2 +-
 libavfilter/vf_signalstats.c        |  2 +-
 libavfilter/vf_signature.c          |  2 +-
 libavfilter/vf_smartblur.c          |  2 +-
 libavfilter/vf_spp.c                |  2 +-
 libavfilter/vf_sr.c                 |  2 +-
 libavfilter/vf_ssim.c               |  2 +-
 libavfilter/vf_stack.c              |  6 ++--
 libavfilter/vf_stereo3d.c           |  2 +-
 libavfilter/vf_subtitles.c          |  4 +--
 libavfilter/vf_super2xsai.c         |  2 +-
 libavfilter/vf_swaprect.c           |  2 +-
 libavfilter/vf_swapuv.c             |  2 +-
 libavfilter/vf_telecine.c           |  2 +-
 libavfilter/vf_threshold.c          |  2 +-
 libavfilter/vf_thumbnail.c          |  2 +-
 libavfilter/vf_thumbnail_cuda.c     |  2 +-
 libavfilter/vf_tile.c               |  2 +-
 libavfilter/vf_tinterlace.c         |  4 +--
 libavfilter/vf_tmidequalizer.c      |  2 +-
 libavfilter/vf_tonemap.c            |  2 +-
 libavfilter/vf_tonemap_opencl.c     |  2 +-
 libavfilter/vf_tonemap_vaapi.c      |  2 +-
 libavfilter/vf_tpad.c               |  2 +-
 libavfilter/vf_transpose.c          |  2 +-
 libavfilter/vf_transpose_npp.c      |  2 +-
 libavfilter/vf_transpose_opencl.c   |  2 +-
 libavfilter/vf_transpose_vaapi.c    |  2 +-
 libavfilter/vf_unsharp.c            |  2 +-
 libavfilter/vf_unsharp_opencl.c     |  2 +-
 libavfilter/vf_untile.c             |  2 +-
 libavfilter/vf_uspp.c               |  2 +-
 libavfilter/vf_v360.c               |  2 +-
 libavfilter/vf_vaguedenoiser.c      |  2 +-
 libavfilter/vf_vectorscope.c        |  2 +-
 libavfilter/vf_vibrance.c           |  2 +-
 libavfilter/vf_vidstabdetect.c      |  2 +-
 libavfilter/vf_vidstabtransform.c   |  2 +-
 libavfilter/vf_vif.c                |  2 +-
 libavfilter/vf_vignette.c           |  2 +-
 libavfilter/vf_vmafmotion.c         |  2 +-
 libavfilter/vf_vpp_qsv.c            |  2 +-
 libavfilter/vf_w3fdif.c             |  2 +-
 libavfilter/vf_waveform.c           |  2 +-
 libavfilter/vf_weave.c              |  4 +--
 libavfilter/vf_xbr.c                |  2 +-
 libavfilter/vf_xfade.c              |  2 +-
 libavfilter/vf_xfade_opencl.c       |  2 +-
 libavfilter/vf_xmedian.c            |  4 +--
 libavfilter/vf_yadif.c              |  2 +-
 libavfilter/vf_yadif_cuda.c         |  2 +-
 libavfilter/vf_yaepblur.c           |  2 +-
 libavfilter/vf_zoompan.c            |  2 +-
 libavfilter/vf_zscale.c             |  2 +-
 libavfilter/vsrc_cellauto.c         |  2 +-
 libavfilter/vsrc_gradients.c        |  2 +-
 libavfilter/vsrc_life.c             |  2 +-
 libavfilter/vsrc_mandelbrot.c       |  2 +-
 libavfilter/vsrc_mptestsrc.c        |  2 +-
 libavfilter/vsrc_sierpinski.c       |  2 +-
 libavfilter/vsrc_testsrc.c          | 24 ++++++-------
 360 files changed, 551 insertions(+), 441 deletions(-)

Comments

Nicolas George Oct. 5, 2021, 10:57 a.m. UTC | #1
Andreas Rheinhardt (12021-09-30):
> If one looks at the many query_formats callbacks in existence,
> one will immediately recognize that there is one type of default
> callback for video and a slightly different default callback for
> audio: It is "return ff_set_common_formats_from_list(ctx, pix_fmts);"
> for video with a filter-specific pix_fmts list. For audio, it is
> the same with a filter-specific sample_fmts list together with
> ff_set_common_all_samplerates() and ff_set_common_all_channel_counts().
> 
> This commit allows to remove the boilerplate query_formats callbacks
> by replacing said callback with a union consisting the old callback
> and pointers for pixel and sample format arrays. For the not uncommon
> case in which these lists only contain a single entry (besides the
> sentinel) enum AVPixelFormat and enum AVSampleFormat fields are also
> added to the union to store them directly in the AVFilter,
> thereby avoiding a relocation.
> 
> The state of said union will be contained in a new, dedicated AVFilter
> field (the nb_inputs and nb_outputs fields have been shrunk to uint8_t
> in order to create a hole for this new field; this is no problem, as
> the maximum of all the nb_inputs is four; for nb_outputs it is only
> two).
> 
> The state's default value coincides with the earlier default of
> query_formats being unset, namely that the filter accepts all formats
> (and also sample rates and channel counts/layouts for audio)
> provided that these properties agree coincide for all inputs and
> outputs.
> 
> By using different union members for audio and video filters
> the type-unsafety of using the same functions for audio and video
> lists will furthermore be more confined to formats.c than before.
> 
> When the new fields are used, they will also avoid allocations:
> Currently something nearly equivalent to ff_default_query_formats()
> is called after every successful call to a query_formats callback;
> yet in the common case that the newly allocated AVFilterFormats
> are not used at all (namely if there are no free links) these newly
> allocated AVFilterFormats are freed again without ever being used.
> Filters no longer using the callback will not exhibit this any more.
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
> ---
> This patchset here aims to remove boilerplate code from the
> query-formats API. Despite touching lots of filters, there should be
> only very few conflicts (if at all) with Nicolas' earlier patch [1].
> The reason for this is that the filters touched here typically only
> use ff_set_common_* functions, which are unaffected by his change.

I do not like the aesthetics of this very much, but it is a useful
change.

I have not looked at each individual filter change, but they are
straightforward.

So ok for my part.

Regards,
diff mbox series

Patch

diff --git a/libavfilter/aeval.c b/libavfilter/aeval.c
index 6c9aad4654..2dc8bace51 100644
--- a/libavfilter/aeval.c
+++ b/libavfilter/aeval.c
@@ -320,13 +320,13 @@  static const AVFilterPad aevalsrc_outputs[] = {
 const AVFilter ff_asrc_aevalsrc = {
     .name          = "aevalsrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate an audio signal generated by an expression."),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
     .priv_size     = sizeof(EvalContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(aevalsrc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &aevalsrc_class,
 };
 
@@ -466,12 +466,12 @@  static const AVFilterPad aeval_outputs[] = {
 const AVFilter ff_af_aeval = {
     .name          = "aeval",
     .description   = NULL_IF_CONFIG_SMALL("Filter audio signal according to a specified expression."),
-    .query_formats = aeval_query_formats,
     .init          = init,
     .uninit        = uninit,
     .priv_size     = sizeof(EvalContext),
     FILTER_INPUTS(aeval_inputs),
     FILTER_OUTPUTS(aeval_outputs),
+    FILTER_QUERY_FUNC(aeval_query_formats),
     .priv_class    = &aeval_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_acontrast.c b/libavfilter/af_acontrast.c
index b5a5381fba..91c4ecd19a 100644
--- a/libavfilter/af_acontrast.c
+++ b/libavfilter/af_acontrast.c
@@ -199,9 +199,9 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_acontrast = {
     .name           = "acontrast",
     .description    = NULL_IF_CONFIG_SMALL("Simple audio dynamic range compression/expansion filter."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(AudioContrastContext),
     .priv_class     = &acontrast_class,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_acrossover.c b/libavfilter/af_acrossover.c
index b339919142..1ba847d31b 100644
--- a/libavfilter/af_acrossover.c
+++ b/libavfilter/af_acrossover.c
@@ -559,7 +559,7 @@  const AVFilter ff_af_acrossover = {
     .priv_class     = &acrossover_class,
     .init           = init,
     .uninit         = uninit,
-    .query_formats  = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     FILTER_INPUTS(inputs),
     .outputs        = NULL,
     .flags          = AVFILTER_FLAG_DYNAMIC_OUTPUTS |
diff --git a/libavfilter/af_acrusher.c b/libavfilter/af_acrusher.c
index 6130c9f2ec..88d6c644ad 100644
--- a/libavfilter/af_acrusher.c
+++ b/libavfilter/af_acrusher.c
@@ -357,7 +357,7 @@  const AVFilter ff_af_acrusher = {
     .priv_size     = sizeof(ACrusherContext),
     .priv_class    = &acrusher_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     FILTER_INPUTS(avfilter_af_acrusher_inputs),
     FILTER_OUTPUTS(avfilter_af_acrusher_outputs),
     .process_command = process_command,
diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c
index 1e30ada03c..f9404b2a4a 100644
--- a/libavfilter/af_adeclick.c
+++ b/libavfilter/af_adeclick.c
@@ -753,7 +753,6 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_adeclick = {
     .name          = "adeclick",
     .description   = NULL_IF_CONFIG_SMALL("Remove impulsive noise from input audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioDeclickContext),
     .priv_class    = &adeclick_class,
     .init          = init,
@@ -761,6 +760,7 @@  const AVFilter ff_af_adeclick = {
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
 
@@ -789,7 +789,6 @@  AVFILTER_DEFINE_CLASS(adeclip);
 const AVFilter ff_af_adeclip = {
     .name          = "adeclip",
     .description   = NULL_IF_CONFIG_SMALL("Remove clipping from input audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioDeclickContext),
     .priv_class    = &adeclip_class,
     .init          = init,
@@ -797,5 +796,6 @@  const AVFilter ff_af_adeclip = {
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_adecorrelate.c b/libavfilter/af_adecorrelate.c
index 6113574125..e0731b0945 100644
--- a/libavfilter/af_adecorrelate.c
+++ b/libavfilter/af_adecorrelate.c
@@ -257,12 +257,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_adecorrelate = {
     .name            = "adecorrelate",
     .description     = NULL_IF_CONFIG_SMALL("Apply decorrelation to input audio."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ADecorrelateContext),
     .priv_class      = &adecorrelate_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_adelay.c b/libavfilter/af_adelay.c
index f9b4acd600..e67f081b97 100644
--- a/libavfilter/af_adelay.c
+++ b/libavfilter/af_adelay.c
@@ -338,12 +338,12 @@  static const AVFilterPad adelay_outputs[] = {
 const AVFilter ff_af_adelay = {
     .name          = "adelay",
     .description   = NULL_IF_CONFIG_SMALL("Delay one or more audio channels."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioDelayContext),
     .priv_class    = &adelay_class,
     .activate      = activate,
     .uninit        = uninit,
     FILTER_INPUTS(adelay_inputs),
     FILTER_OUTPUTS(adelay_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_adenorm.c b/libavfilter/af_adenorm.c
index c48c02fc70..2cac605a2a 100644
--- a/libavfilter/af_adenorm.c
+++ b/libavfilter/af_adenorm.c
@@ -307,10 +307,10 @@  AVFILTER_DEFINE_CLASS(adenorm);
 const AVFilter ff_af_adenorm = {
     .name            = "adenorm",
     .description     = NULL_IF_CONFIG_SMALL("Remedy denormals by adding extremely low-level noise."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ADenormContext),
     FILTER_INPUTS(adenorm_inputs),
     FILTER_OUTPUTS(adenorm_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &adenorm_class,
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
diff --git a/libavfilter/af_aderivative.c b/libavfilter/af_aderivative.c
index e4b6267a1a..e37f978df6 100644
--- a/libavfilter/af_aderivative.c
+++ b/libavfilter/af_aderivative.c
@@ -175,19 +175,19 @@  static const AVFilterPad aderivative_outputs[] = {
 const AVFilter ff_af_aderivative = {
     .name          = "aderivative",
     .description   = NULL_IF_CONFIG_SMALL("Compute derivative of input audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(ADerivativeContext),
     .uninit        = uninit,
     FILTER_INPUTS(aderivative_inputs),
     FILTER_OUTPUTS(aderivative_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 
 const AVFilter ff_af_aintegral = {
     .name          = "aintegral",
     .description   = NULL_IF_CONFIG_SMALL("Compute integral of input audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(ADerivativeContext),
     .uninit        = uninit,
     FILTER_INPUTS(aderivative_inputs),
     FILTER_OUTPUTS(aderivative_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_aecho.c b/libavfilter/af_aecho.c
index d533bb610b..508d54b04e 100644
--- a/libavfilter/af_aecho.c
+++ b/libavfilter/af_aecho.c
@@ -364,7 +364,6 @@  static const AVFilterPad aecho_outputs[] = {
 const AVFilter ff_af_aecho = {
     .name          = "aecho",
     .description   = NULL_IF_CONFIG_SMALL("Add echoing to the audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioEchoContext),
     .priv_class    = &aecho_class,
     .init          = init,
@@ -372,4 +371,5 @@  const AVFilter ff_af_aecho = {
     .uninit        = uninit,
     FILTER_INPUTS(aecho_inputs),
     FILTER_OUTPUTS(aecho_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_aemphasis.c b/libavfilter/af_aemphasis.c
index a9c0cf599d..54a47d2c86 100644
--- a/libavfilter/af_aemphasis.c
+++ b/libavfilter/af_aemphasis.c
@@ -391,9 +391,9 @@  const AVFilter ff_af_aemphasis = {
     .priv_size     = sizeof(AudioEmphasisContext),
     .priv_class    = &aemphasis_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_af_aemphasis_inputs),
     FILTER_OUTPUTS(avfilter_af_aemphasis_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                      AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_aexciter.c b/libavfilter/af_aexciter.c
index f9ece59d93..3300ebbd4f 100644
--- a/libavfilter/af_aexciter.c
+++ b/libavfilter/af_aexciter.c
@@ -294,9 +294,9 @@  const AVFilter ff_af_aexciter = {
     .priv_size     = sizeof(AExciterContext),
     .priv_class    = &aexciter_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_af_aexciter_inputs),
     FILTER_OUTPUTS(avfilter_af_aexciter_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index 3bd0331e77..c96a8fb7e3 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -353,11 +353,11 @@  static const AVFilterPad avfilter_af_afade_outputs[] = {
 const AVFilter ff_af_afade = {
     .name          = "afade",
     .description   = NULL_IF_CONFIG_SMALL("Fade in/out input audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioFadeContext),
     .init          = init,
     FILTER_INPUTS(avfilter_af_afade_inputs),
     FILTER_OUTPUTS(avfilter_af_afade_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &afade_class,
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
@@ -628,12 +628,12 @@  static const AVFilterPad avfilter_af_acrossfade_outputs[] = {
 const AVFilter ff_af_acrossfade = {
     .name          = "acrossfade",
     .description   = NULL_IF_CONFIG_SMALL("Cross fade two input audio streams."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioFadeContext),
     .activate      = activate,
     .priv_class    = &acrossfade_class,
     FILTER_INPUTS(avfilter_af_acrossfade_inputs),
     FILTER_OUTPUTS(avfilter_af_acrossfade_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 
 #endif /* CONFIG_ACROSSFADE_FILTER */
diff --git a/libavfilter/af_afftdn.c b/libavfilter/af_afftdn.c
index 5e9cefcfc1..27a0780ce8 100644
--- a/libavfilter/af_afftdn.c
+++ b/libavfilter/af_afftdn.c
@@ -1411,13 +1411,13 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_afftdn = {
     .name            = "afftdn",
     .description     = NULL_IF_CONFIG_SMALL("Denoise audio samples using FFT."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(AudioFFTDeNoiseContext),
     .priv_class      = &afftdn_class,
     .activate        = activate,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_afftfilt.c b/libavfilter/af_afftfilt.c
index 87e50f57e9..7714f1768f 100644
--- a/libavfilter/af_afftfilt.c
+++ b/libavfilter/af_afftfilt.c
@@ -489,8 +489,8 @@  const AVFilter ff_af_afftfilt = {
     .priv_class      = &afftfilt_class,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate        = activate,
-    .query_formats   = query_formats,
     .uninit          = uninit,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c
index b74e7ddfae..ace5087e90 100644
--- a/libavfilter/af_afir.c
+++ b/libavfilter/af_afir.c
@@ -942,7 +942,7 @@  const AVFilter ff_af_afir = {
     .description   = NULL_IF_CONFIG_SMALL("Apply Finite Impulse Response filter with supplied coefficients in additional stream(s)."),
     .priv_size     = sizeof(AudioFIRContext),
     .priv_class    = &afir_class,
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .activate      = activate,
     .uninit        = uninit,
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index 1cab148d95..7e25c0c6a4 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -160,9 +160,9 @@  const AVFilter ff_af_aformat = {
     .description   = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(AFormatContext),
     .priv_class    = &aformat_class,
     FILTER_INPUTS(avfilter_af_aformat_inputs),
     FILTER_OUTPUTS(avfilter_af_aformat_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_afreqshift.c b/libavfilter/af_afreqshift.c
index 0410bde70b..95fd4e31fc 100644
--- a/libavfilter/af_afreqshift.c
+++ b/libavfilter/af_afreqshift.c
@@ -388,12 +388,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_afreqshift = {
     .name            = "afreqshift",
     .description     = NULL_IF_CONFIG_SMALL("Apply frequency shifting to input audio."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(AFreqShift),
     .priv_class      = &afreqshift_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = ff_filter_process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -411,12 +411,12 @@  AVFILTER_DEFINE_CLASS(aphaseshift);
 const AVFilter ff_af_aphaseshift = {
     .name            = "aphaseshift",
     .description     = NULL_IF_CONFIG_SMALL("Apply phase shifting to input audio."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(AFreqShift),
     .priv_class      = &aphaseshift_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = ff_filter_process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_afwtdn.c b/libavfilter/af_afwtdn.c
index f7e8211bb4..9235e6e28d 100644
--- a/libavfilter/af_afwtdn.c
+++ b/libavfilter/af_afwtdn.c
@@ -1324,13 +1324,13 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_afwtdn = {
     .name            = "afwtdn",
     .description     = NULL_IF_CONFIG_SMALL("Denoise audio stream using Wavelets."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(AudioFWTDNContext),
     .priv_class      = &afwtdn_class,
     .activate        = activate,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c
index 5de2cc0f0e..568006c1f0 100644
--- a/libavfilter/af_agate.c
+++ b/libavfilter/af_agate.c
@@ -252,10 +252,10 @@  const AVFilter ff_af_agate = {
     .name           = "agate",
     .description    = NULL_IF_CONFIG_SMALL("Audio gate."),
     .priv_class     = &agate_sidechaingate_class,
-    .query_formats  = query_formats,
     .priv_size      = sizeof(AudioGateContext),
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = ff_filter_process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -401,11 +401,11 @@  const AVFilter ff_af_sidechaingate = {
     .description    = NULL_IF_CONFIG_SMALL("Audio sidechain gate."),
     .priv_class     = &agate_sidechaingate_class,
     .priv_size      = sizeof(AudioGateContext),
-    .query_formats  = scquery_formats,
     .activate       = activate,
     .uninit         = uninit,
     FILTER_INPUTS(sidechaingate_inputs),
     FILTER_OUTPUTS(sidechaingate_outputs),
+    FILTER_QUERY_FUNC(scquery_formats),
     .process_command = ff_filter_process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_aiir.c b/libavfilter/af_aiir.c
index cae2c365bf..8a4b4814f6 100644
--- a/libavfilter/af_aiir.c
+++ b/libavfilter/af_aiir.c
@@ -1572,8 +1572,8 @@  const AVFilter ff_af_aiir = {
     .priv_class    = &aiir_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS |
                      AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_alimiter.c b/libavfilter/af_alimiter.c
index 9172f305f0..937f28383f 100644
--- a/libavfilter/af_alimiter.c
+++ b/libavfilter/af_alimiter.c
@@ -353,7 +353,7 @@  const AVFilter ff_af_alimiter = {
     .priv_class     = &alimiter_class,
     .init           = init,
     .uninit         = uninit,
-    .query_formats  = query_formats,
     FILTER_INPUTS(alimiter_inputs),
     FILTER_OUTPUTS(alimiter_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c
index 9c6da15a9f..9109af22c5 100644
--- a/libavfilter/af_amerge.c
+++ b/libavfilter/af_amerge.c
@@ -337,10 +337,10 @@  const AVFilter ff_af_amerge = {
     .priv_size     = sizeof(AMergeContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(amerge_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &amerge_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index 92557713c4..d2a363284f 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -639,9 +639,9 @@  const AVFilter ff_af_amix = {
     .init           = init,
     .uninit         = uninit,
     .activate       = activate,
-    .query_formats  = query_formats,
     .inputs         = NULL,
     FILTER_OUTPUTS(avfilter_af_amix_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_amultiply.c b/libavfilter/af_amultiply.c
index 7c44cadb2b..f9413c9fc9 100644
--- a/libavfilter/af_amultiply.c
+++ b/libavfilter/af_amultiply.c
@@ -196,7 +196,7 @@  const AVFilter ff_af_amultiply = {
     .init           = init,
     .uninit         = uninit,
     .activate       = activate,
-    .query_formats  = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_anequalizer.c b/libavfilter/af_anequalizer.c
index ab1838f990..57a9b7634b 100644
--- a/libavfilter/af_anequalizer.c
+++ b/libavfilter/af_anequalizer.c
@@ -770,9 +770,9 @@  const AVFilter ff_af_anequalizer = {
     .priv_class    = &anequalizer_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     .outputs       = NULL,
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS |
                      AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
diff --git a/libavfilter/af_anlmdn.c b/libavfilter/af_anlmdn.c
index 0ba725f59f..af6a6a69e9 100644
--- a/libavfilter/af_anlmdn.c
+++ b/libavfilter/af_anlmdn.c
@@ -402,12 +402,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_anlmdn = {
     .name          = "anlmdn",
     .description   = NULL_IF_CONFIG_SMALL("Reduce broadband noise from stream using Non-Local Means."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioNLMeansContext),
     .priv_class    = &anlmdn_class,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_anlms.c b/libavfilter/af_anlms.c
index 75e932ca96..f1f82b491d 100644
--- a/libavfilter/af_anlms.c
+++ b/libavfilter/af_anlms.c
@@ -306,9 +306,9 @@  const AVFilter ff_af_anlms = {
     .init           = init,
     .uninit         = uninit,
     .activate       = activate,
-    .query_formats  = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/af_aphaser.c b/libavfilter/af_aphaser.c
index 3a365140db..962bfe6b16 100644
--- a/libavfilter/af_aphaser.c
+++ b/libavfilter/af_aphaser.c
@@ -278,11 +278,11 @@  static const AVFilterPad aphaser_outputs[] = {
 const AVFilter ff_af_aphaser = {
     .name          = "aphaser",
     .description   = NULL_IF_CONFIG_SMALL("Add a phasing effect to the audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioPhaserContext),
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(aphaser_inputs),
     FILTER_OUTPUTS(aphaser_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &aphaser_class,
 };
diff --git a/libavfilter/af_apsyclip.c b/libavfilter/af_apsyclip.c
index ef151bcb55..e9f1feb906 100644
--- a/libavfilter/af_apsyclip.c
+++ b/libavfilter/af_apsyclip.c
@@ -666,12 +666,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_apsyclip = {
     .name            = "apsyclip",
     .description     = NULL_IF_CONFIG_SMALL("Audio Psychoacoustic Clipper."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(AudioPsyClipContext),
     .priv_class      = &apsyclip_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                        AVFILTER_FLAG_SLICE_THREADS,
     .activate        = activate,
diff --git a/libavfilter/af_apulsator.c b/libavfilter/af_apulsator.c
index b9a194eb9d..c2a8de0e0b 100644
--- a/libavfilter/af_apulsator.c
+++ b/libavfilter/af_apulsator.c
@@ -249,7 +249,7 @@  const AVFilter ff_af_apulsator = {
     .description   = NULL_IF_CONFIG_SMALL("Audio pulsator."),
     .priv_size     = sizeof(AudioPulsatorContext),
     .priv_class    = &apulsator_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index 8e0eaee17b..6e1be5b7eb 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -332,9 +332,9 @@  const AVFilter ff_af_aresample = {
     .description   = NULL_IF_CONFIG_SMALL("Resample audio data."),
     .preinit       = preinit,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(AResampleContext),
     .priv_class    = &aresample_class,
     FILTER_INPUTS(aresample_inputs),
     FILTER_OUTPUTS(aresample_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_arnndn.c b/libavfilter/af_arnndn.c
index 8225b1657e..3115c4ae0c 100644
--- a/libavfilter/af_arnndn.c
+++ b/libavfilter/af_arnndn.c
@@ -1608,7 +1608,6 @@  AVFILTER_DEFINE_CLASS(arnndn);
 const AVFilter ff_af_arnndn = {
     .name          = "arnndn",
     .description   = NULL_IF_CONFIG_SMALL("Reduce noise from speech using Recurrent Neural Networks."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioRNNContext),
     .priv_class    = &arnndn_class,
     .activate      = activate,
@@ -1616,6 +1615,7 @@  const AVFilter ff_af_arnndn = {
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/af_asetrate.c b/libavfilter/af_asetrate.c
index 920baedad2..637fa4fbb8 100644
--- a/libavfilter/af_asetrate.c
+++ b/libavfilter/af_asetrate.c
@@ -108,9 +108,9 @@  const AVFilter ff_af_asetrate = {
     .name          = "asetrate",
     .description   = NULL_IF_CONFIG_SMALL("Change the sample rate without "
                                           "altering the data."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(ASetRateContext),
     FILTER_INPUTS(asetrate_inputs),
     FILTER_OUTPUTS(asetrate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &asetrate_class,
 };
diff --git a/libavfilter/af_asoftclip.c b/libavfilter/af_asoftclip.c
index 9b3d58747a..50646738a4 100644
--- a/libavfilter/af_asoftclip.c
+++ b/libavfilter/af_asoftclip.c
@@ -500,11 +500,11 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_asoftclip = {
     .name           = "asoftclip",
     .description    = NULL_IF_CONFIG_SMALL("Audio Soft Clipper."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(ASoftClipContext),
     .priv_class     = &asoftclip_class,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .uninit         = uninit,
     .process_command = ff_filter_process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
diff --git a/libavfilter/af_asr.c b/libavfilter/af_asr.c
index c7dc3b2db6..b9c7068526 100644
--- a/libavfilter/af_asr.c
+++ b/libavfilter/af_asr.c
@@ -172,7 +172,7 @@  const AVFilter ff_af_asr = {
     .priv_class    = &asr_class,
     .init          = asr_init,
     .uninit        = asr_uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(asr_inputs),
     FILTER_OUTPUTS(asr_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c
index 899746864d..d43dd086f1 100644
--- a/libavfilter/af_astats.c
+++ b/libavfilter/af_astats.c
@@ -863,11 +863,11 @@  static const AVFilterPad astats_outputs[] = {
 const AVFilter ff_af_astats = {
     .name          = "astats",
     .description   = NULL_IF_CONFIG_SMALL("Show time domain statistics about audio frames."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioStatsContext),
     .priv_class    = &astats_class,
     .uninit        = uninit,
     FILTER_INPUTS(astats_inputs),
     FILTER_OUTPUTS(astats_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_asubboost.c b/libavfilter/af_asubboost.c
index 7543601b8a..9e97cbf375 100644
--- a/libavfilter/af_asubboost.c
+++ b/libavfilter/af_asubboost.c
@@ -233,12 +233,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_asubboost = {
     .name           = "asubboost",
     .description    = NULL_IF_CONFIG_SMALL("Boost subwoofer frequencies."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(ASubBoostContext),
     .priv_class     = &asubboost_class,
     .uninit         = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                        AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_asupercut.c b/libavfilter/af_asupercut.c
index 29f24c7055..0efcbf8d37 100644
--- a/libavfilter/af_asupercut.c
+++ b/libavfilter/af_asupercut.c
@@ -357,12 +357,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_asupercut = {
     .name            = "asupercut",
     .description     = NULL_IF_CONFIG_SMALL("Cut super frequencies."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ASuperCutContext),
     .priv_class      = &asupercut_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -380,12 +380,12 @@  AVFILTER_DEFINE_CLASS(asubcut);
 const AVFilter ff_af_asubcut = {
     .name            = "asubcut",
     .description     = NULL_IF_CONFIG_SMALL("Cut subwoofer frequencies."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ASuperCutContext),
     .priv_class      = &asubcut_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -406,11 +406,11 @@  const AVFilter ff_af_asuperpass = {
     .name            = "asuperpass",
     .description     = NULL_IF_CONFIG_SMALL("Apply high order Butterworth band-pass filter."),
     .priv_class      = &asuperpass_asuperstop_class,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ASuperCutContext),
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -420,11 +420,11 @@  const AVFilter ff_af_asuperstop = {
     .name            = "asuperstop",
     .description     = NULL_IF_CONFIG_SMALL("Apply high order Butterworth band-stop filter."),
     .priv_class      = &asuperpass_asuperstop_class,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ASuperCutContext),
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_atempo.c b/libavfilter/af_atempo.c
index 16fa59701a..6376cdc03e 100644
--- a/libavfilter/af_atempo.c
+++ b/libavfilter/af_atempo.c
@@ -1188,10 +1188,10 @@  const AVFilter ff_af_atempo = {
     .description     = NULL_IF_CONFIG_SMALL("Adjust audio tempo."),
     .init            = init,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     .process_command = process_command,
     .priv_size       = sizeof(ATempoContext),
     .priv_class      = &atempo_class,
     FILTER_INPUTS(atempo_inputs),
     FILTER_OUTPUTS(atempo_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_atilt.c b/libavfilter/af_atilt.c
index 833e0c571b..e242ad2bd5 100644
--- a/libavfilter/af_atilt.c
+++ b/libavfilter/af_atilt.c
@@ -275,12 +275,12 @@  static const AVFilterPad outputs[] = {
 AVFilter ff_af_atilt = {
     .name            = "atilt",
     .description     = NULL_IF_CONFIG_SMALL("Apply spectral tilt to audio."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ATiltContext),
     .priv_class      = &atilt_class,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_axcorrelate.c b/libavfilter/af_axcorrelate.c
index 18fc3004b1..1d9c805b29 100644
--- a/libavfilter/af_axcorrelate.c
+++ b/libavfilter/af_axcorrelate.c
@@ -354,9 +354,9 @@  const AVFilter ff_af_axcorrelate = {
     .description    = NULL_IF_CONFIG_SMALL("Cross-correlate two audio streams."),
     .priv_size      = sizeof(AudioXCorrelateContext),
     .priv_class     = &axcorrelate_class,
-    .query_formats  = query_formats,
     .activate       = activate,
     .uninit         = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c
index 828af05b20..adbae5892d 100644
--- a/libavfilter/af_biquads.c
+++ b/libavfilter/af_biquads.c
@@ -868,9 +868,9 @@  const AVFilter ff_af_##name_ = {                               \
     .priv_size     = sizeof(BiquadsContext),             \
     .init          = name_##_init,                       \
     .uninit        = uninit,                             \
-    .query_formats = query_formats,                      \
     FILTER_INPUTS(inputs),                               \
     FILTER_OUTPUTS(outputs),                             \
+    FILTER_QUERY_FUNC(query_formats),                    \
     .process_command = process_command,                  \
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
 }
diff --git a/libavfilter/af_bs2b.c b/libavfilter/af_bs2b.c
index 55b4d2ac6f..90ae846d95 100644
--- a/libavfilter/af_bs2b.c
+++ b/libavfilter/af_bs2b.c
@@ -205,11 +205,11 @@  static const AVFilterPad bs2b_outputs[] = {
 const AVFilter ff_af_bs2b = {
     .name           = "bs2b",
     .description    = NULL_IF_CONFIG_SMALL("Bauer stereo-to-binaural filter."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(Bs2bContext),
     .priv_class     = &bs2b_class,
     .init           = init,
     .uninit         = uninit,
     FILTER_INPUTS(bs2b_inputs),
     FILTER_OUTPUTS(bs2b_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index f5a57539fe..d3ab77920f 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -400,9 +400,9 @@  const AVFilter ff_af_channelmap = {
     .name          = "channelmap",
     .description   = NULL_IF_CONFIG_SMALL("Remap audio channels."),
     .init          = channelmap_init,
-    .query_formats = channelmap_query_formats,
     .priv_size     = sizeof(ChannelMapContext),
     .priv_class    = &channelmap_class,
     FILTER_INPUTS(avfilter_af_channelmap_inputs),
     FILTER_OUTPUTS(avfilter_af_channelmap_outputs),
+    FILTER_QUERY_FUNC(channelmap_query_formats),
 };
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index 2bb34881a6..1a2519dd32 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -172,8 +172,8 @@  const AVFilter ff_af_channelsplit = {
     .priv_size      = sizeof(ChannelSplitContext),
     .priv_class     = &channelsplit_class,
     .init           = init,
-    .query_formats  = query_formats,
     FILTER_INPUTS(avfilter_af_channelsplit_inputs),
     .outputs        = NULL,
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/af_chorus.c b/libavfilter/af_chorus.c
index 9c9090e4cc..cb6de9a85f 100644
--- a/libavfilter/af_chorus.c
+++ b/libavfilter/af_chorus.c
@@ -357,11 +357,11 @@  static const AVFilterPad chorus_outputs[] = {
 const AVFilter ff_af_chorus = {
     .name          = "chorus",
     .description   = NULL_IF_CONFIG_SMALL("Add a chorus effect to the audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(ChorusContext),
     .priv_class    = &chorus_class,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(chorus_inputs),
     FILTER_OUTPUTS(chorus_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_compand.c b/libavfilter/af_compand.c
index 0172b5f876..6eb68dfa19 100644
--- a/libavfilter/af_compand.c
+++ b/libavfilter/af_compand.c
@@ -574,11 +574,11 @@  const AVFilter ff_af_compand = {
     .name           = "compand",
     .description    = NULL_IF_CONFIG_SMALL(
             "Compress or expand audio dynamic range."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(CompandContext),
     .priv_class     = &compand_class,
     .init           = init,
     .uninit         = uninit,
     FILTER_INPUTS(compand_inputs),
     FILTER_OUTPUTS(compand_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_compensationdelay.c b/libavfilter/af_compensationdelay.c
index 1620750760..ff6f640370 100644
--- a/libavfilter/af_compensationdelay.c
+++ b/libavfilter/af_compensationdelay.c
@@ -174,10 +174,10 @@  static const AVFilterPad compensationdelay_outputs[] = {
 const AVFilter ff_af_compensationdelay = {
     .name          = "compensationdelay",
     .description   = NULL_IF_CONFIG_SMALL("Audio Compensation Delay Line."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(CompensationDelayContext),
     .priv_class    = &compensationdelay_class,
     .uninit        = uninit,
     FILTER_INPUTS(compensationdelay_inputs),
     FILTER_OUTPUTS(compensationdelay_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_crossfeed.c b/libavfilter/af_crossfeed.c
index bbab8f423c..ecfbb978d4 100644
--- a/libavfilter/af_crossfeed.c
+++ b/libavfilter/af_crossfeed.c
@@ -176,11 +176,11 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_crossfeed = {
     .name           = "crossfeed",
     .description    = NULL_IF_CONFIG_SMALL("Apply headphone crossfeed filter."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(CrossfeedContext),
     .priv_class     = &crossfeed_class,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = process_command,
 };
diff --git a/libavfilter/af_crystalizer.c b/libavfilter/af_crystalizer.c
index b20d360bee..9e1a4ef9d2 100644
--- a/libavfilter/af_crystalizer.c
+++ b/libavfilter/af_crystalizer.c
@@ -379,12 +379,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_crystalizer = {
     .name           = "crystalizer",
     .description    = NULL_IF_CONFIG_SMALL("Simple audio noise sharpening filter."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(CrystalizerContext),
     .priv_class     = &crystalizer_class,
     .uninit         = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                       AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_dcshift.c b/libavfilter/af_dcshift.c
index d2751df441..80f2600e7a 100644
--- a/libavfilter/af_dcshift.c
+++ b/libavfilter/af_dcshift.c
@@ -148,11 +148,11 @@  static const AVFilterPad dcshift_outputs[] = {
 const AVFilter ff_af_dcshift = {
     .name           = "dcshift",
     .description    = NULL_IF_CONFIG_SMALL("Apply a DC shift to the audio."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(DCShiftContext),
     .priv_class     = &dcshift_class,
     .init           = init,
     FILTER_INPUTS(dcshift_inputs),
     FILTER_OUTPUTS(dcshift_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_deesser.c b/libavfilter/af_deesser.c
index defea49e41..a5cc0e63ed 100644
--- a/libavfilter/af_deesser.c
+++ b/libavfilter/af_deesser.c
@@ -220,11 +220,11 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_deesser = {
     .name          = "deesser",
     .description   = NULL_IF_CONFIG_SMALL("Apply de-essing to the audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(DeesserContext),
     .priv_class    = &deesser_class,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_drmeter.c b/libavfilter/af_drmeter.c
index 338fce3fc9..010c675271 100644
--- a/libavfilter/af_drmeter.c
+++ b/libavfilter/af_drmeter.c
@@ -214,10 +214,10 @@  static const AVFilterPad drmeter_outputs[] = {
 const AVFilter ff_af_drmeter = {
     .name          = "drmeter",
     .description   = NULL_IF_CONFIG_SMALL("Measure audio dynamic range."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(DRMeterContext),
     .priv_class    = &drmeter_class,
     .uninit        = uninit,
     FILTER_INPUTS(drmeter_inputs),
     FILTER_OUTPUTS(drmeter_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c
index b78b3df85e..73dd9fb04b 100644
--- a/libavfilter/af_dynaudnorm.c
+++ b/libavfilter/af_dynaudnorm.c
@@ -859,13 +859,13 @@  static const AVFilterPad avfilter_af_dynaudnorm_outputs[] = {
 const AVFilter ff_af_dynaudnorm = {
     .name          = "dynaudnorm",
     .description   = NULL_IF_CONFIG_SMALL("Dynamic Audio Normalizer."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(DynamicAudioNormalizerContext),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
     FILTER_INPUTS(avfilter_af_dynaudnorm_inputs),
     FILTER_OUTPUTS(avfilter_af_dynaudnorm_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &dynaudnorm_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = process_command,
diff --git a/libavfilter/af_earwax.c b/libavfilter/af_earwax.c
index 2d219181d4..fa0162abb2 100644
--- a/libavfilter/af_earwax.c
+++ b/libavfilter/af_earwax.c
@@ -232,9 +232,9 @@  static const AVFilterPad earwax_outputs[] = {
 const AVFilter ff_af_earwax = {
     .name           = "earwax",
     .description    = NULL_IF_CONFIG_SMALL("Widen the stereo image."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(EarwaxContext),
     .uninit         = uninit,
     FILTER_INPUTS(earwax_inputs),
     FILTER_OUTPUTS(earwax_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_extrastereo.c b/libavfilter/af_extrastereo.c
index 0fcf840a4a..1645ccb944 100644
--- a/libavfilter/af_extrastereo.c
+++ b/libavfilter/af_extrastereo.c
@@ -120,11 +120,11 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_extrastereo = {
     .name           = "extrastereo",
     .description    = NULL_IF_CONFIG_SMALL("Increase difference between stereo audio channels."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(ExtraStereoContext),
     .priv_class     = &extrastereo_class,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c
index e147118d08..83dc3ce7ed 100644
--- a/libavfilter/af_firequalizer.c
+++ b/libavfilter/af_firequalizer.c
@@ -958,10 +958,10 @@  const AVFilter ff_af_firequalizer = {
     .name               = "firequalizer",
     .description        = NULL_IF_CONFIG_SMALL("Finite Impulse Response Equalizer."),
     .uninit             = uninit,
-    .query_formats      = query_formats,
     .process_command    = process_command,
     .priv_size          = sizeof(FIREqualizerContext),
     FILTER_INPUTS(firequalizer_inputs),
     FILTER_OUTPUTS(firequalizer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class         = &firequalizer_class,
 };
diff --git a/libavfilter/af_flanger.c b/libavfilter/af_flanger.c
index b0d765365c..ecf7f9365b 100644
--- a/libavfilter/af_flanger.c
+++ b/libavfilter/af_flanger.c
@@ -221,11 +221,11 @@  static const AVFilterPad flanger_outputs[] = {
 const AVFilter ff_af_flanger = {
     .name          = "flanger",
     .description   = NULL_IF_CONFIG_SMALL("Apply a flanging effect to the audio."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(FlangerContext),
     .priv_class    = &flanger_class,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(flanger_inputs),
     FILTER_OUTPUTS(flanger_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_haas.c b/libavfilter/af_haas.c
index e162e4b7f0..281ec276f9 100644
--- a/libavfilter/af_haas.c
+++ b/libavfilter/af_haas.c
@@ -216,10 +216,10 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_haas = {
     .name           = "haas",
     .description    = NULL_IF_CONFIG_SMALL("Apply Haas Stereo Enhancer."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(HaasContext),
     .priv_class     = &haas_class,
     .uninit         = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 94a9c701a5..494642106d 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1777,7 +1777,7 @@  const AVFilter ff_af_hdcd = {
     .priv_class    = &hdcd_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_af_hdcd_inputs),
     FILTER_OUTPUTS(avfilter_af_hdcd_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c
index 0cb188b61d..b2030dbbbb 100644
--- a/libavfilter/af_headphone.c
+++ b/libavfilter/af_headphone.c
@@ -763,9 +763,9 @@  const AVFilter ff_af_headphone = {
     .priv_class    = &headphone_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index 2fe1fc9429..6cc21f465c 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -541,8 +541,8 @@  const AVFilter ff_af_join = {
     .init           = join_init,
     .uninit         = join_uninit,
     .activate       = activate,
-    .query_formats  = join_query_formats,
     .inputs         = NULL,
     FILTER_OUTPUTS(avfilter_af_join_outputs),
+    FILTER_QUERY_FUNC(join_query_formats),
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_ladspa.c b/libavfilter/af_ladspa.c
index 73cbd288c0..ff16388a56 100644
--- a/libavfilter/af_ladspa.c
+++ b/libavfilter/af_ladspa.c
@@ -778,9 +778,9 @@  const AVFilter ff_af_ladspa = {
     .priv_class    = &ladspa_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .process_command = process_command,
     .inputs        = 0,
     FILTER_OUTPUTS(ladspa_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_loudnorm.c b/libavfilter/af_loudnorm.c
index 7807ed927a..dbe7fba986 100644
--- a/libavfilter/af_loudnorm.c
+++ b/libavfilter/af_loudnorm.c
@@ -911,9 +911,9 @@  const AVFilter ff_af_loudnorm = {
     .description   = NULL_IF_CONFIG_SMALL("EBU R128 loudness normalization"),
     .priv_size     = sizeof(LoudNormContext),
     .priv_class    = &loudnorm_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(avfilter_af_loudnorm_inputs),
     FILTER_OUTPUTS(avfilter_af_loudnorm_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c
index 75c7494cc8..0f0c797989 100644
--- a/libavfilter/af_lv2.c
+++ b/libavfilter/af_lv2.c
@@ -578,8 +578,8 @@  const AVFilter ff_af_lv2 = {
     .priv_class    = &lv2_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .inputs        = 0,
     FILTER_OUTPUTS(lv2_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_mcompand.c b/libavfilter/af_mcompand.c
index 0ae84221b6..5b689caa49 100644
--- a/libavfilter/af_mcompand.c
+++ b/libavfilter/af_mcompand.c
@@ -654,10 +654,10 @@  const AVFilter ff_af_mcompand = {
     .name           = "mcompand",
     .description    = NULL_IF_CONFIG_SMALL(
             "Multiband Compress or expand audio dynamic range."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(MCompandContext),
     .priv_class     = &mcompand_class,
     .uninit         = uninit,
     FILTER_INPUTS(mcompand_inputs),
     FILTER_OUTPUTS(mcompand_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index d17e45438d..a8a18960c4 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -451,7 +451,7 @@  const AVFilter ff_af_pan = {
     .priv_class    = &pan_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(pan_inputs),
     FILTER_OUTPUTS(pan_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_replaygain.c b/libavfilter/af_replaygain.c
index 7db7fe4178..4bf2763bcf 100644
--- a/libavfilter/af_replaygain.c
+++ b/libavfilter/af_replaygain.c
@@ -604,9 +604,9 @@  static const AVFilterPad replaygain_outputs[] = {
 const AVFilter ff_af_replaygain = {
     .name          = "replaygain",
     .description   = NULL_IF_CONFIG_SMALL("ReplayGain scanner."),
-    .query_formats = query_formats,
     .uninit        = uninit,
     .priv_size     = sizeof(ReplayGainContext),
     FILTER_INPUTS(replaygain_inputs),
     FILTER_OUTPUTS(replaygain_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_rubberband.c b/libavfilter/af_rubberband.c
index 6a4b71d09d..77f6c820be 100644
--- a/libavfilter/af_rubberband.c
+++ b/libavfilter/af_rubberband.c
@@ -222,12 +222,12 @@  static const AVFilterPad rubberband_outputs[] = {
 const AVFilter ff_af_rubberband = {
     .name          = "rubberband",
     .description   = NULL_IF_CONFIG_SMALL("Apply time-stretching and pitch-shifting."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(RubberBandContext),
     .priv_class    = &rubberband_class,
     .uninit        = uninit,
     .activate      = activate,
     FILTER_INPUTS(rubberband_inputs),
     FILTER_OUTPUTS(rubberband_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c
index 22a86ae2a7..7359ba8e7e 100644
--- a/libavfilter/af_sidechaincompress.c
+++ b/libavfilter/af_sidechaincompress.c
@@ -366,11 +366,11 @@  const AVFilter ff_af_sidechaincompress = {
     .description    = NULL_IF_CONFIG_SMALL("Sidechain compressor."),
     .priv_class     = &sidechaincompress_acompressor_class,
     .priv_size      = sizeof(SidechainCompressContext),
-    .query_formats  = query_formats,
     .activate       = activate,
     .uninit         = uninit,
     FILTER_INPUTS(sidechaincompress_inputs),
     FILTER_OUTPUTS(sidechaincompress_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
 #endif  /* CONFIG_SIDECHAINCOMPRESS_FILTER */
@@ -444,9 +444,9 @@  const AVFilter ff_af_acompressor = {
     .description    = NULL_IF_CONFIG_SMALL("Audio compressor."),
     .priv_class     = &sidechaincompress_acompressor_class,
     .priv_size      = sizeof(SidechainCompressContext),
-    .query_formats  = acompressor_query_formats,
     FILTER_INPUTS(acompressor_inputs),
     FILTER_OUTPUTS(acompressor_outputs),
+    FILTER_QUERY_FUNC(acompressor_query_formats),
     .process_command = process_command,
 };
 #endif  /* CONFIG_ACOMPRESSOR_FILTER */
diff --git a/libavfilter/af_silencedetect.c b/libavfilter/af_silencedetect.c
index eb38d2811c..482270d3f7 100644
--- a/libavfilter/af_silencedetect.c
+++ b/libavfilter/af_silencedetect.c
@@ -284,9 +284,9 @@  const AVFilter ff_af_silencedetect = {
     .name          = "silencedetect",
     .description   = NULL_IF_CONFIG_SMALL("Detect silence."),
     .priv_size     = sizeof(SilenceDetectContext),
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(silencedetect_inputs),
     FILTER_OUTPUTS(silencedetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &silencedetect_class,
 };
diff --git a/libavfilter/af_silenceremove.c b/libavfilter/af_silenceremove.c
index 42cdb4efad..1b420d7838 100644
--- a/libavfilter/af_silenceremove.c
+++ b/libavfilter/af_silenceremove.c
@@ -979,7 +979,7 @@  const AVFilter ff_af_silenceremove = {
     .priv_class    = &silenceremove_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(silenceremove_inputs),
     FILTER_OUTPUTS(silenceremove_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c
index 52832e0ee2..20b717bdf8 100644
--- a/libavfilter/af_sofalizer.c
+++ b/libavfilter/af_sofalizer.c
@@ -1112,8 +1112,8 @@  const AVFilter ff_af_sofalizer = {
     .init          = init,
     .activate      = activate,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_speechnorm.c b/libavfilter/af_speechnorm.c
index f56ca8e558..bc83a347e9 100644
--- a/libavfilter/af_speechnorm.c
+++ b/libavfilter/af_speechnorm.c
@@ -562,13 +562,13 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_speechnorm = {
     .name            = "speechnorm",
     .description     = NULL_IF_CONFIG_SMALL("Speech Normalizer."),
-    .query_formats   = query_formats,
     .priv_size       = sizeof(SpeechNormalizerContext),
     .priv_class      = &speechnorm_class,
     .activate        = activate,
     .uninit          = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = process_command,
 };
diff --git a/libavfilter/af_stereotools.c b/libavfilter/af_stereotools.c
index d4aca66a92..27ec4a2e4a 100644
--- a/libavfilter/af_stereotools.c
+++ b/libavfilter/af_stereotools.c
@@ -375,12 +375,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_stereotools = {
     .name           = "stereotools",
     .description    = NULL_IF_CONFIG_SMALL("Apply various stereo tools."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(StereoToolsContext),
     .priv_class     = &stereotools_class,
     .uninit         = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_stereowiden.c b/libavfilter/af_stereowiden.c
index ce194ec5b4..7cce1a8f28 100644
--- a/libavfilter/af_stereowiden.c
+++ b/libavfilter/af_stereowiden.c
@@ -156,12 +156,12 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_stereowiden = {
     .name           = "stereowiden",
     .description    = NULL_IF_CONFIG_SMALL("Apply stereo widening effect."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(StereoWidenContext),
     .priv_class     = &stereowiden_class,
     .uninit         = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/af_superequalizer.c b/libavfilter/af_superequalizer.c
index 69e03e8820..bf55f3ab94 100644
--- a/libavfilter/af_superequalizer.c
+++ b/libavfilter/af_superequalizer.c
@@ -368,10 +368,10 @@  const AVFilter ff_af_superequalizer = {
     .description   = NULL_IF_CONFIG_SMALL("Apply 18 band equalization filter."),
     .priv_size     = sizeof(SuperEqualizerContext),
     .priv_class    = &superequalizer_class,
-    .query_formats = query_formats,
     .init          = init,
     .activate      = activate,
     .uninit        = uninit,
     FILTER_INPUTS(superequalizer_inputs),
     FILTER_OUTPUTS(superequalizer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c
index 33190de248..e3601b9df0 100644
--- a/libavfilter/af_surround.c
+++ b/libavfilter/af_surround.c
@@ -1783,7 +1783,6 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_af_surround = {
     .name           = "surround",
     .description    = NULL_IF_CONFIG_SMALL("Apply audio surround upmix filter."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(AudioSurroundContext),
     .priv_class     = &surround_class,
     .init           = init,
@@ -1791,5 +1790,6 @@  const AVFilter ff_af_surround = {
     .activate       = activate,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_tremolo.c b/libavfilter/af_tremolo.c
index 1ab7832d47..df101cd032 100644
--- a/libavfilter/af_tremolo.c
+++ b/libavfilter/af_tremolo.c
@@ -151,7 +151,7 @@  const AVFilter ff_af_tremolo = {
     .priv_size     = sizeof(TremoloContext),
     .priv_class    = &tremolo_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_af_tremolo_inputs),
     FILTER_OUTPUTS(avfilter_af_tremolo_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_vibrato.c b/libavfilter/af_vibrato.c
index ec6f6558b0..46b6b766bf 100644
--- a/libavfilter/af_vibrato.c
+++ b/libavfilter/af_vibrato.c
@@ -189,7 +189,7 @@  const AVFilter ff_af_vibrato = {
     .priv_size     = sizeof(VibratoContext),
     .priv_class    = &vibrato_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_af_vibrato_inputs),
     FILTER_OUTPUTS(avfilter_af_vibrato_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index 2d4012bfbf..76ccddc316 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -465,13 +465,13 @@  static const AVFilterPad avfilter_af_volume_outputs[] = {
 const AVFilter ff_af_volume = {
     .name           = "volume",
     .description    = NULL_IF_CONFIG_SMALL("Change input volume."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(VolumeContext),
     .priv_class     = &volume_class,
     .init           = init,
     .uninit         = uninit,
     FILTER_INPUTS(avfilter_af_volume_inputs),
     FILTER_OUTPUTS(avfilter_af_volume_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
index 412b690302..ba49b3ca37 100644
--- a/libavfilter/af_volumedetect.c
+++ b/libavfilter/af_volumedetect.c
@@ -147,8 +147,8 @@  const AVFilter ff_af_volumedetect = {
     .name          = "volumedetect",
     .description   = NULL_IF_CONFIG_SMALL("Detect audio volume."),
     .priv_size     = sizeof(VolDetectContext),
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(volumedetect_inputs),
     FILTER_OUTPUTS(volumedetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/asrc_afirsrc.c b/libavfilter/asrc_afirsrc.c
index cea9b2fe8a..79e7842cea 100644
--- a/libavfilter/asrc_afirsrc.c
+++ b/libavfilter/asrc_afirsrc.c
@@ -311,12 +311,12 @@  static const AVFilterPad afirsrc_outputs[] = {
 const AVFilter ff_asrc_afirsrc = {
     .name          = "afirsrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate a FIR coefficients audio stream."),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
     .priv_size     = sizeof(AudioFIRSourceContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(afirsrc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &afirsrc_class,
 };
diff --git a/libavfilter/asrc_anoisesrc.c b/libavfilter/asrc_anoisesrc.c
index ca86658040..8c834492fe 100644
--- a/libavfilter/asrc_anoisesrc.c
+++ b/libavfilter/asrc_anoisesrc.c
@@ -235,10 +235,10 @@  static const AVFilterPad anoisesrc_outputs[] = {
 const AVFilter ff_asrc_anoisesrc = {
     .name          = "anoisesrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate a noise audio signal."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(ANoiseSrcContext),
     .inputs        = NULL,
     .activate      = activate,
     FILTER_OUTPUTS(anoisesrc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &anoisesrc_class,
 };
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 698102deda..7ee2fa5a5d 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -140,10 +140,10 @@  const AVFilter ff_asrc_anullsrc = {
     .name          = "anullsrc",
     .description   = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."),
     .init          = init,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ANullContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_asrc_anullsrc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
     .priv_class    = &anullsrc_class,
 };
diff --git a/libavfilter/asrc_flite.c b/libavfilter/asrc_flite.c
index 61c177e0ba..c861f5c238 100644
--- a/libavfilter/asrc_flite.c
+++ b/libavfilter/asrc_flite.c
@@ -276,11 +276,11 @@  static const AVFilterPad flite_outputs[] = {
 const AVFilter ff_asrc_flite = {
     .name          = "flite",
     .description   = NULL_IF_CONFIG_SMALL("Synthesize voice from text using libflite."),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .priv_size     = sizeof(FliteContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(flite_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &flite_class,
 };
diff --git a/libavfilter/asrc_hilbert.c b/libavfilter/asrc_hilbert.c
index 8ff9934967..56abe4611c 100644
--- a/libavfilter/asrc_hilbert.c
+++ b/libavfilter/asrc_hilbert.c
@@ -181,12 +181,12 @@  static const AVFilterPad hilbert_outputs[] = {
 const AVFilter ff_asrc_hilbert = {
     .name          = "hilbert",
     .description   = NULL_IF_CONFIG_SMALL("Generate a Hilbert transform FIR coefficients."),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
     .priv_size     = sizeof(HilbertContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(hilbert_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &hilbert_class,
 };
diff --git a/libavfilter/asrc_sinc.c b/libavfilter/asrc_sinc.c
index e2d3ea62ff..aaa81291a8 100644
--- a/libavfilter/asrc_sinc.c
+++ b/libavfilter/asrc_sinc.c
@@ -441,9 +441,9 @@  const AVFilter ff_asrc_sinc = {
     .description   = NULL_IF_CONFIG_SMALL("Generate a sinc kaiser-windowed low-pass, high-pass, band-pass, or band-reject FIR coefficients."),
     .priv_size     = sizeof(SincContext),
     .priv_class    = &sinc_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(sinc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c
index ef4e346e7b..c8995ae2c9 100644
--- a/libavfilter/asrc_sine.c
+++ b/libavfilter/asrc_sine.c
@@ -263,12 +263,12 @@  static const AVFilterPad sine_outputs[] = {
 const AVFilter ff_asrc_sine = {
     .name          = "sine",
     .description   = NULL_IF_CONFIG_SMALL("Generate sine wave audio signal."),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
     .priv_size     = sizeof(SineContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(sine_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &sine_class,
 };
diff --git a/libavfilter/avf_abitscope.c b/libavfilter/avf_abitscope.c
index c394091b7b..f74a6eacb0 100644
--- a/libavfilter/avf_abitscope.c
+++ b/libavfilter/avf_abitscope.c
@@ -261,10 +261,10 @@  static const AVFilterPad outputs[] = {
 const AVFilter ff_avf_abitscope = {
     .name          = "abitscope",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to audio bit scope video output."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioBitScopeContext),
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
     .priv_class    = &abitscope_class,
 };
diff --git a/libavfilter/avf_ahistogram.c b/libavfilter/avf_ahistogram.c
index 96baf6da83..258b062873 100644
--- a/libavfilter/avf_ahistogram.c
+++ b/libavfilter/avf_ahistogram.c
@@ -426,10 +426,10 @@  const AVFilter ff_avf_ahistogram = {
     .name          = "ahistogram",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to histogram video output."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioHistogramContext),
     .activate      = activate,
     FILTER_INPUTS(ahistogram_inputs),
     FILTER_OUTPUTS(ahistogram_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &ahistogram_class,
 };
diff --git a/libavfilter/avf_aphasemeter.c b/libavfilter/avf_aphasemeter.c
index 13035328e9..d9302cf867 100644
--- a/libavfilter/avf_aphasemeter.c
+++ b/libavfilter/avf_aphasemeter.c
@@ -387,10 +387,10 @@  const AVFilter ff_avf_aphasemeter = {
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to phase meter video output."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioPhaseMeterContext),
     FILTER_INPUTS(inputs),
     .outputs       = NULL,
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &aphasemeter_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c
index e927b241ff..ba392153f3 100644
--- a/libavfilter/avf_avectorscope.c
+++ b/libavfilter/avf_avectorscope.c
@@ -445,11 +445,11 @@  const AVFilter ff_avf_avectorscope = {
     .name          = "avectorscope",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to vectorscope video output."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(AudioVectorScopeContext),
     .activate      = activate,
     FILTER_INPUTS(audiovectorscope_inputs),
     FILTER_OUTPUTS(audiovectorscope_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &avectorscope_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
index 2ae24e9b39..84c2a52094 100644
--- a/libavfilter/avf_concat.c
+++ b/libavfilter/avf_concat.c
@@ -449,12 +449,12 @@  const AVFilter ff_avf_concat = {
     .description   = NULL_IF_CONFIG_SMALL("Concatenate audio and video streams."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(ConcatContext),
     .inputs        = NULL,
     .outputs       = NULL,
     .priv_class    = &concat_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_DYNAMIC_OUTPUTS,
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
index aab4aa28d6..6f63574a8f 100644
--- a/libavfilter/avf_showcqt.c
+++ b/libavfilter/avf_showcqt.c
@@ -1593,9 +1593,9 @@  const AVFilter ff_avf_showcqt = {
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a CQT (Constant/Clamped Q Transform) spectrum video output."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowCQTContext),
     FILTER_INPUTS(showcqt_inputs),
     FILTER_OUTPUTS(showcqt_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showcqt_class,
 };
diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c
index 7eff726139..52beb75a5b 100644
--- a/libavfilter/avf_showfreqs.c
+++ b/libavfilter/avf_showfreqs.c
@@ -567,10 +567,10 @@  const AVFilter ff_avf_showfreqs = {
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a frequencies video output."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowFreqsContext),
     .activate      = activate,
     FILTER_INPUTS(showfreqs_inputs),
     FILTER_OUTPUTS(showfreqs_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showfreqs_class,
 };
diff --git a/libavfilter/avf_showspatial.c b/libavfilter/avf_showspatial.c
index c5af903216..3069fcb4a3 100644
--- a/libavfilter/avf_showspatial.c
+++ b/libavfilter/avf_showspatial.c
@@ -360,10 +360,10 @@  const AVFilter ff_avf_showspatial = {
     .name          = "showspatial",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a spatial video output."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowSpatialContext),
     FILTER_INPUTS(showspatial_inputs),
     FILTER_OUTPUTS(showspatial_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = spatial_activate,
     .priv_class    = &showspatial_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index a33ef71689..2c0a3d1395 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -1646,10 +1646,10 @@  const AVFilter ff_avf_showspectrum = {
     .name          = "showspectrum",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a spectrum video output."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowSpectrumContext),
     FILTER_INPUTS(showspectrum_inputs),
     FILTER_OUTPUTS(showspectrum_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
     .priv_class    = &showspectrum_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
@@ -1829,10 +1829,10 @@  const AVFilter ff_avf_showspectrumpic = {
     .name          = "showspectrumpic",
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a spectrum video output single picture."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowSpectrumContext),
     FILTER_INPUTS(showspectrumpic_inputs),
     FILTER_OUTPUTS(showspectrumpic_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showspectrumpic_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/avf_showvolume.c b/libavfilter/avf_showvolume.c
index 2fd8298b85..401b65ca69 100644
--- a/libavfilter/avf_showvolume.c
+++ b/libavfilter/avf_showvolume.c
@@ -502,9 +502,9 @@  const AVFilter ff_avf_showvolume = {
     .init          = init,
     .activate      = activate,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowVolumeContext),
     FILTER_INPUTS(showvolume_inputs),
     FILTER_OUTPUTS(showvolume_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showvolume_class,
 };
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index 90180309dd..853f6bbdcb 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -778,11 +778,11 @@  const AVFilter ff_avf_showwaves = {
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a video output."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowWavesContext),
     FILTER_INPUTS(showwaves_inputs),
     .activate      = activate,
     FILTER_OUTPUTS(showwaves_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showwaves_class,
 };
 
@@ -891,10 +891,10 @@  const AVFilter ff_avf_showwavespic = {
     .description   = NULL_IF_CONFIG_SMALL("Convert input audio to a video output single picture."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(ShowWavesContext),
     FILTER_INPUTS(showwavespic_inputs),
     FILTER_OUTPUTS(showwavespic_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showwavespic_class,
 };
 
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 69ecb0186d..566c1b87ce 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -203,12 +203,18 @@  typedef struct AVFilter {
     /**
      * The number of entries in the list of inputs.
      */
-    uint16_t nb_inputs;
+    uint8_t nb_inputs;
 
     /**
      * The number of entries in the list of outputs.
      */
-    uint16_t nb_outputs;
+    uint8_t nb_outputs;
+
+    /**
+     * This field determines the state of the formats union.
+     * It is an enum FilterFormatsState value.
+     */
+    uint8_t formats_state;
 
     /**
      * Filter pre-initialization function
@@ -273,6 +279,11 @@  typedef struct AVFilter {
      */
     void (*uninit)(AVFilterContext *ctx);
 
+    /**
+     * The state of the following union is determined by formats_state.
+     * See the documentation of enum FilterFormatsState in internal.h.
+     */
+    union {
     /**
      * Query formats supported by the filter on its inputs and outputs.
      *
@@ -288,14 +299,43 @@  typedef struct AVFilter {
      * @ref AVFilterLink.incfg.channel_layouts "in_channel_layouts" /
      * @ref AVFilterLink.outcfg.channel_layouts "out_channel_layouts" analogously.
      *
-     * This callback may be NULL for filters with one input, in which case
-     * libavfilter assumes that it supports all input formats and preserves
-     * them on output.
+     * This callback must never be NULL if the union is in this state.
      *
      * @return zero on success, a negative value corresponding to an
      * AVERROR code otherwise
      */
-    int (*query_formats)(AVFilterContext *);
+        int (*query_func)(AVFilterContext *);
+        /**
+         * A pointer to an array of admissible pixel formats delimited
+         * by AV_PIX_FMT_NONE. The generic code will use this list
+         * to indicate that this filter supports each of these pixel formats,
+         * provided that all inputs and outputs use the same pixel format.
+         *
+         * This list must never be NULL if the union is in this state.
+         * The type of all inputs and outputs of filters using this must
+         * be AVMEDIA_TYPE_VIDEO.
+         */
+        const enum AVPixelFormat *pixels_list;
+        /**
+         * Analogous to pixels, but delimited by AV_SAMPLE_FMT_NONE
+         * and restricted to filters that only have AVMEDIA_TYPE_AUDIO
+         * inputs and outputs.
+         *
+         * In addition to that the generic code will mark all inputs
+         * and all outputs as supporting all sample rates and every
+         * channel count and channel layout, as long as all inputs
+         * and outputs use the same sample rate and channel count/layout.
+         */
+        const enum AVSampleFormat *samples_list;
+        /**
+         * Equivalent to { pix_fmt, AV_PIX_FMT_NONE } as pixels_list.
+         */
+        enum AVPixelFormat  pix_fmt;
+        /**
+         * Equivalent to { sample_fmt, AV_SAMPLE_FMT_NONE } as samples_list.
+         */
+        enum AVSampleFormat sample_fmt;
+    } formats;
 
     int priv_size;      ///< size of private data to allocate for the filter
 
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 45b028cd9c..7165bb722d 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -352,7 +352,7 @@  static int filter_query_formats(AVFilterContext *ctx)
                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
                             AVMEDIA_TYPE_VIDEO;
 
-    if ((ret = ctx->filter->query_formats(ctx)) < 0) {
+    if ((ret = ctx->filter->formats.query_func(ctx)) < 0) {
         if (ret != AVERROR(EAGAIN))
             av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
                    ctx->name, av_err2str(ret));
@@ -421,7 +421,7 @@  static int query_formats(AVFilterGraph *graph, void *log_ctx)
         AVFilterContext *f = graph->filters[i];
         if (formats_declared(f))
             continue;
-        if (f->filter->query_formats)
+        if (f->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
             ret = filter_query_formats(f);
         else
             ret = ff_default_query_formats(f);
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 8b46dcb15e..b8ddafec35 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -339,10 +339,10 @@  const AVFilter ff_vsink_buffer = {
     .priv_size     = sizeof(BufferSinkContext),
     .priv_class    = &buffersink_class,
     .init          = common_init,
-    .query_formats = vsink_query_formats,
     .activate      = activate,
     FILTER_INPUTS(avfilter_vsink_buffer_inputs),
     .outputs       = NULL,
+    FILTER_QUERY_FUNC(vsink_query_formats),
 };
 
 static const AVFilterPad avfilter_asink_abuffer_inputs[] = {
@@ -358,8 +358,8 @@  const AVFilter ff_asink_abuffer = {
     .priv_class    = &abuffersink_class,
     .priv_size     = sizeof(BufferSinkContext),
     .init          = common_init,
-    .query_formats = asink_query_formats,
     .activate      = activate,
     FILTER_INPUTS(avfilter_asink_abuffer_inputs),
     .outputs       = NULL,
+    FILTER_QUERY_FUNC(asink_query_formats),
 };
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 632bfc7ad8..b0611872f1 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -440,13 +440,13 @@  const AVFilter ff_vsrc_buffer = {
     .name      = "buffer",
     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
     .priv_size = sizeof(BufferSourceContext),
-    .query_formats = query_formats,
 
     .init      = init_video,
     .uninit    = uninit,
 
     .inputs    = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_buffer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class = &buffer_class,
 };
 
@@ -463,12 +463,12 @@  const AVFilter ff_asrc_abuffer = {
     .name          = "abuffer",
     .description   = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
     .priv_size     = sizeof(BufferSourceContext),
-    .query_formats = query_formats,
 
     .init      = init_audio,
     .uninit    = uninit,
 
     .inputs    = NULL,
     FILTER_OUTPUTS(avfilter_asrc_abuffer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class = &abuffer_class,
 };
diff --git a/libavfilter/f_drawgraph.c b/libavfilter/f_drawgraph.c
index 9996eb3b0e..b6fcb3b75e 100644
--- a/libavfilter/f_drawgraph.c
+++ b/libavfilter/f_drawgraph.c
@@ -474,11 +474,11 @@  const AVFilter ff_vf_drawgraph = {
     .description   = NULL_IF_CONFIG_SMALL("Draw a graph using input video metadata."),
     .priv_size     = sizeof(DrawGraphContext),
     .priv_class    = &drawgraph_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(drawgraph_inputs),
     FILTER_OUTPUTS(drawgraph_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 
 #endif // CONFIG_DRAWGRAPH_FILTER
@@ -507,10 +507,10 @@  const AVFilter ff_avf_adrawgraph = {
     .description   = NULL_IF_CONFIG_SMALL("Draw a graph using input audio metadata."),
     .priv_class    = &drawgraph_class,
     .priv_size     = sizeof(DrawGraphContext),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(adrawgraph_inputs),
     FILTER_OUTPUTS(adrawgraph_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 #endif // CONFIG_ADRAWGRAPH_FILTER
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
index 2ce8a749cf..88d6a1fe46 100644
--- a/libavfilter/f_ebur128.c
+++ b/libavfilter/f_ebur128.c
@@ -1025,9 +1025,9 @@  const AVFilter ff_af_ebur128 = {
     .priv_size     = sizeof(EBUR128Context),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(ebur128_inputs),
     .outputs       = NULL,
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &ebur128_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/f_graphmonitor.c b/libavfilter/f_graphmonitor.c
index de91a863c2..51d0a568e3 100644
--- a/libavfilter/f_graphmonitor.c
+++ b/libavfilter/f_graphmonitor.c
@@ -410,10 +410,10 @@  const AVFilter ff_vf_graphmonitor = {
     .description   = NULL_IF_CONFIG_SMALL("Show various filtergraph stats."),
     .priv_size     = sizeof(GraphMonitorContext),
     .priv_class    = &graphmonitor_class,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(graphmonitor_inputs),
     FILTER_OUTPUTS(graphmonitor_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 
 #endif // CONFIG_GRAPHMONITOR_FILTER
@@ -440,9 +440,9 @@  const AVFilter ff_avf_agraphmonitor = {
     .description   = NULL_IF_CONFIG_SMALL("Show various filtergraph stats."),
     .priv_class    = &graphmonitor_class,
     .priv_size     = sizeof(GraphMonitorContext),
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(agraphmonitor_inputs),
     FILTER_OUTPUTS(agraphmonitor_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 #endif // CONFIG_AGRAPHMONITOR_FILTER
diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c
index 187e98a1a7..47e7d1fef8 100644
--- a/libavfilter/f_select.c
+++ b/libavfilter/f_select.c
@@ -529,10 +529,10 @@  const AVFilter ff_vf_select = {
     .description   = NULL_IF_CONFIG_SMALL("Select video frames to pass in output."),
     .init          = select_init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(SelectContext),
     .priv_class    = &select_class,
     FILTER_INPUTS(avfilter_vf_select_inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
 #endif /* CONFIG_SELECT_FILTER */
diff --git a/libavfilter/f_streamselect.c b/libavfilter/f_streamselect.c
index 80a133fec3..3708d2b256 100644
--- a/libavfilter/f_streamselect.c
+++ b/libavfilter/f_streamselect.c
@@ -318,7 +318,7 @@  const AVFilter ff_vf_streamselect = {
     .name            = "streamselect",
     .description     = NULL_IF_CONFIG_SMALL("Select video streams"),
     .init            = init,
-    .query_formats   = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .uninit          = uninit,
     .activate        = activate,
@@ -332,7 +332,7 @@  const AVFilter ff_af_astreamselect = {
     .description     = NULL_IF_CONFIG_SMALL("Select audio streams"),
     .priv_class      = &streamselect_class,
     .init            = init,
-    .query_formats   = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .uninit          = uninit,
     .activate        = activate,
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index d5b8fa8e50..48927842c2 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -709,12 +709,40 @@  int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
 
 int ff_default_query_formats(AVFilterContext *ctx)
 {
+    const AVFilter *const f = ctx->filter;
+    AVFilterFormats *formats;
+    enum AVMediaType type;
     int ret;
-    enum AVMediaType type = ctx->nb_inputs  ? ctx->inputs [0]->type :
-                            ctx->nb_outputs ? ctx->outputs[0]->type :
-                            AVMEDIA_TYPE_VIDEO;
 
-    ret = ff_set_common_formats(ctx, ff_all_formats(type));
+    switch (f->formats_state) {
+    case FF_FILTER_FORMATS_PIXFMT_LIST:
+        type    = AVMEDIA_TYPE_VIDEO;
+        formats = ff_make_format_list(f->formats.pixels_list);
+        break;
+    case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
+        type    = AVMEDIA_TYPE_AUDIO;
+        formats = ff_make_format_list(f->formats.samples_list);
+        break;
+    case FF_FILTER_FORMATS_SINGLE_PIXFMT:
+        type    = AVMEDIA_TYPE_VIDEO;
+        formats = ff_make_format_from_entry(f->formats.pix_fmt);
+        break;
+    case FF_FILTER_FORMATS_SINGLE_SAMPLEFMT:
+        type    = AVMEDIA_TYPE_AUDIO;
+        formats = ff_make_format_from_entry(f->formats.sample_fmt);
+        break;
+    default:
+        av_assert2(!"Unreachable");
+    /* Intended fallthrough */
+    case FF_FILTER_FORMATS_PASSTHROUGH:
+    case FF_FILTER_FORMATS_QUERY_FUNC:
+        type    = ctx->nb_inputs  ? ctx->inputs [0]->type :
+                  ctx->nb_outputs ? ctx->outputs[0]->type : AVMEDIA_TYPE_VIDEO;
+        formats = ff_all_formats(type);
+        break;
+    }
+
+    ret = ff_set_common_formats(ctx, formats);
     if (ret < 0)
         return ret;
     if (type == AVMEDIA_TYPE_AUDIO) {
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index e7c154aff0..5ac9b04050 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -146,6 +146,45 @@  static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_act
     return ctx->internal->execute(ctx, func, arg, ret, nb_jobs);
 }
 
+enum FilterFormatsState {
+    /**
+     * The default value meaning that this filter supports all formats
+     * and (for audio) sample rates and channel layouts/counts as long
+     * as these properties agree for all inputs and outputs.
+     * This state is only allowed in case all inputs and outputs actually
+     * have the same type.
+     * The union is unused in this state.
+     *
+     * This value must always be zero (for default static initialization).
+     */
+    FF_FILTER_FORMATS_PASSTHROUGH = 0,
+    FF_FILTER_FORMATS_QUERY_FUNC,       ///< formats.query active.
+    FF_FILTER_FORMATS_PIXFMT_LIST,      ///< formats.pixels_list active.
+    FF_FILTER_FORMATS_SAMPLEFMTS_LIST,  ///< formats.samples_list active.
+    FF_FILTER_FORMATS_SINGLE_PIXFMT,    ///< formats.pix_fmt active
+    FF_FILTER_FORMATS_SINGLE_SAMPLEFMT, ///< formats.sample_fmt active.
+};
+
+#define FILTER_QUERY_FUNC(func)        \
+        .formats.query_func   = func,  \
+        .formats_state        = FF_FILTER_FORMATS_QUERY_FUNC
+#define FILTER_PIXFMTS_ARRAY(array)    \
+        .formats.pixels_list  = array, \
+        .formats_state        = FF_FILTER_FORMATS_PIXFMT_LIST
+#define FILTER_SAMPLEFMTS_ARRAY(array) \
+        .formats.samples_list = array, \
+        .formats_state        = FF_FILTER_FORMATS_SAMPLEFMTS_LIST
+#define FILTER_PIXFMTS(...)            \
+    FILTER_PIXFMTS_ARRAY(((const enum AVPixelFormat []) { __VA_ARGS__, AV_PIX_FMT_NONE }))
+#define FILTER_SAMPLEFMTS(...)         \
+    FILTER_SAMPLEFMTS_ARRAY(((const enum AVSampleFormat[]) { __VA_ARGS__, AV_SAMPLE_FMT_NONE }))
+#define FILTER_SINGLE_PIXFMT(pix_fmt_)  \
+        .formats.pix_fmt = pix_fmt_,    \
+        .formats_state   = FF_FILTER_FORMATS_SINGLE_PIXFMT
+#define FILTER_SINGLE_SAMPLEFMT(sample_fmt_) \
+        .formats.sample_fmt = sample_fmt_,   \
+        .formats_state      = FF_FILTER_FORMATS_SINGLE_SAMPLEFMT
+
 #define FILTER_INOUTPADS(inout, array) \
        .inout        = array, \
        .nb_ ## inout = FF_ARRAY_ELEMS(array)
diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
index 27b17c6a9d..573f363705 100644
--- a/libavfilter/src_movie.c
+++ b/libavfilter/src_movie.c
@@ -641,7 +641,7 @@  const AVFilter ff_avsrc_movie = {
     .priv_class    = &movie_class,
     .init          = movie_common_init,
     .uninit        = movie_uninit,
-    .query_formats = movie_query_formats,
+    FILTER_QUERY_FUNC(movie_query_formats),
 
     .inputs    = NULL,
     .outputs   = NULL,
@@ -660,7 +660,7 @@  const AVFilter ff_avsrc_amovie = {
     .priv_size     = sizeof(MovieContext),
     .init          = movie_common_init,
     .uninit        = movie_uninit,
-    .query_formats = movie_query_formats,
+    FILTER_QUERY_FUNC(movie_query_formats),
 
     .inputs     = NULL,
     .outputs    = NULL,
diff --git a/libavfilter/tests/filtfmts.c b/libavfilter/tests/filtfmts.c
index 356f467331..55bb64abc5 100644
--- a/libavfilter/tests/filtfmts.c
+++ b/libavfilter/tests/filtfmts.c
@@ -137,8 +137,8 @@  int main(int argc, char **argv)
         filter_ctx->outputs[i] = link;
     }
 
-    if (filter->query_formats)
-        ret = filter->query_formats(filter_ctx);
+    if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
+        ret = filter->formats.query_func(filter_ctx);
     else
         ret = ff_default_query_formats(filter_ctx);
 
diff --git a/libavfilter/vaf_spectrumsynth.c b/libavfilter/vaf_spectrumsynth.c
index a59170ea02..a558da244e 100644
--- a/libavfilter/vaf_spectrumsynth.c
+++ b/libavfilter/vaf_spectrumsynth.c
@@ -546,10 +546,10 @@  const AVFilter ff_vaf_spectrumsynth = {
     .name          = "spectrumsynth",
     .description   = NULL_IF_CONFIG_SMALL("Convert input spectrum videos to audio output."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(SpectrumSynthContext),
     FILTER_INPUTS(spectrumsynth_inputs),
     FILTER_OUTPUTS(spectrumsynth_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &spectrumsynth_class,
 };
diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
index 8fb601ce06..4bbc06da36 100644
--- a/libavfilter/vf_alphamerge.c
+++ b/libavfilter/vf_alphamerge.c
@@ -194,9 +194,9 @@  const AVFilter ff_vf_alphamerge = {
     .priv_size      = sizeof(AlphaMergeContext),
     .priv_class     = &alphamerge_class,
     .init           = init,
-    .query_formats  = query_formats,
     FILTER_INPUTS(alphamerge_inputs),
     FILTER_OUTPUTS(alphamerge_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .uninit         = uninit,
     .activate       = activate,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
diff --git a/libavfilter/vf_amplify.c b/libavfilter/vf_amplify.c
index 713e1560b0..558cbd918e 100644
--- a/libavfilter/vf_amplify.c
+++ b/libavfilter/vf_amplify.c
@@ -314,9 +314,9 @@  const AVFilter ff_vf_amplify = {
     .description   = NULL_IF_CONFIG_SMALL("Amplify changes between successive video frames."),
     .priv_size     = sizeof(AmplifyContext),
     .priv_class    = &amplify_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c
index d21726aa5e..40f983cd9e 100644
--- a/libavfilter/vf_atadenoise.c
+++ b/libavfilter/vf_atadenoise.c
@@ -574,9 +574,9 @@  const AVFilter ff_vf_atadenoise = {
     .priv_class    = &atadenoise_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_avgblur.c b/libavfilter/vf_avgblur.c
index a838285bb4..01f055e5bb 100644
--- a/libavfilter/vf_avgblur.c
+++ b/libavfilter/vf_avgblur.c
@@ -350,9 +350,9 @@  const AVFilter ff_vf_avgblur = {
     .priv_size     = sizeof(AverageBlurContext),
     .priv_class    = &avgblur_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avgblur_inputs),
     FILTER_OUTPUTS(avgblur_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_avgblur_opencl.c b/libavfilter/vf_avgblur_opencl.c
index e9a3bc6100..241c312576 100644
--- a/libavfilter/vf_avgblur_opencl.c
+++ b/libavfilter/vf_avgblur_opencl.c
@@ -345,9 +345,9 @@  const AVFilter ff_vf_avgblur_opencl = {
     .priv_class     = &avgblur_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &avgblur_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(avgblur_opencl_inputs),
     FILTER_OUTPUTS(avgblur_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -384,9 +384,9 @@  const AVFilter ff_vf_boxblur_opencl = {
     .priv_class     = &boxblur_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &avgblur_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(avgblur_opencl_inputs),
     FILTER_OUTPUTS(avgblur_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_avgblur_vulkan.c b/libavfilter/vf_avgblur_vulkan.c
index 5ae487fc8c..a4d855754f 100644
--- a/libavfilter/vf_avgblur_vulkan.c
+++ b/libavfilter/vf_avgblur_vulkan.c
@@ -402,9 +402,9 @@  const AVFilter ff_vf_avgblur_vulkan = {
     .priv_size      = sizeof(AvgBlurVulkanContext),
     .init           = &ff_vk_filter_init,
     .uninit         = &avgblur_vulkan_uninit,
-    .query_formats  = &ff_vk_filter_query_formats,
     FILTER_INPUTS(avgblur_vulkan_inputs),
     FILTER_OUTPUTS(avgblur_vulkan_outputs),
+    FILTER_QUERY_FUNC(&ff_vk_filter_query_formats),
     .priv_class     = &avgblur_vulkan_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c
index 9f03db3cfd..181cbf0bfe 100644
--- a/libavfilter/vf_bbox.c
+++ b/libavfilter/vf_bbox.c
@@ -153,9 +153,9 @@  const AVFilter ff_vf_bbox = {
     .description   = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
     .priv_size     = sizeof(BBoxContext),
     .priv_class    = &bbox_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(bbox_inputs),
     FILTER_OUTPUTS(bbox_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_bilateral.c b/libavfilter/vf_bilateral.c
index 6d7fa8b30d..b292629c62 100644
--- a/libavfilter/vf_bilateral.c
+++ b/libavfilter/vf_bilateral.c
@@ -383,9 +383,9 @@  const AVFilter ff_vf_bilateral = {
     .priv_size     = sizeof(BilateralContext),
     .priv_class    = &bilateral_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(bilateral_inputs),
     FILTER_OUTPUTS(bilateral_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_bitplanenoise.c b/libavfilter/vf_bitplanenoise.c
index d45dd7777f..8b895ff680 100644
--- a/libavfilter/vf_bitplanenoise.c
+++ b/libavfilter/vf_bitplanenoise.c
@@ -213,9 +213,9 @@  const AVFilter ff_vf_bitplanenoise = {
     .name           = "bitplanenoise",
     .description    = NULL_IF_CONFIG_SMALL("Measure bit plane noise."),
     .priv_size      = sizeof(BPNContext),
-    .query_formats  = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class     = &bitplanenoise_class,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c
index b3a03c6e91..e2471f27c2 100644
--- a/libavfilter/vf_blackdetect.c
+++ b/libavfilter/vf_blackdetect.c
@@ -257,9 +257,9 @@  const AVFilter ff_vf_blackdetect = {
     .name          = "blackdetect",
     .description   = NULL_IF_CONFIG_SMALL("Detect video intervals that are (almost) black."),
     .priv_size     = sizeof(BlackDetectContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(blackdetect_inputs),
     FILTER_OUTPUTS(blackdetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .uninit        = uninit,
     .priv_class    = &blackdetect_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index ac7f7347c6..29bed4af68 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -132,7 +132,7 @@  const AVFilter ff_vf_blackframe = {
     .description   = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."),
     .priv_size     = sizeof(BlackFrameContext),
     .priv_class    = &blackframe_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_blackframe_inputs),
     FILTER_OUTPUTS(avfilter_vf_blackframe_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
index ddfd6cf0f0..1401849bc3 100644
--- a/libavfilter/vf_blend.c
+++ b/libavfilter/vf_blend.c
@@ -584,10 +584,10 @@  const AVFilter ff_vf_blend = {
     .init          = init,
     .uninit        = uninit,
     .priv_size     = sizeof(BlendContext),
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(blend_inputs),
     FILTER_OUTPUTS(blend_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &blend_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -641,11 +641,11 @@  const AVFilter ff_vf_tblend = {
     .description   = NULL_IF_CONFIG_SMALL("Blend successive frames."),
     .priv_size     = sizeof(BlendContext),
     .priv_class    = &tblend_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(tblend_inputs),
     FILTER_OUTPUTS(tblend_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_bm3d.c b/libavfilter/vf_bm3d.c
index 007f8bbf8c..46f4c65676 100644
--- a/libavfilter/vf_bm3d.c
+++ b/libavfilter/vf_bm3d.c
@@ -1053,9 +1053,9 @@  const AVFilter ff_vf_bm3d = {
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(bm3d_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &bm3d_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_DYNAMIC_INPUTS |
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index 3ace88e5b6..e13c2472b3 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -308,8 +308,8 @@  const AVFilter ff_vf_boxblur = {
     .priv_size     = sizeof(BoxBlurContext),
     .priv_class    = &boxblur_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_boxblur_inputs),
     FILTER_OUTPUTS(avfilter_vf_boxblur_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c
index 7f3fb0034b..cb880c7241 100644
--- a/libavfilter/vf_bwdif.c
+++ b/libavfilter/vf_bwdif.c
@@ -409,8 +409,8 @@  const AVFilter ff_vf_bwdif = {
     .priv_size     = sizeof(BWDIFContext),
     .priv_class    = &bwdif_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_bwdif_inputs),
     FILTER_OUTPUTS(avfilter_vf_bwdif_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_cas.c b/libavfilter/vf_cas.c
index d28932a62b..32ac6aa04b 100644
--- a/libavfilter/vf_cas.c
+++ b/libavfilter/vf_cas.c
@@ -283,9 +283,9 @@  const AVFilter ff_vf_cas = {
     .description   = NULL_IF_CONFIG_SMALL("Contrast Adaptive Sharpen."),
     .priv_size     = sizeof(CASContext),
     .priv_class    = &cas_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(cas_inputs),
     FILTER_OUTPUTS(cas_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_chromaber_vulkan.c b/libavfilter/vf_chromaber_vulkan.c
index 96fdd7bd9c..87e55a9c4f 100644
--- a/libavfilter/vf_chromaber_vulkan.c
+++ b/libavfilter/vf_chromaber_vulkan.c
@@ -337,9 +337,9 @@  const AVFilter ff_vf_chromaber_vulkan = {
     .priv_size      = sizeof(ChromaticAberrationVulkanContext),
     .init           = &ff_vk_filter_init,
     .uninit         = &chromaber_vulkan_uninit,
-    .query_formats  = &ff_vk_filter_query_formats,
     FILTER_INPUTS(chromaber_vulkan_inputs),
     FILTER_OUTPUTS(chromaber_vulkan_outputs),
+    FILTER_QUERY_FUNC(&ff_vk_filter_query_formats),
     .priv_class     = &chromaber_vulkan_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_chromakey.c b/libavfilter/vf_chromakey.c
index 304cb9ee6c..532d81ecf6 100644
--- a/libavfilter/vf_chromakey.c
+++ b/libavfilter/vf_chromakey.c
@@ -399,9 +399,9 @@  const AVFilter ff_vf_chromakey = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain color into transparency. Operates on YUV colors."),
     .priv_size     = sizeof(ChromakeyContext),
     .priv_class    = &chromakey_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(chromakey_inputs),
     FILTER_OUTPUTS(chromakey_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -439,9 +439,9 @@  const AVFilter ff_vf_chromahold = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain color range into gray."),
     .priv_size     = sizeof(ChromakeyContext),
     .priv_class    = &chromahold_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(chromahold_inputs),
     FILTER_OUTPUTS(chromahold_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_chromanr.c b/libavfilter/vf_chromanr.c
index fe9bca1d9d..0f16f68b3f 100644
--- a/libavfilter/vf_chromanr.c
+++ b/libavfilter/vf_chromanr.c
@@ -280,9 +280,9 @@  const AVFilter ff_vf_chromanr = {
     .description   = NULL_IF_CONFIG_SMALL("Reduce chrominance noise."),
     .priv_size     = sizeof(ChromaNRContext),
     .priv_class    = &chromanr_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_chromashift.c b/libavfilter/vf_chromashift.c
index bcff4144e3..18e362adb8 100644
--- a/libavfilter/vf_chromashift.c
+++ b/libavfilter/vf_chromashift.c
@@ -445,9 +445,9 @@  const AVFilter ff_vf_chromashift = {
     .description   = NULL_IF_CONFIG_SMALL("Shift chroma."),
     .priv_size     = sizeof(ChromaShiftContext),
     .priv_class    = &chromashift_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -474,9 +474,9 @@  const AVFilter ff_vf_rgbashift = {
     .description   = NULL_IF_CONFIG_SMALL("Shift RGBA."),
     .priv_size     = sizeof(ChromaShiftContext),
     .priv_class    = &rgbashift_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_ciescope.c b/libavfilter/vf_ciescope.c
index b09012920c..fcb28d2b5e 100644
--- a/libavfilter/vf_ciescope.c
+++ b/libavfilter/vf_ciescope.c
@@ -1507,8 +1507,8 @@  const AVFilter ff_vf_ciescope = {
     .description   = NULL_IF_CONFIG_SMALL("Video CIE scope."),
     .priv_size     = sizeof(CiescopeContext),
     .priv_class    = &ciescope_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c
index dc3d3acd82..4226bab8d8 100644
--- a/libavfilter/vf_codecview.c
+++ b/libavfilter/vf_codecview.c
@@ -317,9 +317,9 @@  const AVFilter ff_vf_codecview = {
     .name          = "codecview",
     .description   = NULL_IF_CONFIG_SMALL("Visualize information about some codecs."),
     .priv_size     = sizeof(CodecViewContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(codecview_inputs),
     FILTER_OUTPUTS(codecview_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &codecview_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c
index 8055829adf..9ca0078ecc 100644
--- a/libavfilter/vf_colorbalance.c
+++ b/libavfilter/vf_colorbalance.c
@@ -440,9 +440,9 @@  const AVFilter ff_vf_colorbalance = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust the color balance."),
     .priv_size     = sizeof(ColorBalanceContext),
     .priv_class    = &colorbalance_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(colorbalance_inputs),
     FILTER_OUTPUTS(colorbalance_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c
index f1a193116e..4453d901bd 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -780,9 +780,9 @@  const AVFilter ff_vf_colorchannelmixer = {
     .priv_size     = sizeof(ColorChannelMixerContext),
     .priv_class    = &colorchannelmixer_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(colorchannelmixer_inputs),
     FILTER_OUTPUTS(colorchannelmixer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_colorconstancy.c b/libavfilter/vf_colorconstancy.c
index 8c54f7c238..9ccb462d0f 100644
--- a/libavfilter/vf_colorconstancy.c
+++ b/libavfilter/vf_colorconstancy.c
@@ -752,10 +752,10 @@  const AVFilter ff_vf_greyedge = {
     .description   = NULL_IF_CONFIG_SMALL("Estimates scene illumination by grey edge assumption."),
     .priv_size     = sizeof(ColorConstancyContext),
     .priv_class    = &greyedge_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(colorconstancy_inputs),
     FILTER_OUTPUTS(colorconstancy_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
 
diff --git a/libavfilter/vf_colorcontrast.c b/libavfilter/vf_colorcontrast.c
index e89b3e7af4..b0f856a85e 100644
--- a/libavfilter/vf_colorcontrast.c
+++ b/libavfilter/vf_colorcontrast.c
@@ -392,9 +392,9 @@  const AVFilter ff_vf_colorcontrast = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust color contrast between RGB components."),
     .priv_size     = sizeof(ColorContrastContext),
     .priv_class    = &colorcontrast_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(colorcontrast_inputs),
     FILTER_OUTPUTS(colorcontrast_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_colorcorrect.c b/libavfilter/vf_colorcorrect.c
index 2570bb105c..dd4783306d 100644
--- a/libavfilter/vf_colorcorrect.c
+++ b/libavfilter/vf_colorcorrect.c
@@ -546,10 +546,10 @@  const AVFilter ff_vf_colorcorrect = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust color white balance selectively for blacks and whites."),
     .priv_size     = sizeof(ColorCorrectContext),
     .priv_class    = &colorcorrect_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(colorcorrect_inputs),
     FILTER_OUTPUTS(colorcorrect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_colorize.c b/libavfilter/vf_colorize.c
index 4b57998a22..3ad832b6d9 100644
--- a/libavfilter/vf_colorize.c
+++ b/libavfilter/vf_colorize.c
@@ -290,9 +290,9 @@  const AVFilter ff_vf_colorize = {
     .description   = NULL_IF_CONFIG_SMALL("Overlay a solid color on the video stream."),
     .priv_size     = sizeof(ColorizeContext),
     .priv_class    = &colorize_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(colorize_inputs),
     FILTER_OUTPUTS(colorize_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_colorkey.c b/libavfilter/vf_colorkey.c
index bef3e37414..93f2ae3ec9 100644
--- a/libavfilter/vf_colorkey.c
+++ b/libavfilter/vf_colorkey.c
@@ -208,10 +208,10 @@  const AVFilter ff_vf_colorkey = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain color into transparency. Operates on RGB colors."),
     .priv_size     = sizeof(ColorkeyContext),
     .priv_class    = &colorkey_class,
-    .query_formats = query_formats,
     .init          = init_filter,
     FILTER_INPUTS(colorkey_inputs),
     FILTER_OUTPUTS(colorkey_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
@@ -233,10 +233,10 @@  const AVFilter ff_vf_colorhold = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain color range into gray. Operates on RGB colors."),
     .priv_size     = sizeof(ColorkeyContext),
     .priv_class    = &colorhold_class,
-    .query_formats = query_formats,
     .init          = init_filter,
     FILTER_INPUTS(colorkey_inputs),
     FILTER_OUTPUTS(colorkey_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_colorkey_opencl.c b/libavfilter/vf_colorkey_opencl.c
index f4015cbf21..d54dd86c21 100644
--- a/libavfilter/vf_colorkey_opencl.c
+++ b/libavfilter/vf_colorkey_opencl.c
@@ -235,8 +235,8 @@  const AVFilter ff_vf_colorkey_opencl = {
     .priv_class     = &colorkey_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &colorkey_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(colorkey_opencl_inputs),
     FILTER_OUTPUTS(colorkey_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE
 };
diff --git a/libavfilter/vf_colorlevels.c b/libavfilter/vf_colorlevels.c
index 89021e95d0..552b701a2d 100644
--- a/libavfilter/vf_colorlevels.c
+++ b/libavfilter/vf_colorlevels.c
@@ -386,9 +386,9 @@  const AVFilter ff_vf_colorlevels = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust the color levels."),
     .priv_size     = sizeof(ColorLevelsContext),
     .priv_class    = &colorlevels_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(colorlevels_inputs),
     FILTER_OUTPUTS(colorlevels_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c
index 87bf478398..73bc0e9cf0 100644
--- a/libavfilter/vf_colormatrix.c
+++ b/libavfilter/vf_colormatrix.c
@@ -507,9 +507,9 @@  const AVFilter ff_vf_colormatrix = {
     .description   = NULL_IF_CONFIG_SMALL("Convert color matrix."),
     .priv_size     = sizeof(ColorMatrixContext),
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(colormatrix_inputs),
     FILTER_OUTPUTS(colormatrix_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &colormatrix_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c
index 6b23b27ea5..0bd8e2b0cf 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -1072,10 +1072,10 @@  const AVFilter ff_vf_colorspace = {
     .description     = NULL_IF_CONFIG_SMALL("Convert between colorspaces."),
     .init            = init,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ColorSpaceContext),
     .priv_class      = &colorspace_class,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_colortemperature.c b/libavfilter/vf_colortemperature.c
index da2e3bf908..919ad81c69 100644
--- a/libavfilter/vf_colortemperature.c
+++ b/libavfilter/vf_colortemperature.c
@@ -354,9 +354,9 @@  const AVFilter ff_vf_colortemperature = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust color temperature of video."),
     .priv_size     = sizeof(ColorTemperatureContext),
     .priv_class    = &colortemperature_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c
index c1ebf4c791..707f2dd4e3 100644
--- a/libavfilter/vf_convolution.c
+++ b/libavfilter/vf_convolution.c
@@ -965,9 +965,9 @@  const AVFilter ff_vf_convolution = {
     .priv_size     = sizeof(ConvolutionContext),
     .priv_class    = &convolution_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(convolution_inputs),
     FILTER_OUTPUTS(convolution_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -992,9 +992,9 @@  const AVFilter ff_vf_prewitt = {
     .priv_size     = sizeof(ConvolutionContext),
     .priv_class    = &common_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(convolution_inputs),
     FILTER_OUTPUTS(convolution_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -1009,9 +1009,9 @@  const AVFilter ff_vf_sobel = {
     .priv_size     = sizeof(ConvolutionContext),
     .priv_class    = &common_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(convolution_inputs),
     FILTER_OUTPUTS(convolution_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -1026,9 +1026,9 @@  const AVFilter ff_vf_roberts = {
     .priv_size     = sizeof(ConvolutionContext),
     .priv_class    = &common_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(convolution_inputs),
     FILTER_OUTPUTS(convolution_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -1043,9 +1043,9 @@  const AVFilter ff_vf_kirsch = {
     .priv_size     = sizeof(ConvolutionContext),
     .priv_class    = &common_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(convolution_inputs),
     FILTER_OUTPUTS(convolution_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -1060,9 +1060,9 @@  const AVFilter ff_vf_scharr = {
     .priv_size     = sizeof(ConvolutionContext),
     .priv_class    = &common_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(convolution_inputs),
     FILTER_OUTPUTS(convolution_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_convolution_opencl.c b/libavfilter/vf_convolution_opencl.c
index 6932eff246..3871ddcff4 100644
--- a/libavfilter/vf_convolution_opencl.c
+++ b/libavfilter/vf_convolution_opencl.c
@@ -367,9 +367,9 @@  const AVFilter ff_vf_convolution_opencl = {
     .priv_class     = &convolution_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &convolution_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(convolution_opencl_inputs),
     FILTER_OUTPUTS(convolution_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -393,9 +393,9 @@  const AVFilter ff_vf_sobel_opencl = {
     .priv_class     = &sobel_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &convolution_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(convolution_opencl_inputs),
     FILTER_OUTPUTS(convolution_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -419,9 +419,9 @@  const AVFilter ff_vf_prewitt_opencl = {
     .priv_class     = &prewitt_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &convolution_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(convolution_opencl_inputs),
     FILTER_OUTPUTS(convolution_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -445,9 +445,9 @@  const AVFilter ff_vf_roberts_opencl = {
     .priv_class     = &roberts_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &convolution_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(convolution_opencl_inputs),
     FILTER_OUTPUTS(convolution_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_convolve.c b/libavfilter/vf_convolve.c
index 65e7bde107..d7fdb9b121 100644
--- a/libavfilter/vf_convolve.c
+++ b/libavfilter/vf_convolve.c
@@ -663,12 +663,12 @@  const AVFilter ff_vf_convolve = {
     .preinit       = convolve_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(ConvolveContext),
     .priv_class    = &convolve_class,
     FILTER_INPUTS(convolve_inputs),
     FILTER_OUTPUTS(convolve_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
@@ -693,12 +693,12 @@  const AVFilter ff_vf_deconvolve = {
     .preinit       = convolve_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(ConvolveContext),
     .priv_class    = &deconvolve_class,
     FILTER_INPUTS(convolve_inputs),
     FILTER_OUTPUTS(convolve_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index 0ed61324e7..5554565bae 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -77,5 +77,5 @@  const AVFilter ff_vf_copy = {
     .description = NULL_IF_CONFIG_SMALL("Copy the input video unchanged to the output."),
     FILTER_INPUTS(avfilter_vf_copy_inputs),
     FILTER_OUTPUTS(avfilter_vf_copy_outputs),
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_coreimage.m b/libavfilter/vf_coreimage.m
index 5c7d272616..4e1f89ee71 100644
--- a/libavfilter/vf_coreimage.m
+++ b/libavfilter/vf_coreimage.m
@@ -629,7 +629,7 @@  const AVFilter ff_vf_coreimage = {
     .priv_class    = &coreimage_class,
     FILTER_INPUTS(vf_coreimage_inputs),
     FILTER_OUTPUTS(vf_coreimage_outputs),
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
 };
 
 // definitions for coreimagesrc video source
@@ -650,5 +650,5 @@  const AVFilter ff_vsrc_coreimagesrc = {
     .priv_class    = &coreimagesrc_class,
     .inputs        = NULL,
     FILTER_OUTPUTS(vsrc_coreimagesrc_outputs),
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_cover_rect.c b/libavfilter/vf_cover_rect.c
index 0a8c10e06d..90e19ea8a6 100644
--- a/libavfilter/vf_cover_rect.c
+++ b/libavfilter/vf_cover_rect.c
@@ -251,8 +251,8 @@  const AVFilter ff_vf_cover_rect = {
     .priv_size       = sizeof(CoverContext),
     .init            = init,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(cover_rect_inputs),
     FILTER_OUTPUTS(cover_rect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &cover_rect_class,
 };
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 27ae1b8118..c7cbfa51ef 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -391,9 +391,9 @@  const AVFilter ff_vf_crop = {
     .description     = NULL_IF_CONFIG_SMALL("Crop the input video."),
     .priv_size       = sizeof(CropContext),
     .priv_class      = &crop_class,
-    .query_formats   = query_formats,
     .uninit          = uninit,
     FILTER_INPUTS(avfilter_vf_crop_inputs),
     FILTER_OUTPUTS(avfilter_vf_crop_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index 500ef7fa7f..22e8885e01 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -275,8 +275,8 @@  const AVFilter ff_vf_cropdetect = {
     .priv_size     = sizeof(CropDetectContext),
     .priv_class    = &cropdetect_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_cropdetect_inputs),
     FILTER_OUTPUTS(avfilter_vf_cropdetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 7d7773419e..4aeb9e36ae 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -815,9 +815,9 @@  const AVFilter ff_vf_curves = {
     .priv_size     = sizeof(CurvesContext),
     .init          = curves_init,
     .uninit        = curves_uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(curves_inputs),
     FILTER_OUTPUTS(curves_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &curves_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_datascope.c b/libavfilter/vf_datascope.c
index a60d061d18..0a605985f1 100644
--- a/libavfilter/vf_datascope.c
+++ b/libavfilter/vf_datascope.c
@@ -453,9 +453,9 @@  const AVFilter ff_vf_datascope = {
     .description   = NULL_IF_CONFIG_SMALL("Video data analysis."),
     .priv_size     = sizeof(DatascopeContext),
     .priv_class    = &datascope_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -740,9 +740,9 @@  const AVFilter ff_vf_pixscope = {
     .description   = NULL_IF_CONFIG_SMALL("Pixel data analysis."),
     .priv_size     = sizeof(PixscopeContext),
     .priv_class    = &pixscope_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(pixscope_inputs),
     FILTER_OUTPUTS(pixscope_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = pixscope_process_command,
 };
@@ -1144,10 +1144,10 @@  const AVFilter ff_vf_oscilloscope = {
     .description   = NULL_IF_CONFIG_SMALL("2D Video Oscilloscope."),
     .priv_size     = sizeof(OscilloscopeContext),
     .priv_class    = &oscilloscope_class,
-    .query_formats = query_formats,
     .uninit        = oscilloscope_uninit,
     FILTER_INPUTS(oscilloscope_inputs),
     FILTER_OUTPUTS(oscilloscope_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = oscilloscope_process_command,
 };
diff --git a/libavfilter/vf_dblur.c b/libavfilter/vf_dblur.c
index 931c6c689d..91c0023a13 100644
--- a/libavfilter/vf_dblur.c
+++ b/libavfilter/vf_dblur.c
@@ -296,9 +296,9 @@  const AVFilter ff_vf_dblur = {
     .priv_size     = sizeof(DBlurContext),
     .priv_class    = &dblur_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(dblur_inputs),
     FILTER_OUTPUTS(dblur_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c
index 3192a2f8ae..a967eb72d3 100644
--- a/libavfilter/vf_dctdnoiz.c
+++ b/libavfilter/vf_dctdnoiz.c
@@ -826,9 +826,9 @@  const AVFilter ff_vf_dctdnoiz = {
     .priv_size     = sizeof(DCTdnoizContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(dctdnoiz_inputs),
     FILTER_OUTPUTS(dctdnoiz_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &dctdnoiz_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_deband.c b/libavfilter/vf_deband.c
index 6d9fd2c52b..ec91cb1548 100644
--- a/libavfilter/vf_deband.c
+++ b/libavfilter/vf_deband.c
@@ -471,9 +471,9 @@  const AVFilter ff_vf_deband = {
     .priv_size     = sizeof(DebandContext),
     .priv_class    = &deband_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_deband_inputs),
     FILTER_OUTPUTS(avfilter_vf_deband_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_deblock.c b/libavfilter/vf_deblock.c
index 60f2d206bb..809e004ae9 100644
--- a/libavfilter/vf_deblock.c
+++ b/libavfilter/vf_deblock.c
@@ -415,9 +415,9 @@  const AVFilter ff_vf_deblock = {
     .description   = NULL_IF_CONFIG_SMALL("Deblock video."),
     .priv_size     = sizeof(DeblockContext),
     .priv_class    = &deblock_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
index cc75aecf81..a547f272de 100644
--- a/libavfilter/vf_decimate.c
+++ b/libavfilter/vf_decimate.c
@@ -437,8 +437,8 @@  const AVFilter ff_vf_decimate = {
     .activate      = activate,
     .uninit        = decimate_uninit,
     .priv_size     = sizeof(DecimateContext),
-    .query_formats = query_formats,
     FILTER_OUTPUTS(decimate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &decimate_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_dedot.c b/libavfilter/vf_dedot.c
index a61c08ab02..9d31af3f6d 100644
--- a/libavfilter/vf_dedot.c
+++ b/libavfilter/vf_dedot.c
@@ -401,10 +401,10 @@  const AVFilter ff_vf_dedot = {
     .description   = NULL_IF_CONFIG_SMALL("Reduce cross-luminance and cross-color."),
     .priv_size     = sizeof(DedotContext),
     .priv_class    = &dedot_class,
-    .query_formats = query_formats,
     .activate      = activate,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_deflicker.c b/libavfilter/vf_deflicker.c
index c15f8cec33..11652c40ec 100644
--- a/libavfilter/vf_deflicker.c
+++ b/libavfilter/vf_deflicker.c
@@ -467,7 +467,7 @@  const AVFilter ff_vf_deflicker = {
     .priv_size     = sizeof(DeflickerContext),
     .priv_class    = &deflicker_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c
index 173c314bb8..c30e1e7fc2 100644
--- a/libavfilter/vf_deinterlace_qsv.c
+++ b/libavfilter/vf_deinterlace_qsv.c
@@ -598,13 +598,13 @@  const AVFilter ff_vf_deinterlace_qsv = {
     .description = NULL_IF_CONFIG_SMALL("QuickSync video deinterlacing"),
 
     .uninit        = qsvdeint_uninit,
-    .query_formats = qsvdeint_query_formats,
 
     .priv_size = sizeof(QSVDeintContext),
     .priv_class = &qsvdeint_class,
 
     FILTER_INPUTS(qsvdeint_inputs),
     FILTER_OUTPUTS(qsvdeint_outputs),
+    FILTER_QUERY_FUNC(qsvdeint_query_formats),
 
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c
index 5ec830213e..65f319ba9a 100644
--- a/libavfilter/vf_deinterlace_vaapi.c
+++ b/libavfilter/vf_deinterlace_vaapi.c
@@ -385,9 +385,9 @@  const AVFilter ff_vf_deinterlace_vaapi = {
     .priv_size      = sizeof(DeintVAAPIContext),
     .init           = &deint_vaapi_init,
     .uninit         = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats  = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(deint_vaapi_inputs),
     FILTER_OUTPUTS(deint_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class     = &deint_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index f7320aa0fe..ce24aa92a7 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -400,8 +400,8 @@  const AVFilter ff_vf_delogo = {
     .priv_class    = &delogo_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_delogo_inputs),
     FILTER_OUTPUTS(avfilter_vf_delogo_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_derain.c b/libavfilter/vf_derain.c
index 97bdb4e843..2950527f69 100644
--- a/libavfilter/vf_derain.c
+++ b/libavfilter/vf_derain.c
@@ -134,9 +134,9 @@  const AVFilter ff_vf_derain = {
     .priv_size     = sizeof(DRContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(derain_inputs),
     FILTER_OUTPUTS(derain_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &derain_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index 4d3d950191..a2b410c3c8 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -552,8 +552,8 @@  const AVFilter ff_vf_deshake = {
     .priv_size     = sizeof(DeshakeContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(deshake_inputs),
     FILTER_OUTPUTS(deshake_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &deshake_class,
 };
diff --git a/libavfilter/vf_deshake_opencl.c b/libavfilter/vf_deshake_opencl.c
index 93c50a410d..848f4a4f30 100644
--- a/libavfilter/vf_deshake_opencl.c
+++ b/libavfilter/vf_deshake_opencl.c
@@ -2192,9 +2192,9 @@  const AVFilter ff_vf_deshake_opencl = {
     .priv_class     = &deshake_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &deshake_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     .activate       = activate,
     FILTER_INPUTS(deshake_opencl_inputs),
     FILTER_OUTPUTS(deshake_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE
 };
diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c
index 2c60112b48..ecaaddac11 100644
--- a/libavfilter/vf_despill.c
+++ b/libavfilter/vf_despill.c
@@ -168,9 +168,9 @@  const AVFilter ff_vf_despill = {
     .description   = NULL_IF_CONFIG_SMALL("Despill video."),
     .priv_size     = sizeof(DespillContext),
     .priv_class    = &despill_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(despill_inputs),
     FILTER_OUTPUTS(despill_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = ff_filter_process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_detelecine.c b/libavfilter/vf_detelecine.c
index e36e1a6245..e1f0587b6a 100644
--- a/libavfilter/vf_detelecine.c
+++ b/libavfilter/vf_detelecine.c
@@ -372,7 +372,7 @@  const AVFilter ff_vf_detelecine = {
     .priv_class    = &detelecine_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(detelecine_inputs),
     FILTER_OUTPUTS(detelecine_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c
index 3dbba3b95c..8afef87d7a 100644
--- a/libavfilter/vf_displace.c
+++ b/libavfilter/vf_displace.c
@@ -398,10 +398,10 @@  const AVFilter ff_vf_displace = {
     .description   = NULL_IF_CONFIG_SMALL("Displace pixels."),
     .priv_size     = sizeof(DisplaceContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(displace_inputs),
     FILTER_OUTPUTS(displace_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &displace_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_dnn_classify.c b/libavfilter/vf_dnn_classify.c
index d1ba8dffbc..ea929c2c19 100644
--- a/libavfilter/vf_dnn_classify.c
+++ b/libavfilter/vf_dnn_classify.c
@@ -321,9 +321,9 @@  const AVFilter ff_vf_dnn_classify = {
     .priv_size     = sizeof(DnnClassifyContext),
     .init          = dnn_classify_init,
     .uninit        = dnn_classify_uninit,
-    .query_formats = dnn_classify_query_formats,
     FILTER_INPUTS(dnn_classify_inputs),
     FILTER_OUTPUTS(dnn_classify_outputs),
+    FILTER_QUERY_FUNC(dnn_classify_query_formats),
     .priv_class    = &dnn_classify_class,
     .activate      = dnn_classify_activate,
 };
diff --git a/libavfilter/vf_dnn_detect.c b/libavfilter/vf_dnn_detect.c
index 637874b2a1..2cfff00a4a 100644
--- a/libavfilter/vf_dnn_detect.c
+++ b/libavfilter/vf_dnn_detect.c
@@ -464,9 +464,9 @@  const AVFilter ff_vf_dnn_detect = {
     .priv_size     = sizeof(DnnDetectContext),
     .init          = dnn_detect_init,
     .uninit        = dnn_detect_uninit,
-    .query_formats = dnn_detect_query_formats,
     FILTER_INPUTS(dnn_detect_inputs),
     FILTER_OUTPUTS(dnn_detect_outputs),
+    FILTER_QUERY_FUNC(dnn_detect_query_formats),
     .priv_class    = &dnn_detect_class,
     .activate      = dnn_detect_activate,
 };
diff --git a/libavfilter/vf_dnn_processing.c b/libavfilter/vf_dnn_processing.c
index 55634efde5..d193205550 100644
--- a/libavfilter/vf_dnn_processing.c
+++ b/libavfilter/vf_dnn_processing.c
@@ -370,9 +370,9 @@  const AVFilter ff_vf_dnn_processing = {
     .priv_size     = sizeof(DnnProcessingContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(dnn_processing_inputs),
     FILTER_OUTPUTS(dnn_processing_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &dnn_processing_class,
     .activate      = activate,
 };
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index 2d36da89cd..c5ced11bbe 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -403,9 +403,9 @@  const AVFilter ff_vf_drawbox = {
     .priv_size     = sizeof(DrawBoxContext),
     .priv_class    = &drawbox_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(drawbox_inputs),
     FILTER_OUTPUTS(drawbox_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -485,9 +485,9 @@  const AVFilter ff_vf_drawgrid = {
     .priv_size     = sizeof(DrawBoxContext),
     .priv_class    = &drawgrid_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(drawgrid_inputs),
     FILTER_OUTPUTS(drawgrid_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index b1ea58f30a..2a88692cbd 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -1635,9 +1635,9 @@  const AVFilter ff_vf_drawtext = {
     .priv_class    = &drawtext_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_drawtext_inputs),
     FILTER_OUTPUTS(avfilter_vf_drawtext_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c
index 982ed729cf..3eea34e325 100644
--- a/libavfilter/vf_edgedetect.c
+++ b/libavfilter/vf_edgedetect.c
@@ -431,9 +431,9 @@  const AVFilter ff_vf_edgedetect = {
     .priv_size     = sizeof(EdgeDetectContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(edgedetect_inputs),
     FILTER_OUTPUTS(edgedetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &edgedetect_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_elbg.c b/libavfilter/vf_elbg.c
index 7f40be6092..fc73346ae1 100644
--- a/libavfilter/vf_elbg.c
+++ b/libavfilter/vf_elbg.c
@@ -265,9 +265,9 @@  const AVFilter ff_vf_elbg = {
     .description   = NULL_IF_CONFIG_SMALL("Apply posterize effect, using the ELBG algorithm."),
     .priv_size     = sizeof(ELBGFilterContext),
     .priv_class    = &elbg_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(elbg_inputs),
     FILTER_OUTPUTS(elbg_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_entropy.c b/libavfilter/vf_entropy.c
index bac962fbd9..2d29ad16d3 100644
--- a/libavfilter/vf_entropy.c
+++ b/libavfilter/vf_entropy.c
@@ -193,9 +193,9 @@  const AVFilter ff_vf_entropy = {
     .description    = NULL_IF_CONFIG_SMALL("Measure video frames entropy."),
     .priv_size      = sizeof(EntropyContext),
     .uninit         = uninit,
-    .query_formats  = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class     = &entropy_class,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_epx.c b/libavfilter/vf_epx.c
index 4adf6d5a32..be0749463f 100644
--- a/libavfilter/vf_epx.c
+++ b/libavfilter/vf_epx.c
@@ -275,7 +275,7 @@  const AVFilter ff_vf_epx = {
     .description   = NULL_IF_CONFIG_SMALL("Scale the input using EPX algorithm."),
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     .priv_size     = sizeof(EPXContext),
     .priv_class    = &epx_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_eq.c b/libavfilter/vf_eq.c
index 7763601935..74fc4d4968 100644
--- a/libavfilter/vf_eq.c
+++ b/libavfilter/vf_eq.c
@@ -379,8 +379,8 @@  const AVFilter ff_vf_eq = {
     .priv_class      = &eq_class,
     FILTER_INPUTS(eq_inputs),
     FILTER_OUTPUTS(eq_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
-    .query_formats   = query_formats,
     .init            = initialize,
     .uninit          = uninit,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
diff --git a/libavfilter/vf_estdif.c b/libavfilter/vf_estdif.c
index 70e804a3c6..dea393e7b9 100644
--- a/libavfilter/vf_estdif.c
+++ b/libavfilter/vf_estdif.c
@@ -576,9 +576,9 @@  const AVFilter ff_vf_estdif = {
     .priv_size     = sizeof(ESTDIFContext),
     .priv_class    = &estdif_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(estdif_inputs),
     FILTER_OUTPUTS(estdif_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_exposure.c b/libavfilter/vf_exposure.c
index 2b6e6f1586..6443eb77f1 100644
--- a/libavfilter/vf_exposure.c
+++ b/libavfilter/vf_exposure.c
@@ -128,9 +128,9 @@  const AVFilter ff_vf_exposure = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust exposure of the video stream."),
     .priv_size     = sizeof(ExposureContext),
     .priv_class    = &exposure_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(exposure_inputs),
     FILTER_OUTPUTS(exposure_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c
index 6e7931b3e3..80fbc6e4b8 100644
--- a/libavfilter/vf_extractplanes.c
+++ b/libavfilter/vf_extractplanes.c
@@ -374,9 +374,9 @@  const AVFilter ff_vf_extractplanes = {
     .priv_size     = sizeof(ExtractPlanesContext),
     .priv_class    = &extractplanes_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(extractplanes_inputs),
     .outputs       = NULL,
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
 
@@ -406,8 +406,8 @@  const AVFilter ff_vf_alphaextract = {
                       "grayscale image component."),
     .priv_size      = sizeof(ExtractPlanesContext),
     .init           = init_alphaextract,
-    .query_formats  = query_formats,
     FILTER_INPUTS(extractplanes_inputs),
     FILTER_OUTPUTS(alphaextract_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
 #endif  /* CONFIG_ALPHAEXTRACT_FILTER */
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 71d40c4928..868e7cc16a 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -570,9 +570,9 @@  const AVFilter ff_vf_fade = {
     .init          = init,
     .priv_size     = sizeof(FadeContext),
     .priv_class    = &fade_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_fade_inputs),
     FILTER_OUTPUTS(avfilter_vf_fade_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS |
                      AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_fftdnoiz.c b/libavfilter/vf_fftdnoiz.c
index 110674d5a1..e5b1156b9b 100644
--- a/libavfilter/vf_fftdnoiz.c
+++ b/libavfilter/vf_fftdnoiz.c
@@ -685,9 +685,9 @@  const AVFilter ff_vf_fftdnoiz = {
     .priv_size     = sizeof(FFTdnoizContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(fftdnoiz_inputs),
     FILTER_OUTPUTS(fftdnoiz_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &fftdnoiz_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c
index b1b657596d..3f044ec157 100644
--- a/libavfilter/vf_fftfilt.c
+++ b/libavfilter/vf_fftfilt.c
@@ -430,7 +430,7 @@  const AVFilter ff_vf_fftfilt = {
     .priv_class      = &fftfilt_class,
     FILTER_INPUTS(fftfilt_inputs),
     FILTER_OUTPUTS(fftfilt_outputs),
-    .query_formats   = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     .init            = initialize,
     .uninit          = uninit,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
diff --git a/libavfilter/vf_fieldhint.c b/libavfilter/vf_fieldhint.c
index c41f2ef751..e4513dddfa 100644
--- a/libavfilter/vf_fieldhint.c
+++ b/libavfilter/vf_fieldhint.c
@@ -296,7 +296,7 @@  const AVFilter ff_vf_fieldhint = {
     .priv_class    = &fieldhint_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index 45285eade7..ab027b80eb 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -1042,13 +1042,13 @@  static const AVFilterPad fieldmatch_outputs[] = {
 const AVFilter ff_vf_fieldmatch = {
     .name           = "fieldmatch",
     .description    = NULL_IF_CONFIG_SMALL("Field matching for inverse telecine."),
-    .query_formats  = query_formats,
     .priv_size      = sizeof(FieldMatchContext),
     .init           = fieldmatch_init,
     .activate       = activate,
     .uninit         = fieldmatch_uninit,
     .inputs         = NULL,
     FILTER_OUTPUTS(fieldmatch_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class     = &fieldmatch_class,
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index 40bfd6549f..85b6688fb3 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -181,8 +181,8 @@  const AVFilter ff_vf_fieldorder = {
     .description   = NULL_IF_CONFIG_SMALL("Set the field order."),
     .priv_size     = sizeof(FieldOrderContext),
     .priv_class    = &fieldorder_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_fieldorder_inputs),
     FILTER_OUTPUTS(avfilter_vf_fieldorder_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_fillborders.c b/libavfilter/vf_fillborders.c
index 4a799422b4..88955736d5 100644
--- a/libavfilter/vf_fillborders.c
+++ b/libavfilter/vf_fillborders.c
@@ -723,9 +723,9 @@  const AVFilter ff_vf_fillborders = {
     .description   = NULL_IF_CONFIG_SMALL("Fill borders of the input video."),
     .priv_size     = sizeof(FillBordersContext),
     .priv_class    = &fillborders_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(fillborders_inputs),
     FILTER_OUTPUTS(fillborders_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_find_rect.c b/libavfilter/vf_find_rect.c
index 6c126af721..32d9a8a67a 100644
--- a/libavfilter/vf_find_rect.c
+++ b/libavfilter/vf_find_rect.c
@@ -305,8 +305,8 @@  const AVFilter ff_vf_find_rect = {
     .priv_size       = sizeof(FOCContext),
     .init            = init,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(foc_inputs),
     FILTER_OUTPUTS(foc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &find_rect_class,
 };
diff --git a/libavfilter/vf_floodfill.c b/libavfilter/vf_floodfill.c
index 5f2a4f4392..2e98fb5b71 100644
--- a/libavfilter/vf_floodfill.c
+++ b/libavfilter/vf_floodfill.c
@@ -418,9 +418,9 @@  const AVFilter ff_vf_floodfill = {
     .description   = NULL_IF_CONFIG_SMALL("Fill area with same color with another color."),
     .priv_size     = sizeof(FloodfillContext),
     .priv_class    = &floodfill_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(floodfill_inputs),
     FILTER_OUTPUTS(floodfill_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 0a5c739db6..7e15c43086 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -166,13 +166,13 @@  const AVFilter ff_vf_format = {
     .init          = init,
     .uninit        = uninit,
 
-    .query_formats = query_formats,
-
     .priv_size     = sizeof(FormatContext),
     .priv_class    = &format_class,
 
     FILTER_INPUTS(avfilter_vf_format_inputs),
     FILTER_OUTPUTS(avfilter_vf_format_outputs),
+
+    FILTER_QUERY_FUNC(query_formats),
 };
 #endif /* CONFIG_FORMAT_FILTER */
 
@@ -201,11 +201,11 @@  const AVFilter ff_vf_noformat = {
     .init          = init,
     .uninit        = uninit,
 
-    .query_formats = query_formats,
-
     .priv_size     = sizeof(FormatContext),
 
     FILTER_INPUTS(avfilter_vf_noformat_inputs),
     FILTER_OUTPUTS(avfilter_vf_noformat_outputs),
+
+    FILTER_QUERY_FUNC(query_formats),
 };
 #endif /* CONFIG_NOFORMAT_FILTER */
diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c
index 73c973036a..eb6fb70ae7 100644
--- a/libavfilter/vf_framepack.c
+++ b/libavfilter/vf_framepack.c
@@ -469,9 +469,9 @@  const AVFilter ff_vf_framepack = {
     .description   = NULL_IF_CONFIG_SMALL("Generate a frame packed stereoscopic video."),
     .priv_size     = sizeof(FramepackContext),
     .priv_class    = &framepack_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(framepack_inputs),
     FILTER_OUTPUTS(framepack_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
     .uninit        = framepack_uninit,
 };
diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c
index 0f9994e1ac..fff5b2232a 100644
--- a/libavfilter/vf_framerate.c
+++ b/libavfilter/vf_framerate.c
@@ -444,9 +444,9 @@  const AVFilter ff_vf_framerate = {
     .priv_class    = &framerate_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(framerate_inputs),
     FILTER_OUTPUTS(framerate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
     .activate      = activate,
 };
diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
index 152ffdbe30..0852cc3472 100644
--- a/libavfilter/vf_freezedetect.c
+++ b/libavfilter/vf_freezedetect.c
@@ -222,8 +222,8 @@  const AVFilter ff_vf_freezedetect = {
     .priv_size     = sizeof(FreezeDetectContext),
     .priv_class    = &freezedetect_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(freezedetect_inputs),
     FILTER_OUTPUTS(freezedetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
 };
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 827f9c7082..9cd0098e73 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -414,13 +414,13 @@  static const AVFilterPad avfilter_vf_frei0r_outputs[] = {
 const AVFilter ff_vf_frei0r = {
     .name          = "frei0r",
     .description   = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."),
-    .query_formats = query_formats,
     .init          = filter_init,
     .uninit        = uninit,
     .priv_size     = sizeof(Frei0rContext),
     .priv_class    = &frei0r_class,
     FILTER_INPUTS(avfilter_vf_frei0r_inputs),
     FILTER_OUTPUTS(avfilter_vf_frei0r_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -505,7 +505,7 @@  const AVFilter ff_vsrc_frei0r_src = {
     .priv_class    = &frei0r_src_class,
     .init          = source_init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_frei0r_src_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_fspp.c b/libavfilter/vf_fspp.c
index 238dbcb429..622614c071 100644
--- a/libavfilter/vf_fspp.c
+++ b/libavfilter/vf_fspp.c
@@ -667,9 +667,9 @@  const AVFilter ff_vf_fspp = {
     .description     = NULL_IF_CONFIG_SMALL("Apply Fast Simple Post-processing filter."),
     .priv_size       = sizeof(FSPPContext),
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(fspp_inputs),
     FILTER_OUTPUTS(fspp_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &fspp_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_gblur.c b/libavfilter/vf_gblur.c
index ad48eae672..eb83360dfe 100644
--- a/libavfilter/vf_gblur.c
+++ b/libavfilter/vf_gblur.c
@@ -415,9 +415,9 @@  const AVFilter ff_vf_gblur = {
     .priv_size     = sizeof(GBlurContext),
     .priv_class    = &gblur_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(gblur_inputs),
     FILTER_OUTPUTS(gblur_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index 1dc59dc1fa..eef1ac0958 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -489,9 +489,9 @@  const AVFilter ff_vf_geq = {
     .priv_size     = sizeof(GEQContext),
     .init          = geq_init,
     .uninit        = geq_uninit,
-    .query_formats = geq_query_formats,
     FILTER_INPUTS(geq_inputs),
     FILTER_OUTPUTS(geq_outputs),
+    FILTER_QUERY_FUNC(geq_query_formats),
     .priv_class    = &geq_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 6171e75a28..5eb346cd90 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -253,8 +253,8 @@  const AVFilter ff_vf_gradfun = {
     .priv_class    = &gradfun_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_gradfun_inputs),
     FILTER_OUTPUTS(avfilter_vf_gradfun_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_grayworld.c b/libavfilter/vf_grayworld.c
index fd424527e2..d3a935ebe3 100644
--- a/libavfilter/vf_grayworld.c
+++ b/libavfilter/vf_grayworld.c
@@ -329,9 +329,9 @@  const AVFilter ff_vf_grayworld = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust white balance using LAB gray world algorithm"),
     .priv_size     = sizeof(GrayWorldContext),
     .priv_class    = &grayworld_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(grayworld_inputs),
     FILTER_OUTPUTS(grayworld_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .uninit        = uninit,
 };
diff --git a/libavfilter/vf_guided.c b/libavfilter/vf_guided.c
index 6720213219..ea33f5fee4 100644
--- a/libavfilter/vf_guided.c
+++ b/libavfilter/vf_guided.c
@@ -488,12 +488,12 @@  const AVFilter ff_vf_guided = {
     .description     = NULL_IF_CONFIG_SMALL("Apply Guided filter."),
     .init            = init,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(GuidedContext),
     .priv_class      = &guided_class,
     .activate        = activate,
     .inputs          = NULL,
     FILTER_OUTPUTS(guided_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_SLICE_THREADS |
                        AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index fa3fd72bd9..0362660679 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -249,8 +249,8 @@  const AVFilter ff_vf_hflip = {
     .description   = NULL_IF_CONFIG_SMALL("Horizontally flip the input video."),
     .priv_size     = sizeof(FlipContext),
     .priv_class    = &hflip_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_hflip_inputs),
     FILTER_OUTPUTS(avfilter_vf_hflip_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_histeq.c b/libavfilter/vf_histeq.c
index d37dc07389..e08315c50c 100644
--- a/libavfilter/vf_histeq.c
+++ b/libavfilter/vf_histeq.c
@@ -270,9 +270,9 @@  const AVFilter ff_vf_histeq = {
     .description   = NULL_IF_CONFIG_SMALL("Apply global color histogram equalization."),
     .priv_size     = sizeof(HisteqContext),
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(histeq_inputs),
     FILTER_OUTPUTS(histeq_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &histeq_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
index ff79d2130c..52ef26d9b6 100644
--- a/libavfilter/vf_histogram.c
+++ b/libavfilter/vf_histogram.c
@@ -504,9 +504,9 @@  const AVFilter ff_vf_histogram = {
     .name          = "histogram",
     .description   = NULL_IF_CONFIG_SMALL("Compute and draw a histogram."),
     .priv_size     = sizeof(HistogramContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &histogram_class,
 };
 
@@ -546,9 +546,9 @@  const AVFilter ff_vf_thistogram = {
     .name          = "thistogram",
     .description   = NULL_IF_CONFIG_SMALL("Compute and draw a temporal histogram."),
     .priv_size     = sizeof(HistogramContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .uninit        = uninit,
     .priv_class    = &thistogram_class,
 };
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index f11fc46ae5..6621ea8846 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -400,9 +400,9 @@  const AVFilter ff_vf_hqdn3d = {
     .priv_class    = &hqdn3d_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_hqdn3d_inputs),
     FILTER_OUTPUTS(avfilter_vf_hqdn3d_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_hqx.c b/libavfilter/vf_hqx.c
index 8adb1524b0..7f4dc7af37 100644
--- a/libavfilter/vf_hqx.c
+++ b/libavfilter/vf_hqx.c
@@ -554,9 +554,9 @@  const AVFilter ff_vf_hqx = {
     .description   = NULL_IF_CONFIG_SMALL("Scale the input by 2, 3 or 4 using the hq*x magnification algorithm."),
     .priv_size     = sizeof(HQXContext),
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(hqx_inputs),
     FILTER_OUTPUTS(hqx_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &hqx_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_hsvkey.c b/libavfilter/vf_hsvkey.c
index 2f2f037714..30dcbfc029 100644
--- a/libavfilter/vf_hsvkey.c
+++ b/libavfilter/vf_hsvkey.c
@@ -331,9 +331,9 @@  const AVFilter ff_vf_hsvkey = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain HSV range into transparency. Operates on YUV colors."),
     .priv_size     = sizeof(HSVKeyContext),
     .priv_class    = &hsvkey_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(hsvkey_inputs),
     FILTER_OUTPUTS(hsvkey_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
@@ -372,9 +372,9 @@  const AVFilter ff_vf_hsvhold = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain HSV range into gray."),
     .priv_size     = sizeof(HSVKeyContext),
     .priv_class    = &hsvhold_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(hsvhold_inputs),
     FILTER_OUTPUTS(hsvhold_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
index c35722eb4b..a9f96a02f7 100644
--- a/libavfilter/vf_hue.c
+++ b/libavfilter/vf_hue.c
@@ -517,10 +517,10 @@  const AVFilter ff_vf_hue = {
     .priv_size       = sizeof(HueContext),
     .init            = init,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     .process_command = process_command,
     FILTER_INPUTS(hue_inputs),
     FILTER_OUTPUTS(hue_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &hue_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_hwdownload.c b/libavfilter/vf_hwdownload.c
index 5bd63a8a8f..5ef23cb5d4 100644
--- a/libavfilter/vf_hwdownload.c
+++ b/libavfilter/vf_hwdownload.c
@@ -193,10 +193,10 @@  const AVFilter ff_vf_hwdownload = {
     .name          = "hwdownload",
     .description   = NULL_IF_CONFIG_SMALL("Download a hardware frame to a normal frame"),
     .uninit        = hwdownload_uninit,
-    .query_formats = hwdownload_query_formats,
     .priv_size     = sizeof(HWDownloadContext),
     .priv_class    = &hwdownload_class,
     FILTER_INPUTS(hwdownload_inputs),
     FILTER_OUTPUTS(hwdownload_outputs),
+    FILTER_QUERY_FUNC(hwdownload_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c
index be29261223..2e03dfc1fe 100644
--- a/libavfilter/vf_hwmap.c
+++ b/libavfilter/vf_hwmap.c
@@ -423,8 +423,8 @@  const AVFilter ff_vf_hwmap = {
     .uninit         = hwmap_uninit,
     .priv_size      = sizeof(HWMapContext),
     .priv_class     = &hwmap_class,
-    .query_formats  = hwmap_query_formats,
     FILTER_INPUTS(hwmap_inputs),
     FILTER_OUTPUTS(hwmap_outputs),
+    FILTER_QUERY_FUNC(hwmap_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c
index 4cbc621af3..dbc41734cc 100644
--- a/libavfilter/vf_hwupload.c
+++ b/libavfilter/vf_hwupload.c
@@ -252,10 +252,10 @@  const AVFilter ff_vf_hwupload = {
     .name          = "hwupload",
     .description   = NULL_IF_CONFIG_SMALL("Upload a normal frame to a hardware frame"),
     .uninit        = hwupload_uninit,
-    .query_formats = hwupload_query_formats,
     .priv_size     = sizeof(HWUploadContext),
     .priv_class    = &hwupload_class,
     FILTER_INPUTS(hwupload_inputs),
     FILTER_OUTPUTS(hwupload_outputs),
+    FILTER_QUERY_FUNC(hwupload_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c
index 31c1cdbddb..f5fe3ddbbe 100644
--- a/libavfilter/vf_hwupload_cuda.c
+++ b/libavfilter/vf_hwupload_cuda.c
@@ -188,13 +188,13 @@  const AVFilter ff_vf_hwupload_cuda = {
     .init      = cudaupload_init,
     .uninit    = cudaupload_uninit,
 
-    .query_formats = cudaupload_query_formats,
-
     .priv_size  = sizeof(CudaUploadContext),
     .priv_class = &cudaupload_class,
 
     FILTER_INPUTS(cudaupload_inputs),
     FILTER_OUTPUTS(cudaupload_outputs),
 
+    FILTER_QUERY_FUNC(cudaupload_query_formats),
+
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hysteresis.c b/libavfilter/vf_hysteresis.c
index 0346465e43..abdf224f83 100644
--- a/libavfilter/vf_hysteresis.c
+++ b/libavfilter/vf_hysteresis.c
@@ -374,10 +374,10 @@  const AVFilter ff_vf_hysteresis = {
     .preinit       = hysteresis_framesync_preinit,
     .priv_size     = sizeof(HysteresisContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(hysteresis_inputs),
     FILTER_OUTPUTS(hysteresis_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &hysteresis_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_identity.c b/libavfilter/vf_identity.c
index 5f0b4e9834..22ee744c2d 100644
--- a/libavfilter/vf_identity.c
+++ b/libavfilter/vf_identity.c
@@ -411,12 +411,12 @@  const AVFilter ff_vf_identity = {
     .preinit       = identity_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(IdentityContext),
     .priv_class    = &identity_class,
     FILTER_INPUTS(identity_inputs),
     FILTER_OUTPUTS(identity_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
@@ -433,12 +433,12 @@  const AVFilter ff_vf_msad = {
     .preinit       = msad_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(IdentityContext),
     .priv_class    = &msad_class,
     FILTER_INPUTS(identity_inputs),
     FILTER_OUTPUTS(identity_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index e006e72da9..5048b1ae46 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -441,8 +441,8 @@  const AVFilter ff_vf_idet = {
     .priv_size     = sizeof(IDETContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(idet_inputs),
     FILTER_OUTPUTS(idet_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &idet_class,
 };
diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c
index 38ef1ac47a..e1c380a2cf 100644
--- a/libavfilter/vf_il.c
+++ b/libavfilter/vf_il.c
@@ -194,9 +194,9 @@  const AVFilter ff_vf_il = {
     .name          = "il",
     .description   = NULL_IF_CONFIG_SMALL("Deinterleave or interleave fields."),
     .priv_size     = sizeof(IlContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &il_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = ff_filter_process_command,
diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c
index 85b426d0b0..5d3e32a3ce 100644
--- a/libavfilter/vf_kerndeint.c
+++ b/libavfilter/vf_kerndeint.c
@@ -308,7 +308,7 @@  const AVFilter ff_vf_kerndeint = {
     .priv_size     = sizeof(KerndeintContext),
     .priv_class    = &kerndeint_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(kerndeint_inputs),
     FILTER_OUTPUTS(kerndeint_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_lagfun.c b/libavfilter/vf_lagfun.c
index fee371b25f..0b400524ed 100644
--- a/libavfilter/vf_lagfun.c
+++ b/libavfilter/vf_lagfun.c
@@ -220,10 +220,10 @@  const AVFilter ff_vf_lagfun = {
     .description   = NULL_IF_CONFIG_SMALL("Slowly update darker pixels."),
     .priv_size     = sizeof(LagfunContext),
     .priv_class    = &lagfun_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_OUTPUTS(outputs),
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_lenscorrection.c b/libavfilter/vf_lenscorrection.c
index 1140e1d484..fc13ffd4c2 100644
--- a/libavfilter/vf_lenscorrection.c
+++ b/libavfilter/vf_lenscorrection.c
@@ -357,9 +357,9 @@  const AVFilter ff_vf_lenscorrection = {
     .name          = "lenscorrection",
     .description   = NULL_IF_CONFIG_SMALL("Rectify the image by correcting for lens distortion."),
     .priv_size     = sizeof(LenscorrectionCtx),
-    .query_formats = query_formats,
     FILTER_INPUTS(lenscorrection_inputs),
     FILTER_OUTPUTS(lenscorrection_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &lenscorrection_class,
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_lensfun.c b/libavfilter/vf_lensfun.c
index 3837500481..c9a62ccee7 100644
--- a/libavfilter/vf_lensfun.c
+++ b/libavfilter/vf_lensfun.c
@@ -534,9 +534,9 @@  const AVFilter ff_vf_lensfun = {
     .priv_size     = sizeof(LensfunContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(lensfun_inputs),
     FILTER_OUTPUTS(lensfun_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &lensfun_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index f886395ab7..2f45f70fd4 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -427,9 +427,9 @@  const AVFilter ff_vf_ocv = {
     .description   = NULL_IF_CONFIG_SMALL("Apply transform using libopencv."),
     .priv_size     = sizeof(OCVContext),
     .priv_class    = &ocv_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(avfilter_vf_ocv_inputs),
     FILTER_OUTPUTS(avfilter_vf_ocv_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c
index 00b2661f5e..db008d5c05 100644
--- a/libavfilter/vf_libvmaf.c
+++ b/libavfilter/vf_libvmaf.c
@@ -362,10 +362,10 @@  const AVFilter ff_vf_libvmaf = {
     .preinit       = libvmaf_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(LIBVMAFContext),
     .priv_class    = &libvmaf_class,
     FILTER_INPUTS(libvmaf_inputs),
     FILTER_OUTPUTS(libvmaf_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c
index 022b9ebf39..cd21fd0319 100644
--- a/libavfilter/vf_limiter.c
+++ b/libavfilter/vf_limiter.c
@@ -261,9 +261,9 @@  const AVFilter ff_vf_limiter = {
     .priv_size     = sizeof(LimiterContext),
     .priv_class    = &limiter_class,
     .init          = init,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_lumakey.c b/libavfilter/vf_lumakey.c
index b3bfb0a278..9c3329925c 100644
--- a/libavfilter/vf_lumakey.c
+++ b/libavfilter/vf_lumakey.c
@@ -202,9 +202,9 @@  const AVFilter ff_vf_lumakey = {
     .description   = NULL_IF_CONFIG_SMALL("Turns a certain luma into transparency."),
     .priv_size     = sizeof(LumakeyContext),
     .priv_class    = &lumakey_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(lumakey_inputs),
     FILTER_OUTPUTS(lumakey_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index d335fd6c39..64668039d1 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -595,9 +595,9 @@  static const AVFilterPad outputs[] = {
         .priv_size     = sizeof(LutContext),                            \
         .init          = name_##_init,                                  \
         .uninit        = uninit,                                        \
-        .query_formats = query_formats,                                 \
         FILTER_INPUTS(inputs),                                          \
         FILTER_OUTPUTS(outputs),                                        \
+        FILTER_QUERY_FUNC(query_formats),                               \
         .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |       \
                          AVFILTER_FLAG_SLICE_THREADS,                   \
         .process_command = process_command,                             \
diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c
index 9fde3a08ee..868c0496fa 100644
--- a/libavfilter/vf_lut2.c
+++ b/libavfilter/vf_lut2.c
@@ -566,10 +566,10 @@  const AVFilter ff_vf_lut2 = {
     .priv_size     = sizeof(LUT2Context),
     .priv_class    = &lut2_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -655,11 +655,11 @@  const AVFilter ff_vf_tlut2 = {
     .description   = NULL_IF_CONFIG_SMALL("Compute and apply a lookup table from two successive frames."),
     .priv_size     = sizeof(LUT2Context),
     .priv_class    = &tlut2_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(tlut2_inputs),
     FILTER_OUTPUTS(tlut2_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 9fbda833b9..bb26bb3068 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -1364,9 +1364,9 @@  const AVFilter ff_vf_lut3d = {
     .priv_size     = sizeof(LUT3DContext),
     .init          = lut3d_init,
     .uninit        = lut3d_uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(lut3d_inputs),
     FILTER_OUTPUTS(lut3d_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &lut3d_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -1627,10 +1627,10 @@  const AVFilter ff_vf_haldclut = {
     .preinit       = haldclut_framesync_preinit,
     .init          = haldclut_init,
     .uninit        = haldclut_uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(haldclut_inputs),
     FILTER_OUTPUTS(haldclut_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &haldclut_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -2291,9 +2291,9 @@  const AVFilter ff_vf_lut1d = {
     .description   = NULL_IF_CONFIG_SMALL("Adjust colors using a 1D LUT."),
     .priv_size     = sizeof(LUT1DContext),
     .init          = lut1d_init,
-    .query_formats = query_formats,
     FILTER_INPUTS(lut1d_inputs),
     FILTER_OUTPUTS(lut1d_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &lut1d_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = lut1d_process_command,
diff --git a/libavfilter/vf_maskedclamp.c b/libavfilter/vf_maskedclamp.c
index f46c5c9934..6152ec5405 100644
--- a/libavfilter/vf_maskedclamp.c
+++ b/libavfilter/vf_maskedclamp.c
@@ -315,9 +315,9 @@  const AVFilter ff_vf_maskedclamp = {
     .priv_size     = sizeof(MaskedClampContext),
     .uninit        = uninit,
     .activate      = activate,
-    .query_formats = query_formats,
     FILTER_INPUTS(maskedclamp_inputs),
     FILTER_OUTPUTS(maskedclamp_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &maskedclamp_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c
index 26b54830b8..e3b3f01ef8 100644
--- a/libavfilter/vf_maskedmerge.c
+++ b/libavfilter/vf_maskedmerge.c
@@ -315,10 +315,10 @@  const AVFilter ff_vf_maskedmerge = {
     .description   = NULL_IF_CONFIG_SMALL("Merge first stream with second stream using third stream as mask."),
     .priv_size     = sizeof(MaskedMergeContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(maskedmerge_inputs),
     FILTER_OUTPUTS(maskedmerge_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &maskedmerge_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
diff --git a/libavfilter/vf_maskedminmax.c b/libavfilter/vf_maskedminmax.c
index 82b0eca8f0..9f4846b08b 100644
--- a/libavfilter/vf_maskedminmax.c
+++ b/libavfilter/vf_maskedminmax.c
@@ -328,9 +328,9 @@  const AVFilter ff_vf_maskedmin = {
     .init          = maskedmin_init,
     .uninit        = uninit,
     .activate      = activate,
-    .query_formats = query_formats,
     FILTER_INPUTS(maskedminmax_inputs),
     FILTER_OUTPUTS(maskedminmax_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
@@ -342,9 +342,9 @@  const AVFilter ff_vf_maskedmax = {
     .priv_size     = sizeof(MaskedMinMaxContext),
     .uninit        = uninit,
     .activate      = activate,
-    .query_formats = query_formats,
     FILTER_INPUTS(maskedminmax_inputs),
     FILTER_OUTPUTS(maskedminmax_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_maskedthreshold.c b/libavfilter/vf_maskedthreshold.c
index a8f717364e..4f23f8369e 100644
--- a/libavfilter/vf_maskedthreshold.c
+++ b/libavfilter/vf_maskedthreshold.c
@@ -285,9 +285,9 @@  const AVFilter ff_vf_maskedthreshold = {
     .priv_size     = sizeof(MaskedThresholdContext),
     .uninit        = uninit,
     .activate      = activate,
-    .query_formats = query_formats,
     FILTER_INPUTS(maskedthreshold_inputs),
     FILTER_OUTPUTS(maskedthreshold_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_maskfun.c b/libavfilter/vf_maskfun.c
index 5f323385ee..4209205489 100644
--- a/libavfilter/vf_maskfun.c
+++ b/libavfilter/vf_maskfun.c
@@ -311,10 +311,10 @@  const AVFilter ff_vf_maskfun = {
     .name          = "maskfun",
     .description   = NULL_IF_CONFIG_SMALL("Create Mask."),
     .priv_size     = sizeof(MaskFunContext),
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(maskfun_inputs),
     FILTER_OUTPUTS(maskfun_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &maskfun_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c
index 88c8b25a6d..fcbc0257b9 100644
--- a/libavfilter/vf_mcdeint.c
+++ b/libavfilter/vf_mcdeint.c
@@ -304,8 +304,8 @@  const AVFilter ff_vf_mcdeint = {
     .description   = NULL_IF_CONFIG_SMALL("Apply motion compensating deinterlacing."),
     .priv_size     = sizeof(MCDeintContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(mcdeint_inputs),
     FILTER_OUTPUTS(mcdeint_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &mcdeint_class,
 };
diff --git a/libavfilter/vf_median.c b/libavfilter/vf_median.c
index 61a2656244..8fd5f95ad6 100644
--- a/libavfilter/vf_median.c
+++ b/libavfilter/vf_median.c
@@ -288,9 +288,9 @@  const AVFilter ff_vf_median = {
     .priv_size     = sizeof(MedianContext),
     .priv_class    = &median_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(median_inputs),
     FILTER_OUTPUTS(median_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_mergeplanes.c b/libavfilter/vf_mergeplanes.c
index 638a7065f2..fc1d50a72e 100644
--- a/libavfilter/vf_mergeplanes.c
+++ b/libavfilter/vf_mergeplanes.c
@@ -296,9 +296,9 @@  const AVFilter ff_vf_mergeplanes = {
     .priv_class    = &mergeplanes_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(mergeplanes_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_mestimate.c b/libavfilter/vf_mestimate.c
index 578c3be812..2856d121c3 100644
--- a/libavfilter/vf_mestimate.c
+++ b/libavfilter/vf_mestimate.c
@@ -368,7 +368,7 @@  const AVFilter ff_vf_mestimate = {
     .priv_size     = sizeof(MEContext),
     .priv_class    = &mestimate_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(mestimate_inputs),
     FILTER_OUTPUTS(mestimate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_midequalizer.c b/libavfilter/vf_midequalizer.c
index 069bf47174..93d1ebff2d 100644
--- a/libavfilter/vf_midequalizer.c
+++ b/libavfilter/vf_midequalizer.c
@@ -373,10 +373,10 @@  const AVFilter ff_vf_midequalizer = {
     .description   = NULL_IF_CONFIG_SMALL("Apply Midway Equalization."),
     .priv_size     = sizeof(MidEqualizerContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(midequalizer_inputs),
     FILTER_OUTPUTS(midequalizer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &midequalizer_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c
index f4e791a19e..28ba2633d1 100644
--- a/libavfilter/vf_minterpolate.c
+++ b/libavfilter/vf_minterpolate.c
@@ -1258,7 +1258,7 @@  const AVFilter ff_vf_minterpolate = {
     .priv_size     = sizeof(MIContext),
     .priv_class    = &minterpolate_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(minterpolate_inputs),
     FILTER_OUTPUTS(minterpolate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_misc_vaapi.c b/libavfilter/vf_misc_vaapi.c
index 83aedcdc31..db3e69679a 100644
--- a/libavfilter/vf_misc_vaapi.c
+++ b/libavfilter/vf_misc_vaapi.c
@@ -238,9 +238,9 @@  const AVFilter ff_vf_denoise_vaapi = {
     .priv_size     = sizeof(DenoiseVAAPIContext),
     .init          = &denoise_vaapi_init,
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(misc_vaapi_inputs),
     FILTER_OUTPUTS(misc_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class    = &denoise_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
@@ -251,9 +251,9 @@  const AVFilter ff_vf_sharpness_vaapi = {
     .priv_size     = sizeof(SharpnessVAAPIContext),
     .init          = &sharpness_vaapi_init,
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(misc_vaapi_inputs),
     FILTER_OUTPUTS(misc_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class    = &sharpness_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_mix.c b/libavfilter/vf_mix.c
index 13032e466a..27455657f2 100644
--- a/libavfilter/vf_mix.c
+++ b/libavfilter/vf_mix.c
@@ -353,8 +353,8 @@  const AVFilter ff_vf_mix = {
     .description   = NULL_IF_CONFIG_SMALL("Mix video inputs."),
     .priv_size     = sizeof(MixContext),
     .priv_class    = &mix_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
@@ -430,9 +430,9 @@  const AVFilter ff_vf_tmix = {
     .description   = NULL_IF_CONFIG_SMALL("Mix successive video frames."),
     .priv_size     = sizeof(MixContext),
     .priv_class    = &tmix_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
     FILTER_INPUTS(inputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_monochrome.c b/libavfilter/vf_monochrome.c
index 5792e27cb9..b2db6eb864 100644
--- a/libavfilter/vf_monochrome.c
+++ b/libavfilter/vf_monochrome.c
@@ -298,9 +298,9 @@  const AVFilter ff_vf_monochrome = {
     .description   = NULL_IF_CONFIG_SMALL("Convert video to gray using custom color filter."),
     .priv_size     = sizeof(MonochromeContext),
     .priv_class    = &monochrome_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(monochrome_inputs),
     FILTER_OUTPUTS(monochrome_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_morpho.c b/libavfilter/vf_morpho.c
index 13d58c4194..574f248153 100644
--- a/libavfilter/vf_morpho.c
+++ b/libavfilter/vf_morpho.c
@@ -1019,9 +1019,9 @@  const AVFilter ff_vf_morpho = {
     .priv_class      = &morpho_class,
     .activate        = activate,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(morpho_inputs),
     FILTER_OUTPUTS(morpho_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c
index 8d515396f3..c48cff8a4b 100644
--- a/libavfilter/vf_mpdecimate.c
+++ b/libavfilter/vf_mpdecimate.c
@@ -244,7 +244,7 @@  const AVFilter ff_vf_mpdecimate = {
     .uninit        = uninit,
     .priv_size     = sizeof(DecimateContext),
     .priv_class    = &mpdecimate_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(mpdecimate_inputs),
     FILTER_OUTPUTS(mpdecimate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_neighbor.c b/libavfilter/vf_neighbor.c
index c35a8a7917..8723350a63 100644
--- a/libavfilter/vf_neighbor.c
+++ b/libavfilter/vf_neighbor.c
@@ -360,9 +360,9 @@  const AVFilter ff_vf_##name_ = {                                   \
     .description   = NULL_IF_CONFIG_SMALL(description_),     \
     .priv_class    = &priv_class_##_class,                   \
     .priv_size     = sizeof(NContext),                       \
-    .query_formats = query_formats,                          \
     FILTER_INPUTS(neighbor_inputs),                          \
     FILTER_OUTPUTS(neighbor_outputs),                        \
+    FILTER_QUERY_FUNC(query_formats),                        \
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC| \
                      AVFILTER_FLAG_SLICE_THREADS,            \
     .process_command = ff_filter_process_command,            \
diff --git a/libavfilter/vf_neighbor_opencl.c b/libavfilter/vf_neighbor_opencl.c
index 68becfe143..93c5fbbadc 100644
--- a/libavfilter/vf_neighbor_opencl.c
+++ b/libavfilter/vf_neighbor_opencl.c
@@ -278,9 +278,9 @@  const AVFilter ff_vf_erosion_opencl = {
     .priv_class     = &erosion_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &neighbor_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(neighbor_opencl_inputs),
     FILTER_OUTPUTS(neighbor_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -306,7 +306,7 @@  const AVFilter ff_vf_dilation_opencl = {
     .priv_class     = &dilation_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &neighbor_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     FILTER_INPUTS(neighbor_opencl_inputs),
     FILTER_OUTPUTS(neighbor_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
diff --git a/libavfilter/vf_nlmeans.c b/libavfilter/vf_nlmeans.c
index 20107022c4..30a845e93c 100644
--- a/libavfilter/vf_nlmeans.c
+++ b/libavfilter/vf_nlmeans.c
@@ -578,9 +578,9 @@  const AVFilter ff_vf_nlmeans = {
     .priv_size     = sizeof(NLMeansContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(nlmeans_inputs),
     FILTER_OUTPUTS(nlmeans_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &nlmeans_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_nlmeans_opencl.c b/libavfilter/vf_nlmeans_opencl.c
index 6e28f4be7a..6d6ac8136c 100644
--- a/libavfilter/vf_nlmeans_opencl.c
+++ b/libavfilter/vf_nlmeans_opencl.c
@@ -434,8 +434,8 @@  const AVFilter ff_vf_nlmeans_opencl = {
     .priv_class     = &nlmeans_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &nlmeans_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(nlmeans_opencl_inputs),
     FILTER_OUTPUTS(nlmeans_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_nnedi.c b/libavfilter/vf_nnedi.c
index 944736a279..03f0541292 100644
--- a/libavfilter/vf_nnedi.c
+++ b/libavfilter/vf_nnedi.c
@@ -1159,9 +1159,9 @@  const AVFilter ff_vf_nnedi = {
     .priv_class    = &nnedi_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c
index 50febf230d..0e3e72b6b5 100644
--- a/libavfilter/vf_noise.c
+++ b/libavfilter/vf_noise.c
@@ -342,9 +342,9 @@  const AVFilter ff_vf_noise = {
     .priv_size     = sizeof(NoiseContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(noise_inputs),
     FILTER_OUTPUTS(noise_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &noise_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_normalize.c b/libavfilter/vf_normalize.c
index 26f8e2f426..e185cd998c 100644
--- a/libavfilter/vf_normalize.c
+++ b/libavfilter/vf_normalize.c
@@ -531,9 +531,9 @@  const AVFilter ff_vf_normalize = {
     .priv_size     = sizeof(NormalizeContext),
     .priv_class    = &normalize_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_ocr.c b/libavfilter/vf_ocr.c
index 7691f41932..bc088f0299 100644
--- a/libavfilter/vf_ocr.c
+++ b/libavfilter/vf_ocr.c
@@ -146,9 +146,9 @@  const AVFilter ff_vf_ocr = {
     .description   = NULL_IF_CONFIG_SMALL("Optical Character Recognition."),
     .priv_size     = sizeof(OCRContext),
     .priv_class    = &ocr_class,
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(ocr_inputs),
     FILTER_OUTPUTS(ocr_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index afa694e100..2966cef09c 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -1112,11 +1112,11 @@  const AVFilter ff_vf_overlay = {
     .uninit        = uninit,
     .priv_size     = sizeof(OverlayContext),
     .priv_class    = &overlay_class,
-    .query_formats = query_formats,
     .activate      = activate,
     .process_command = process_command,
     FILTER_INPUTS(avfilter_vf_overlay_inputs),
     FILTER_OUTPUTS(avfilter_vf_overlay_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_overlay_cuda.c b/libavfilter/vf_overlay_cuda.c
index 4c0719871b..38387780dc 100644
--- a/libavfilter/vf_overlay_cuda.c
+++ b/libavfilter/vf_overlay_cuda.c
@@ -583,9 +583,9 @@  const AVFilter ff_vf_overlay_cuda = {
     .init            = &overlay_cuda_init,
     .uninit          = &overlay_cuda_uninit,
     .activate        = &overlay_cuda_activate,
-    .query_formats   = &overlay_cuda_query_formats,
     FILTER_INPUTS(overlay_cuda_inputs),
     FILTER_OUTPUTS(overlay_cuda_outputs),
+    FILTER_QUERY_FUNC(&overlay_cuda_query_formats),
     .preinit         = overlay_cuda_framesync_preinit,
     .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_overlay_opencl.c b/libavfilter/vf_overlay_opencl.c
index 4f1d6bbdd2..b17b60c980 100644
--- a/libavfilter/vf_overlay_opencl.c
+++ b/libavfilter/vf_overlay_opencl.c
@@ -317,9 +317,9 @@  const AVFilter ff_vf_overlay_opencl = {
     .priv_class      = &overlay_opencl_class,
     .init            = &overlay_opencl_init,
     .uninit          = &overlay_opencl_uninit,
-    .query_formats   = &ff_opencl_filter_query_formats,
     .activate        = &overlay_opencl_activate,
     FILTER_INPUTS(overlay_opencl_inputs),
     FILTER_OUTPUTS(overlay_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 76bad4a984..7e76b39aa9 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -417,13 +417,13 @@  const AVFilter ff_vf_overlay_qsv = {
     .name           = "overlay_qsv",
     .description    = NULL_IF_CONFIG_SMALL("Quick Sync Video overlay."),
     .priv_size      = sizeof(QSVOverlayContext),
-    .query_formats  = overlay_qsv_query_formats,
     .preinit        = overlay_qsv_framesync_preinit,
     .init           = overlay_qsv_init,
     .uninit         = overlay_qsv_uninit,
     .activate       = activate,
     FILTER_INPUTS(overlay_qsv_inputs),
     FILTER_OUTPUTS(overlay_qsv_outputs),
+    FILTER_QUERY_FUNC(overlay_qsv_query_formats),
     .priv_class     = &overlay_qsv_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_overlay_vulkan.c b/libavfilter/vf_overlay_vulkan.c
index 1815709d82..5573e5e57d 100644
--- a/libavfilter/vf_overlay_vulkan.c
+++ b/libavfilter/vf_overlay_vulkan.c
@@ -479,10 +479,10 @@  const AVFilter ff_vf_overlay_vulkan = {
     .priv_size      = sizeof(OverlayVulkanContext),
     .init           = &overlay_vulkan_init,
     .uninit         = &overlay_vulkan_uninit,
-    .query_formats  = &ff_vk_filter_query_formats,
     .activate       = &overlay_vulkan_activate,
     FILTER_INPUTS(overlay_vulkan_inputs),
     FILTER_OUTPUTS(overlay_vulkan_outputs),
+    FILTER_QUERY_FUNC(&ff_vk_filter_query_formats),
     .priv_class     = &overlay_vulkan_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_owdenoise.c b/libavfilter/vf_owdenoise.c
index 80ce3ca654..f0d2740ca1 100644
--- a/libavfilter/vf_owdenoise.c
+++ b/libavfilter/vf_owdenoise.c
@@ -365,9 +365,9 @@  const AVFilter ff_vf_owdenoise = {
     .description   = NULL_IF_CONFIG_SMALL("Denoise using wavelets."),
     .priv_size     = sizeof(OWDenoiseContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(owdenoise_inputs),
     FILTER_OUTPUTS(owdenoise_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &owdenoise_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index ba1728f820..738e255621 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -456,7 +456,7 @@  const AVFilter ff_vf_pad = {
     .description   = NULL_IF_CONFIG_SMALL("Pad the input video."),
     .priv_size     = sizeof(PadContext),
     .priv_class    = &pad_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_pad_inputs),
     FILTER_OUTPUTS(avfilter_vf_pad_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_pad_opencl.c b/libavfilter/vf_pad_opencl.c
index 9e6fc94097..4e52556e9e 100644
--- a/libavfilter/vf_pad_opencl.c
+++ b/libavfilter/vf_pad_opencl.c
@@ -388,8 +388,8 @@  const AVFilter ff_vf_pad_opencl = {
     .priv_class     = &pad_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &pad_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(pad_opencl_inputs),
     FILTER_OUTPUTS(pad_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE
 };
diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index 4c2fbd36d7..4b262dfa1c 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -573,8 +573,8 @@  const AVFilter ff_vf_palettegen = {
     .description   = NULL_IF_CONFIG_SMALL("Find the optimal palette for a given stream."),
     .priv_size     = sizeof(PaletteGenContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(palettegen_inputs),
     FILTER_OUTPUTS(palettegen_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &palettegen_class,
 };
diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index f9bc28f7d0..09e67de042 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -1132,11 +1132,11 @@  const AVFilter ff_vf_paletteuse = {
     .name          = "paletteuse",
     .description   = NULL_IF_CONFIG_SMALL("Use a palette to downsample an input video stream."),
     .priv_size     = sizeof(PaletteUseContext),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
     FILTER_INPUTS(paletteuse_inputs),
     FILTER_OUTPUTS(paletteuse_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &paletteuse_class,
 };
diff --git a/libavfilter/vf_perspective.c b/libavfilter/vf_perspective.c
index 5fa661862f..216674d0d6 100644
--- a/libavfilter/vf_perspective.c
+++ b/libavfilter/vf_perspective.c
@@ -513,9 +513,9 @@  const AVFilter ff_vf_perspective = {
     .priv_size     = sizeof(PerspectiveContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(perspective_inputs),
     FILTER_OUTPUTS(perspective_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &perspective_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_phase.c b/libavfilter/vf_phase.c
index cab6174d72..6229754663 100644
--- a/libavfilter/vf_phase.c
+++ b/libavfilter/vf_phase.c
@@ -236,9 +236,9 @@  const AVFilter ff_vf_phase = {
     .priv_size     = sizeof(PhaseContext),
     .priv_class    = &phase_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(phase_inputs),
     FILTER_OUTPUTS(phase_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_photosensitivity.c b/libavfilter/vf_photosensitivity.c
index a5a86133f1..18a210c292 100644
--- a/libavfilter/vf_photosensitivity.c
+++ b/libavfilter/vf_photosensitivity.c
@@ -332,7 +332,7 @@  const AVFilter ff_vf_photosensitivity = {
     .priv_size     = sizeof(PhotosensitivityContext),
     .priv_class    = &photosensitivity_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c
index c27c2029c0..77a23f1388 100644
--- a/libavfilter/vf_pp.c
+++ b/libavfilter/vf_pp.c
@@ -192,9 +192,9 @@  const AVFilter ff_vf_pp = {
     .priv_size       = sizeof(PPFilterContext),
     .init            = pp_init,
     .uninit          = pp_uninit,
-    .query_formats   = pp_query_formats,
     FILTER_INPUTS(pp_inputs),
     FILTER_OUTPUTS(pp_outputs),
+    FILTER_QUERY_FUNC(pp_query_formats),
     .process_command = pp_process_command,
     .priv_class      = &pp_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
diff --git a/libavfilter/vf_pp7.c b/libavfilter/vf_pp7.c
index 74f20365e0..d645c40ee9 100644
--- a/libavfilter/vf_pp7.c
+++ b/libavfilter/vf_pp7.c
@@ -401,9 +401,9 @@  const AVFilter ff_vf_pp7 = {
     .description     = NULL_IF_CONFIG_SMALL("Apply Postprocessing 7 filter."),
     .priv_size       = sizeof(PP7Context),
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(pp7_inputs),
     FILTER_OUTPUTS(pp7_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &pp7_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c
index ada249fc55..4b60de7b7b 100644
--- a/libavfilter/vf_premultiply.c
+++ b/libavfilter/vf_premultiply.c
@@ -824,10 +824,10 @@  const AVFilter ff_vf_premultiply = {
     .priv_size     = sizeof(PreMultiplyContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(premultiply_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &premultiply_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_DYNAMIC_INPUTS |
@@ -845,10 +845,10 @@  const AVFilter ff_vf_unpremultiply = {
     .priv_size     = sizeof(PreMultiplyContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(premultiply_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_DYNAMIC_INPUTS |
                      AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_procamp_vaapi.c b/libavfilter/vf_procamp_vaapi.c
index 758546abf9..4a3b9d0766 100644
--- a/libavfilter/vf_procamp_vaapi.c
+++ b/libavfilter/vf_procamp_vaapi.c
@@ -235,9 +235,9 @@  const AVFilter ff_vf_procamp_vaapi = {
     .priv_size     = sizeof(ProcampVAAPIContext),
     .init          = &procamp_vaapi_init,
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(procamp_vaapi_inputs),
     FILTER_OUTPUTS(procamp_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class    = &procamp_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_program_opencl.c b/libavfilter/vf_program_opencl.c
index 1ffb18bde1..7615e5c7c7 100644
--- a/libavfilter/vf_program_opencl.c
+++ b/libavfilter/vf_program_opencl.c
@@ -364,10 +364,10 @@  const AVFilter ff_vf_program_opencl = {
     .preinit        = &program_opencl_framesync_preinit,
     .init           = &program_opencl_init,
     .uninit         = &program_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     .activate       = &program_opencl_activate,
     .inputs         = NULL,
     FILTER_OUTPUTS(program_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -415,9 +415,9 @@  const AVFilter ff_vsrc_openclsrc = {
     .priv_class     = &openclsrc_class,
     .init           = &program_opencl_init,
     .uninit         = &program_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = NULL,
     FILTER_OUTPUTS(openclsrc_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c
index 44cb01ef9a..fd84a0a819 100644
--- a/libavfilter/vf_pseudocolor.c
+++ b/libavfilter/vf_pseudocolor.c
@@ -922,9 +922,9 @@  const AVFilter ff_vf_pseudocolor = {
     .priv_size     = sizeof(PseudoColorContext),
     .priv_class    = &pseudocolor_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c
index a4ce9a4c4c..e6ae0afb6c 100644
--- a/libavfilter/vf_psnr.c
+++ b/libavfilter/vf_psnr.c
@@ -465,11 +465,11 @@  const AVFilter ff_vf_psnr = {
     .preinit       = psnr_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(PSNRContext),
     .priv_class    = &psnr_class,
     FILTER_INPUTS(psnr_inputs),
     FILTER_OUTPUTS(psnr_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c
index 57e86e9c89..4b02e8c255 100644
--- a/libavfilter/vf_pullup.c
+++ b/libavfilter/vf_pullup.c
@@ -765,7 +765,7 @@  const AVFilter ff_vf_pullup = {
     .priv_size     = sizeof(PullupContext),
     .priv_class    = &pullup_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(pullup_inputs),
     FILTER_OUTPUTS(pullup_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_readeia608.c b/libavfilter/vf_readeia608.c
index 5ce2e75213..5412ff5ae7 100644
--- a/libavfilter/vf_readeia608.c
+++ b/libavfilter/vf_readeia608.c
@@ -555,9 +555,9 @@  const AVFilter ff_vf_readeia608 = {
     .description   = NULL_IF_CONFIG_SMALL("Read EIA-608 Closed Caption codes from input video and write them to frame metadata."),
     .priv_size     = sizeof(ReadEIA608Context),
     .priv_class    = &readeia608_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(readeia608_inputs),
     FILTER_OUTPUTS(readeia608_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_readvitc.c b/libavfilter/vf_readvitc.c
index d117a81284..eb8d11f7f2 100644
--- a/libavfilter/vf_readvitc.c
+++ b/libavfilter/vf_readvitc.c
@@ -249,5 +249,5 @@  const AVFilter ff_vf_readvitc = {
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
     .init          = init,
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c
index ec925e8948..f536580a90 100644
--- a/libavfilter/vf_remap.c
+++ b/libavfilter/vf_remap.c
@@ -398,10 +398,10 @@  const AVFilter ff_vf_remap = {
     .description   = NULL_IF_CONFIG_SMALL("Remap pixels."),
     .priv_size     = sizeof(RemapContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(remap_inputs),
     FILTER_OUTPUTS(remap_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &remap_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_removegrain.c b/libavfilter/vf_removegrain.c
index 1d1d756057..f87d141ae7 100644
--- a/libavfilter/vf_removegrain.c
+++ b/libavfilter/vf_removegrain.c
@@ -647,9 +647,9 @@  const AVFilter ff_vf_removegrain = {
     .name          = "removegrain",
     .description   = NULL_IF_CONFIG_SMALL("Remove grain."),
     .priv_size     = sizeof(RemoveGrainContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(removegrain_inputs),
     FILTER_OUTPUTS(removegrain_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &removegrain_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c
index acf09960ff..0bfec406c0 100644
--- a/libavfilter/vf_removelogo.c
+++ b/libavfilter/vf_removelogo.c
@@ -574,9 +574,9 @@  const AVFilter ff_vf_removelogo = {
     .priv_size     = sizeof(RemovelogoContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(removelogo_inputs),
     FILTER_OUTPUTS(removelogo_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &removelogo_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_repeatfields.c b/libavfilter/vf_repeatfields.c
index ca4bd97b2f..f2aca5a059 100644
--- a/libavfilter/vf_repeatfields.c
+++ b/libavfilter/vf_repeatfields.c
@@ -183,5 +183,5 @@  const AVFilter ff_vf_repeatfields = {
     .uninit        = uninit,
     FILTER_INPUTS(repeatfields_inputs),
     FILTER_OUTPUTS(repeatfields_outputs),
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c
index c74e1adff9..4f3f3959b0 100644
--- a/libavfilter/vf_rotate.c
+++ b/libavfilter/vf_rotate.c
@@ -601,10 +601,10 @@  const AVFilter ff_vf_rotate = {
     .priv_size     = sizeof(RotContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .process_command = process_command,
     FILTER_INPUTS(rotate_inputs),
     FILTER_OUTPUTS(rotate_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &rotate_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_sab.c b/libavfilter/vf_sab.c
index bc7e7e30ed..1e696fed5f 100644
--- a/libavfilter/vf_sab.c
+++ b/libavfilter/vf_sab.c
@@ -324,9 +324,9 @@  const AVFilter ff_vf_sab = {
     .priv_size     = sizeof(SabContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(sab_inputs),
     FILTER_OUTPUTS(sab_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &sab_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index a1902a13cf..5411289894 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -996,11 +996,11 @@  const AVFilter ff_vf_scale = {
     .description     = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format."),
     .init_dict       = init_dict,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ScaleContext),
     .priv_class      = &scale_class,
     FILTER_INPUTS(avfilter_vf_scale_inputs),
     FILTER_OUTPUTS(avfilter_vf_scale_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
 
@@ -1037,10 +1037,10 @@  const AVFilter ff_vf_scale2ref = {
     .description     = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format to the given reference."),
     .init_dict       = init_dict,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ScaleContext),
     .priv_class      = &scale_class,
     FILTER_INPUTS(avfilter_vf_scale2ref_inputs),
     FILTER_OUTPUTS(avfilter_vf_scale2ref_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c
index fa7b799e0e..93ff839b5a 100644
--- a/libavfilter/vf_scale_cuda.c
+++ b/libavfilter/vf_scale_cuda.c
@@ -641,7 +641,6 @@  const AVFilter ff_vf_scale_cuda = {
 
     .init          = cudascale_init,
     .uninit        = cudascale_uninit,
-    .query_formats = cudascale_query_formats,
 
     .priv_size = sizeof(CUDAScaleContext),
     .priv_class = &cudascale_class,
@@ -649,5 +648,7 @@  const AVFilter ff_vf_scale_cuda = {
     FILTER_INPUTS(cudascale_inputs),
     FILTER_OUTPUTS(cudascale_outputs),
 
+    FILTER_QUERY_FUNC(cudascale_query_formats),
+
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c
index 3e25c2c95f..11ac5ad245 100644
--- a/libavfilter/vf_scale_npp.c
+++ b/libavfilter/vf_scale_npp.c
@@ -594,7 +594,6 @@  const AVFilter ff_vf_scale_npp = {
 
     .init          = nppscale_init,
     .uninit        = nppscale_uninit,
-    .query_formats = nppscale_query_formats,
 
     .priv_size = sizeof(NPPScaleContext),
     .priv_class = &nppscale_class,
@@ -602,5 +601,7 @@  const AVFilter ff_vf_scale_npp = {
     FILTER_INPUTS(nppscale_inputs),
     FILTER_OUTPUTS(nppscale_outputs),
 
+    FILTER_QUERY_FUNC(nppscale_query_formats),
+
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c
index 5a37cef63d..ab497a9d45 100644
--- a/libavfilter/vf_scale_qsv.c
+++ b/libavfilter/vf_scale_qsv.c
@@ -671,7 +671,6 @@  const AVFilter ff_vf_scale_qsv = {
 
     .init          = qsvscale_init,
     .uninit        = qsvscale_uninit,
-    .query_formats = qsvscale_query_formats,
 
     .priv_size = sizeof(QSVScaleContext),
     .priv_class = &qsvscale_class,
@@ -679,5 +678,7 @@  const AVFilter ff_vf_scale_qsv = {
     FILTER_INPUTS(qsvscale_inputs),
     FILTER_OUTPUTS(qsvscale_outputs),
 
+    FILTER_QUERY_FUNC(qsvscale_query_formats),
+
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c
index 554b7bac4f..a371077ee0 100644
--- a/libavfilter/vf_scale_vaapi.c
+++ b/libavfilter/vf_scale_vaapi.c
@@ -285,9 +285,9 @@  const AVFilter ff_vf_scale_vaapi = {
     .priv_size     = sizeof(ScaleVAAPIContext),
     .init          = &scale_vaapi_init,
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(scale_vaapi_inputs),
     FILTER_OUTPUTS(scale_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class    = &scale_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
index 4eb4fe5664..af9677e46a 100644
--- a/libavfilter/vf_scale_vulkan.c
+++ b/libavfilter/vf_scale_vulkan.c
@@ -528,9 +528,9 @@  const AVFilter ff_vf_scale_vulkan = {
     .priv_size      = sizeof(ScaleVulkanContext),
     .init           = &ff_vk_filter_init,
     .uninit         = &scale_vulkan_uninit,
-    .query_formats  = &ff_vk_filter_query_formats,
     FILTER_INPUTS(scale_vulkan_inputs),
     FILTER_OUTPUTS(scale_vulkan_outputs),
+    FILTER_QUERY_FUNC(&ff_vk_filter_query_formats),
     .priv_class     = &scale_vulkan_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scdet.c b/libavfilter/vf_scdet.c
index b8017a00e5..a14d9c2aeb 100644
--- a/libavfilter/vf_scdet.c
+++ b/libavfilter/vf_scdet.c
@@ -211,8 +211,8 @@  const AVFilter ff_vf_scdet = {
     .priv_size     = sizeof(SCDetContext),
     .priv_class    = &scdet_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(scdet_inputs),
     FILTER_OUTPUTS(scdet_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
 };
diff --git a/libavfilter/vf_scroll.c b/libavfilter/vf_scroll.c
index 5e9cf76095..8b8e8580f7 100644
--- a/libavfilter/vf_scroll.c
+++ b/libavfilter/vf_scroll.c
@@ -211,9 +211,9 @@  const AVFilter ff_vf_scroll = {
     .description   = NULL_IF_CONFIG_SMALL("Scroll input video."),
     .priv_size     = sizeof(ScrollContext),
     .priv_class    = &scroll_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(scroll_inputs),
     FILTER_OUTPUTS(scroll_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_selectivecolor.c b/libavfilter/vf_selectivecolor.c
index 398d4bec0d..247b88117d 100644
--- a/libavfilter/vf_selectivecolor.c
+++ b/libavfilter/vf_selectivecolor.c
@@ -489,9 +489,9 @@  const AVFilter ff_vf_selectivecolor = {
     .name          = "selectivecolor",
     .description   = NULL_IF_CONFIG_SMALL("Apply CMYK adjustments to specific color ranges."),
     .priv_size     = sizeof(SelectiveColorContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(selectivecolor_inputs),
     FILTER_OUTPUTS(selectivecolor_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &selectivecolor_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_shear.c b/libavfilter/vf_shear.c
index e58084d3cd..9c291bc152 100644
--- a/libavfilter/vf_shear.c
+++ b/libavfilter/vf_shear.c
@@ -317,9 +317,9 @@  const AVFilter ff_vf_shear = {
     .description     = NULL_IF_CONFIG_SMALL("Shear transform the input image."),
     .priv_size       = sizeof(ShearContext),
     .init            = init,
-    .query_formats   = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &shear_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_showpalette.c b/libavfilter/vf_showpalette.c
index 569f5040d0..0405bdb947 100644
--- a/libavfilter/vf_showpalette.c
+++ b/libavfilter/vf_showpalette.c
@@ -114,8 +114,8 @@  const AVFilter ff_vf_showpalette = {
     .name          = "showpalette",
     .description   = NULL_IF_CONFIG_SMALL("Display frame palette."),
     .priv_size     = sizeof(ShowPaletteContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(showpalette_inputs),
     FILTER_OUTPUTS(showpalette_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &showpalette_class,
 };
diff --git a/libavfilter/vf_shufflepixels.c b/libavfilter/vf_shufflepixels.c
index aa8c726971..e89e3c027f 100644
--- a/libavfilter/vf_shufflepixels.c
+++ b/libavfilter/vf_shufflepixels.c
@@ -449,9 +449,9 @@  const AVFilter ff_vf_shufflepixels = {
     .description   = NULL_IF_CONFIG_SMALL("Shuffle video pixels."),
     .priv_size     = sizeof(ShufflePixelsContext),
     .priv_class    = &shufflepixels_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(shufflepixels_inputs),
     FILTER_OUTPUTS(shufflepixels_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_shuffleplanes.c b/libavfilter/vf_shuffleplanes.c
index 3ca4aa976d..b2f64ad076 100644
--- a/libavfilter/vf_shuffleplanes.c
+++ b/libavfilter/vf_shuffleplanes.c
@@ -165,8 +165,8 @@  const AVFilter ff_vf_shuffleplanes = {
     .description  = NULL_IF_CONFIG_SMALL("Shuffle video planes."),
     .priv_size    = sizeof(ShufflePlanesContext),
     .priv_class   = &shuffleplanes_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(shuffleplanes_inputs),
     FILTER_OUTPUTS(shuffleplanes_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags        = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 1bfa7f158d..aa54543bcf 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -1012,10 +1012,10 @@  const AVFilter ff_vf_signalstats = {
     .description   = "Generate statistics from video analysis.",
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(SignalstatsContext),
     FILTER_INPUTS(signalstats_inputs),
     FILTER_OUTPUTS(signalstats_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &signalstats_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_signature.c b/libavfilter/vf_signature.c
index 784869a7ae..03b53f9a4c 100644
--- a/libavfilter/vf_signature.c
+++ b/libavfilter/vf_signature.c
@@ -760,8 +760,8 @@  const AVFilter ff_vf_signature = {
     .priv_class    = &signature_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(signature_outputs),
     .inputs        = NULL,
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
index 24aa533fd7..6737f60c9f 100644
--- a/libavfilter/vf_smartblur.c
+++ b/libavfilter/vf_smartblur.c
@@ -292,9 +292,9 @@  const AVFilter ff_vf_smartblur = {
     .priv_size     = sizeof(SmartblurContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(smartblur_inputs),
     FILTER_OUTPUTS(smartblur_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &smartblur_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_spp.c b/libavfilter/vf_spp.c
index b9b5f7bc78..32a3c59987 100644
--- a/libavfilter/vf_spp.c
+++ b/libavfilter/vf_spp.c
@@ -501,9 +501,9 @@  const AVFilter ff_vf_spp = {
     .priv_size       = sizeof(SPPContext),
     .preinit         = preinit,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(spp_inputs),
     FILTER_OUTPUTS(spp_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
     .priv_class      = &spp_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
diff --git a/libavfilter/vf_sr.c b/libavfilter/vf_sr.c
index f4fc84d251..f528fdcad4 100644
--- a/libavfilter/vf_sr.c
+++ b/libavfilter/vf_sr.c
@@ -198,8 +198,8 @@  const AVFilter ff_vf_sr = {
     .priv_size     = sizeof(SRContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(sr_inputs),
     FILTER_OUTPUTS(sr_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &sr_class,
 };
diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c
index 14d7ab3ec6..ba0f18df8a 100644
--- a/libavfilter/vf_ssim.c
+++ b/libavfilter/vf_ssim.c
@@ -591,11 +591,11 @@  const AVFilter ff_vf_ssim = {
     .preinit       = ssim_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(SSIMContext),
     .priv_class    = &ssim_class,
     FILTER_INPUTS(ssim_inputs),
     FILTER_OUTPUTS(ssim_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
index 338154e715..f584e8349b 100644
--- a/libavfilter/vf_stack.c
+++ b/libavfilter/vf_stack.c
@@ -402,8 +402,8 @@  const AVFilter ff_vf_hstack = {
     .description   = NULL_IF_CONFIG_SMALL("Stack video inputs horizontally."),
     .priv_class    = &stack_class,
     .priv_size     = sizeof(StackContext),
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
@@ -419,8 +419,8 @@  const AVFilter ff_vf_vstack = {
     .description   = NULL_IF_CONFIG_SMALL("Stack video inputs vertically."),
     .priv_class    = &stack_class,
     .priv_size     = sizeof(StackContext),
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
@@ -446,8 +446,8 @@  const AVFilter ff_vf_xstack = {
     .description   = NULL_IF_CONFIG_SMALL("Stack video inputs into custom layout."),
     .priv_size     = sizeof(StackContext),
     .priv_class    = &xstack_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index 10aade7bd9..0ba18861af 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -1111,9 +1111,9 @@  const AVFilter ff_vf_stereo3d = {
     .description   = NULL_IF_CONFIG_SMALL("Convert video stereoscopic 3D view."),
     .priv_size     = sizeof(Stereo3DContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(stereo3d_inputs),
     FILTER_OUTPUTS(stereo3d_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &stereo3d_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index f08a7fba9d..377160c72b 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -251,9 +251,9 @@  const AVFilter ff_vf_ass = {
     .priv_size     = sizeof(AssContext),
     .init          = init_ass,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(ass_inputs),
     FILTER_OUTPUTS(ass_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &ass_class,
 };
 #endif
@@ -484,9 +484,9 @@  const AVFilter ff_vf_subtitles = {
     .priv_size     = sizeof(AssContext),
     .init          = init_subtitles,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(ass_inputs),
     FILTER_OUTPUTS(ass_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &subtitles_class,
 };
 #endif
diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c
index 3e99d53cee..11532925bb 100644
--- a/libavfilter/vf_super2xsai.c
+++ b/libavfilter/vf_super2xsai.c
@@ -359,8 +359,8 @@  const AVFilter ff_vf_super2xsai = {
     .name          = "super2xsai",
     .description   = NULL_IF_CONFIG_SMALL("Scale the input by 2x using the Super2xSaI pixel art algorithm."),
     .priv_size     = sizeof(Super2xSaIContext),
-    .query_formats = query_formats,
     FILTER_INPUTS(super2xsai_inputs),
     FILTER_OUTPUTS(super2xsai_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_swaprect.c b/libavfilter/vf_swaprect.c
index e03603fe5a..b76e3bb99d 100644
--- a/libavfilter/vf_swaprect.c
+++ b/libavfilter/vf_swaprect.c
@@ -237,10 +237,10 @@  const AVFilter ff_vf_swaprect = {
     .description   = NULL_IF_CONFIG_SMALL("Swap 2 rectangular objects in video."),
     .priv_size     = sizeof(SwapRectContext),
     .priv_class    = &swaprect_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c
index 0c285e547c..27d083f026 100644
--- a/libavfilter/vf_swapuv.c
+++ b/libavfilter/vf_swapuv.c
@@ -112,10 +112,10 @@  static const AVFilterPad swapuv_outputs[] = {
 const AVFilter ff_vf_swapuv = {
     .name          = "swapuv",
     .description   = NULL_IF_CONFIG_SMALL("Swap U and V components."),
-    .query_formats = query_formats,
     .priv_size     = sizeof(SwapUVContext),
     .priv_class    = &swapuv_class,
     FILTER_INPUTS(swapuv_inputs),
     FILTER_OUTPUTS(swapuv_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c
index eaaddf734d..e8de63bbcf 100644
--- a/libavfilter/vf_telecine.c
+++ b/libavfilter/vf_telecine.c
@@ -287,7 +287,7 @@  const AVFilter ff_vf_telecine = {
     .priv_class    = &telecine_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(telecine_inputs),
     FILTER_OUTPUTS(telecine_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c
index b6b93fef6f..65da3734b0 100644
--- a/libavfilter/vf_threshold.c
+++ b/libavfilter/vf_threshold.c
@@ -352,10 +352,10 @@  const AVFilter ff_vf_threshold = {
     .priv_size     = sizeof(ThresholdContext),
     .priv_class    = &threshold_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_thumbnail.c b/libavfilter/vf_thumbnail.c
index acfc0ce481..0d3de1afbf 100644
--- a/libavfilter/vf_thumbnail.c
+++ b/libavfilter/vf_thumbnail.c
@@ -288,9 +288,9 @@  const AVFilter ff_vf_thumbnail = {
     .priv_size     = sizeof(ThumbContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(thumbnail_inputs),
     FILTER_OUTPUTS(thumbnail_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &thumbnail_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_thumbnail_cuda.c b/libavfilter/vf_thumbnail_cuda.c
index df9bba22e0..a7a246c959 100644
--- a/libavfilter/vf_thumbnail_cuda.c
+++ b/libavfilter/vf_thumbnail_cuda.c
@@ -444,9 +444,9 @@  const AVFilter ff_vf_thumbnail_cuda = {
     .priv_size     = sizeof(ThumbnailCudaContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(thumbnail_cuda_inputs),
     FILTER_OUTPUTS(thumbnail_cuda_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &thumbnail_cuda_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c
index 13bd53bba6..ca2397fb18 100644
--- a/libavfilter/vf_tile.c
+++ b/libavfilter/vf_tile.c
@@ -288,9 +288,9 @@  const AVFilter ff_vf_tile = {
     .description   = NULL_IF_CONFIG_SMALL("Tile several successive frames together."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(TileContext),
     FILTER_INPUTS(tile_inputs),
     FILTER_OUTPUTS(tile_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &tile_class,
 };
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 7c0f00898b..91626192e0 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -555,9 +555,9 @@  const AVFilter ff_vf_tinterlace = {
     .description   = NULL_IF_CONFIG_SMALL("Perform temporal field interlacing."),
     .priv_size     = sizeof(TInterlaceContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(tinterlace_inputs),
     FILTER_OUTPUTS(tinterlace_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &tinterlace_class,
 };
 
@@ -568,8 +568,8 @@  const AVFilter ff_vf_interlace = {
     .priv_size     = sizeof(TInterlaceContext),
     .init          = init_interlace,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(tinterlace_inputs),
     FILTER_OUTPUTS(tinterlace_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &interlace_class,
 };
diff --git a/libavfilter/vf_tmidequalizer.c b/libavfilter/vf_tmidequalizer.c
index cf9fcf9047..96b12f11a7 100644
--- a/libavfilter/vf_tmidequalizer.c
+++ b/libavfilter/vf_tmidequalizer.c
@@ -430,9 +430,9 @@  const AVFilter ff_vf_tmidequalizer = {
     .description   = NULL_IF_CONFIG_SMALL("Apply Temporal Midway Equalization."),
     .priv_size     = sizeof(TMidEqualizerContext),
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(tmidequalizer_inputs),
     FILTER_OUTPUTS(tmidequalizer_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &tmidequalizer_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c
index 8ea54ecafb..51f56c7386 100644
--- a/libavfilter/vf_tonemap.c
+++ b/libavfilter/vf_tonemap.c
@@ -337,10 +337,10 @@  const AVFilter ff_vf_tonemap = {
     .name            = "tonemap",
     .description     = NULL_IF_CONFIG_SMALL("Conversion to/from different dynamic ranges."),
     .init            = init,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(TonemapContext),
     .priv_class      = &tonemap_class,
     FILTER_INPUTS(tonemap_inputs),
     FILTER_OUTPUTS(tonemap_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_tonemap_opencl.c b/libavfilter/vf_tonemap_opencl.c
index f659669159..0e65f16234 100644
--- a/libavfilter/vf_tonemap_opencl.c
+++ b/libavfilter/vf_tonemap_opencl.c
@@ -544,8 +544,8 @@  const AVFilter ff_vf_tonemap_opencl = {
     .priv_class     = &tonemap_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &tonemap_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(tonemap_opencl_inputs),
     FILTER_OUTPUTS(tonemap_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_tonemap_vaapi.c b/libavfilter/vf_tonemap_vaapi.c
index a5cf9b0d8d..5a41f14d00 100644
--- a/libavfilter/vf_tonemap_vaapi.c
+++ b/libavfilter/vf_tonemap_vaapi.c
@@ -407,9 +407,9 @@  const AVFilter ff_vf_tonemap_vaapi = {
     .priv_size      = sizeof(HDRVAAPIContext),
     .init           = &tonemap_vaapi_init,
     .uninit         = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats  = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(tonemap_vaapi_inputs),
     FILTER_OUTPUTS(tonemap_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class     = &tonemap_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_tpad.c b/libavfilter/vf_tpad.c
index 59b4a60d7c..e5acece1e4 100644
--- a/libavfilter/vf_tpad.c
+++ b/libavfilter/vf_tpad.c
@@ -208,9 +208,9 @@  const AVFilter ff_vf_tpad = {
     .description   = NULL_IF_CONFIG_SMALL("Temporarily pad video frames."),
     .priv_size     = sizeof(TPadContext),
     .priv_class    = &tpad_class,
-    .query_formats = query_formats,
     .activate      = activate,
     .uninit        = uninit,
     FILTER_INPUTS(tpad_inputs),
     FILTER_OUTPUTS(tpad_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 9ed132fc0f..b0354b938f 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -401,8 +401,8 @@  const AVFilter ff_vf_transpose = {
     .description   = NULL_IF_CONFIG_SMALL("Transpose input video."),
     .priv_size     = sizeof(TransContext),
     .priv_class    = &transpose_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_transpose_inputs),
     FILTER_OUTPUTS(avfilter_vf_transpose_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_transpose_npp.c b/libavfilter/vf_transpose_npp.c
index 14b9d62488..b05c07f29d 100644
--- a/libavfilter/vf_transpose_npp.c
+++ b/libavfilter/vf_transpose_npp.c
@@ -475,10 +475,10 @@  const AVFilter ff_vf_transpose_npp = {
     .description    = NULL_IF_CONFIG_SMALL("NVIDIA Performance Primitives video transpose"),
     .init           = npptranspose_init,
     .uninit         = npptranspose_uninit,
-    .query_formats  = npptranspose_query_formats,
     .priv_size      = sizeof(NPPTransposeContext),
     .priv_class     = &npptranspose_class,
     FILTER_INPUTS(npptranspose_inputs),
     FILTER_OUTPUTS(npptranspose_outputs),
+    FILTER_QUERY_FUNC(npptranspose_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_transpose_opencl.c b/libavfilter/vf_transpose_opencl.c
index 05e7aa19e0..c275a7d08e 100644
--- a/libavfilter/vf_transpose_opencl.c
+++ b/libavfilter/vf_transpose_opencl.c
@@ -277,8 +277,8 @@  const AVFilter ff_vf_transpose_opencl = {
     .priv_class     = &transpose_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &transpose_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(transpose_opencl_inputs),
     FILTER_OUTPUTS(transpose_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_transpose_vaapi.c b/libavfilter/vf_transpose_vaapi.c
index f0d356da71..5f1829dd05 100644
--- a/libavfilter/vf_transpose_vaapi.c
+++ b/libavfilter/vf_transpose_vaapi.c
@@ -276,9 +276,9 @@  const AVFilter ff_vf_transpose_vaapi = {
     .priv_size      = sizeof(TransposeVAAPIContext),
     .init           = &transpose_vaapi_init,
     .uninit         = &ff_vaapi_vpp_ctx_uninit,
-    .query_formats  = &ff_vaapi_vpp_query_formats,
     FILTER_INPUTS(transpose_vaapi_inputs),
     FILTER_OUTPUTS(transpose_vaapi_outputs),
+    FILTER_QUERY_FUNC(&ff_vaapi_vpp_query_formats),
     .priv_class     = &transpose_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index b413133e41..85182910f6 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -359,8 +359,8 @@  const AVFilter ff_vf_unsharp = {
     .priv_class    = &unsharp_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_unsharp_inputs),
     FILTER_OUTPUTS(avfilter_vf_unsharp_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_unsharp_opencl.c b/libavfilter/vf_unsharp_opencl.c
index 129611c70d..d8c0c8dc3b 100644
--- a/libavfilter/vf_unsharp_opencl.c
+++ b/libavfilter/vf_unsharp_opencl.c
@@ -403,8 +403,8 @@  const AVFilter ff_vf_unsharp_opencl = {
     .priv_class     = &unsharp_opencl_class,
     .init           = &ff_opencl_filter_init,
     .uninit         = &unsharp_opencl_uninit,
-    .query_formats  = &ff_opencl_filter_query_formats,
     FILTER_INPUTS(unsharp_opencl_inputs),
     FILTER_OUTPUTS(unsharp_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_untile.c b/libavfilter/vf_untile.c
index 85e1d56d2b..5d7709d68c 100644
--- a/libavfilter/vf_untile.c
+++ b/libavfilter/vf_untile.c
@@ -182,10 +182,10 @@  const AVFilter ff_vf_untile = {
     .description   = NULL_IF_CONFIG_SMALL("Untile a frame into a sequence of frames."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     .priv_size     = sizeof(UntileContext),
     FILTER_INPUTS(untile_inputs),
     FILTER_OUTPUTS(untile_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &untile_class,
 };
diff --git a/libavfilter/vf_uspp.c b/libavfilter/vf_uspp.c
index ba6ae816a8..d9022b1053 100644
--- a/libavfilter/vf_uspp.c
+++ b/libavfilter/vf_uspp.c
@@ -494,9 +494,9 @@  const AVFilter ff_vf_uspp = {
     .description     = NULL_IF_CONFIG_SMALL("Apply Ultra Simple / Slow Post-processing filter."),
     .priv_size       = sizeof(USPPContext),
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(uspp_inputs),
     FILTER_OUTPUTS(uspp_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class      = &uspp_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index 6d65127db5..25456ac9f4 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -4997,9 +4997,9 @@  const AVFilter ff_vf_v360 = {
     .priv_size     = sizeof(V360Context),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &v360_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_vaguedenoiser.c b/libavfilter/vf_vaguedenoiser.c
index ea23067110..cfb532ccb7 100644
--- a/libavfilter/vf_vaguedenoiser.c
+++ b/libavfilter/vf_vaguedenoiser.c
@@ -612,8 +612,8 @@  const AVFilter ff_vf_vaguedenoiser = {
     .priv_class    = &vaguedenoiser_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(vaguedenoiser_inputs),
     FILTER_OUTPUTS(vaguedenoiser_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_vectorscope.c b/libavfilter/vf_vectorscope.c
index b8b406430c..2aec091572 100644
--- a/libavfilter/vf_vectorscope.c
+++ b/libavfilter/vf_vectorscope.c
@@ -1590,8 +1590,8 @@  const AVFilter ff_vf_vectorscope = {
     .description   = NULL_IF_CONFIG_SMALL("Video vectorscope."),
     .priv_size     = sizeof(VectorscopeContext),
     .priv_class    = &vectorscope_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_vibrance.c b/libavfilter/vf_vibrance.c
index 7253ebd594..b1f9ecba52 100644
--- a/libavfilter/vf_vibrance.c
+++ b/libavfilter/vf_vibrance.c
@@ -375,9 +375,9 @@  const AVFilter ff_vf_vibrance = {
     .description   = NULL_IF_CONFIG_SMALL("Boost or alter saturation."),
     .priv_size     = sizeof(VibranceContext),
     .priv_class    = &vibrance_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(vibrance_inputs),
     FILTER_OUTPUTS(vibrance_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_vidstabdetect.c b/libavfilter/vf_vidstabdetect.c
index 5e12d31d0e..278d0f15a6 100644
--- a/libavfilter/vf_vidstabdetect.c
+++ b/libavfilter/vf_vidstabdetect.c
@@ -210,8 +210,8 @@  const AVFilter ff_vf_vidstabdetect = {
     .priv_size     = sizeof(StabData),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_vidstabdetect_inputs),
     FILTER_OUTPUTS(avfilter_vf_vidstabdetect_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &vidstabdetect_class,
 };
diff --git a/libavfilter/vf_vidstabtransform.c b/libavfilter/vf_vidstabtransform.c
index 3499b9afe4..70fe552b59 100644
--- a/libavfilter/vf_vidstabtransform.c
+++ b/libavfilter/vf_vidstabtransform.c
@@ -311,8 +311,8 @@  const AVFilter ff_vf_vidstabtransform = {
     .priv_size     = sizeof(TransformContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_vidstabtransform_inputs),
     FILTER_OUTPUTS(avfilter_vf_vidstabtransform_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &vidstabtransform_class,
 };
diff --git a/libavfilter/vf_vif.c b/libavfilter/vf_vif.c
index ee7c67337d..01851a01bc 100644
--- a/libavfilter/vf_vif.c
+++ b/libavfilter/vf_vif.c
@@ -637,11 +637,11 @@  const AVFilter ff_vf_vif = {
     .name          = "vif",
     .description   = NULL_IF_CONFIG_SMALL("Calculate the VIF between two video streams."),
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(VIFContext),
     .priv_class    = &vif_class,
     .activate      = activate,
     FILTER_INPUTS(vif_inputs),
     FILTER_OUTPUTS(vif_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_vignette.c b/libavfilter/vf_vignette.c
index 8e9f196ab9..27772d469c 100644
--- a/libavfilter/vf_vignette.c
+++ b/libavfilter/vf_vignette.c
@@ -342,9 +342,9 @@  const AVFilter ff_vf_vignette = {
     .priv_size     = sizeof(VignetteContext),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(vignette_inputs),
     FILTER_OUTPUTS(vignette_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .priv_class    = &vignette_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_vmafmotion.c b/libavfilter/vf_vmafmotion.c
index 67cc012b18..362839735e 100644
--- a/libavfilter/vf_vmafmotion.c
+++ b/libavfilter/vf_vmafmotion.c
@@ -361,9 +361,9 @@  const AVFilter ff_vf_vmafmotion = {
     .description   = NULL_IF_CONFIG_SMALL("Calculate the VMAF Motion score."),
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .priv_size     = sizeof(VMAFMotionContext),
     .priv_class    = &vmafmotion_class,
     FILTER_INPUTS(vmafmotion_inputs),
     FILTER_OUTPUTS(vmafmotion_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index 22ffe0d7f3..ab58a5777e 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -614,11 +614,11 @@  const AVFilter ff_vf_vpp_qsv = {
     .name          = "vpp_qsv",
     .description   = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."),
     .priv_size     = sizeof(VPPContext),
-    .query_formats = query_formats,
     .init          = vpp_init,
     .uninit        = vpp_uninit,
     FILTER_INPUTS(vpp_inputs),
     FILTER_OUTPUTS(vpp_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
     .priv_class    = &vpp_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c
index 9d073e9c34..46f1435582 100644
--- a/libavfilter/vf_w3fdif.c
+++ b/libavfilter/vf_w3fdif.c
@@ -615,9 +615,9 @@  const AVFilter ff_vf_w3fdif = {
     .priv_size     = sizeof(W3FDIFContext),
     .priv_class    = &w3fdif_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(w3fdif_inputs),
     FILTER_OUTPUTS(w3fdif_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_waveform.c b/libavfilter/vf_waveform.c
index 431740705b..33a3ac08d3 100644
--- a/libavfilter/vf_waveform.c
+++ b/libavfilter/vf_waveform.c
@@ -3518,9 +3518,9 @@  const AVFilter ff_vf_waveform = {
     .description   = NULL_IF_CONFIG_SMALL("Video waveform monitor."),
     .priv_size     = sizeof(WaveformContext),
     .priv_class    = &waveform_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c
index 52fb4c684d..2bd3994e5e 100644
--- a/libavfilter/vf_weave.c
+++ b/libavfilter/vf_weave.c
@@ -187,10 +187,10 @@  const AVFilter ff_vf_weave = {
     .description   = NULL_IF_CONFIG_SMALL("Weave input video fields into frames."),
     .priv_size     = sizeof(WeaveContext),
     .priv_class    = &weave_class,
-    .query_formats = query_formats,
     .uninit        = uninit,
     FILTER_INPUTS(weave_inputs),
     FILTER_OUTPUTS(weave_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
 
@@ -209,10 +209,10 @@  const AVFilter ff_vf_doubleweave = {
     .description   = NULL_IF_CONFIG_SMALL("Weave input video fields into double number of frames."),
     .priv_class    = &weave_class,
     .priv_size     = sizeof(WeaveContext),
-    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     FILTER_INPUTS(weave_inputs),
     FILTER_OUTPUTS(weave_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_xbr.c b/libavfilter/vf_xbr.c
index bb7b704abb..c799284566 100644
--- a/libavfilter/vf_xbr.c
+++ b/libavfilter/vf_xbr.c
@@ -425,7 +425,7 @@  const AVFilter ff_vf_xbr = {
     .description   = NULL_IF_CONFIG_SMALL("Scale the input using xBR algorithm."),
     FILTER_INPUTS(xbr_inputs),
     FILTER_OUTPUTS(xbr_outputs),
-    .query_formats = query_formats,
+    FILTER_QUERY_FUNC(query_formats),
     .priv_size     = sizeof(XBRContext),
     .priv_class    = &xbr_class,
     .init          = init,
diff --git a/libavfilter/vf_xfade.c b/libavfilter/vf_xfade.c
index b4edcbf1b4..d5506a44a8 100644
--- a/libavfilter/vf_xfade.c
+++ b/libavfilter/vf_xfade.c
@@ -2001,10 +2001,10 @@  const AVFilter ff_vf_xfade = {
     .description   = NULL_IF_CONFIG_SMALL("Cross fade one video with another video."),
     .priv_size     = sizeof(XFadeContext),
     .priv_class    = &xfade_class,
-    .query_formats = query_formats,
     .activate      = xfade_activate,
     .uninit        = uninit,
     FILTER_INPUTS(xfade_inputs),
     FILTER_OUTPUTS(xfade_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_xfade_opencl.c b/libavfilter/vf_xfade_opencl.c
index c24528eb89..f8d90a483f 100644
--- a/libavfilter/vf_xfade_opencl.c
+++ b/libavfilter/vf_xfade_opencl.c
@@ -428,9 +428,9 @@  const AVFilter ff_vf_xfade_opencl = {
     .priv_class      = &xfade_opencl_class,
     .init            = &ff_opencl_filter_init,
     .uninit          = &xfade_opencl_uninit,
-    .query_formats   = &ff_opencl_filter_query_formats,
     .activate        = &xfade_opencl_activate,
     FILTER_INPUTS(xfade_opencl_inputs),
     FILTER_OUTPUTS(xfade_opencl_outputs),
+    FILTER_QUERY_FUNC(&ff_opencl_filter_query_formats),
     .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_xmedian.c b/libavfilter/vf_xmedian.c
index a9e3255a2a..2ae4132b44 100644
--- a/libavfilter/vf_xmedian.c
+++ b/libavfilter/vf_xmedian.c
@@ -395,8 +395,8 @@  const AVFilter ff_vf_xmedian = {
     .description   = NULL_IF_CONFIG_SMALL("Pick median pixels from several video inputs."),
     .priv_size     = sizeof(XMedianContext),
     .priv_class    = &xmedian_class,
-    .query_formats = query_formats,
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .preinit       = xmedian_framesync_preinit,
     .init          = xmedian_init,
     .uninit        = uninit,
@@ -478,9 +478,9 @@  const AVFilter ff_vf_tmedian = {
     .description   = NULL_IF_CONFIG_SMALL("Pick median pixels from successive frames."),
     .priv_size     = sizeof(XMedianContext),
     .priv_class    = &tmedian_class,
-    .query_formats = query_formats,
     FILTER_INPUTS(tmedian_inputs),
     FILTER_OUTPUTS(tmedian_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .init          = init,
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 8b71e0584d..26d457360a 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -354,8 +354,8 @@  const AVFilter ff_vf_yadif = {
     .priv_size     = sizeof(YADIFContext),
     .priv_class    = &yadif_class,
     .uninit        = uninit,
-    .query_formats = query_formats,
     FILTER_INPUTS(avfilter_vf_yadif_inputs),
     FILTER_OUTPUTS(avfilter_vf_yadif_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_yadif_cuda.c b/libavfilter/vf_yadif_cuda.c
index 5ddb9a9324..da1ab5a8ff 100644
--- a/libavfilter/vf_yadif_cuda.c
+++ b/libavfilter/vf_yadif_cuda.c
@@ -380,9 +380,9 @@  const AVFilter ff_vf_yadif_cuda = {
     .priv_size      = sizeof(DeintCUDAContext),
     .priv_class     = &yadif_cuda_class,
     .uninit         = deint_cuda_uninit,
-    .query_formats  = deint_cuda_query_formats,
     FILTER_INPUTS(deint_cuda_inputs),
     FILTER_OUTPUTS(deint_cuda_outputs),
+    FILTER_QUERY_FUNC(deint_cuda_query_formats),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_yaepblur.c b/libavfilter/vf_yaepblur.c
index c4e4a1f82d..ed48e20c2d 100644
--- a/libavfilter/vf_yaepblur.c
+++ b/libavfilter/vf_yaepblur.c
@@ -342,9 +342,9 @@  const AVFilter ff_vf_yaepblur = {
     .priv_size       = sizeof(YAEPContext),
     .priv_class      = &yaepblur_class,
     .uninit          = uninit,
-    .query_formats   = query_formats,
     FILTER_INPUTS(yaep_inputs),
     FILTER_OUTPUTS(yaep_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_zoompan.c b/libavfilter/vf_zoompan.c
index 92769f1fd1..58155bc162 100644
--- a/libavfilter/vf_zoompan.c
+++ b/libavfilter/vf_zoompan.c
@@ -378,8 +378,8 @@  const AVFilter ff_vf_zoompan = {
     .priv_class    = &zoompan_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .activate      = activate,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c
index 495545fa52..3f7dba489a 100644
--- a/libavfilter/vf_zscale.c
+++ b/libavfilter/vf_zscale.c
@@ -939,11 +939,11 @@  const AVFilter ff_vf_zscale = {
     .name            = "zscale",
     .description     = NULL_IF_CONFIG_SMALL("Apply resizing, colorspace and bit depth conversion."),
     .init            = init,
-    .query_formats   = query_formats,
     .priv_size       = sizeof(ZScaleContext),
     .priv_class      = &zscale_class,
     .uninit          = uninit,
     FILTER_INPUTS(avfilter_vf_zscale_inputs),
     FILTER_OUTPUTS(avfilter_vf_zscale_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .process_command = process_command,
 };
diff --git a/libavfilter/vsrc_cellauto.c b/libavfilter/vsrc_cellauto.c
index b22e8be836..8f6e02c82d 100644
--- a/libavfilter/vsrc_cellauto.c
+++ b/libavfilter/vsrc_cellauto.c
@@ -330,7 +330,7 @@  const AVFilter ff_vsrc_cellauto = {
     .priv_class    = &cellauto_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(cellauto_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vsrc_gradients.c b/libavfilter/vsrc_gradients.c
index 863cfe9b5e..5563d832d9 100644
--- a/libavfilter/vsrc_gradients.c
+++ b/libavfilter/vsrc_gradients.c
@@ -299,9 +299,9 @@  const AVFilter ff_vsrc_gradients = {
     .description   = NULL_IF_CONFIG_SMALL("Draw a gradients."),
     .priv_size     = sizeof(GradientsContext),
     .priv_class    = &gradients_class,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(gradients_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .activate      = activate,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vsrc_life.c b/libavfilter/vsrc_life.c
index 2165d1a70f..38df2a6a57 100644
--- a/libavfilter/vsrc_life.c
+++ b/libavfilter/vsrc_life.c
@@ -445,7 +445,7 @@  const AVFilter ff_vsrc_life = {
     .priv_class    = &life_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(life_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vsrc_mandelbrot.c b/libavfilter/vsrc_mandelbrot.c
index df8584b37c..cf7da01506 100644
--- a/libavfilter/vsrc_mandelbrot.c
+++ b/libavfilter/vsrc_mandelbrot.c
@@ -422,7 +422,7 @@  const AVFilter ff_vsrc_mandelbrot = {
     .priv_class    = &mandelbrot_class,
     .init          = init,
     .uninit        = uninit,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(mandelbrot_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vsrc_mptestsrc.c b/libavfilter/vsrc_mptestsrc.c
index f94a78fb84..329af1fe21 100644
--- a/libavfilter/vsrc_mptestsrc.c
+++ b/libavfilter/vsrc_mptestsrc.c
@@ -359,7 +359,7 @@  const AVFilter ff_vsrc_mptestsrc = {
     .priv_size     = sizeof(MPTestContext),
     .priv_class    = &mptestsrc_class,
     .init          = init,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(mptestsrc_outputs),
+    FILTER_QUERY_FUNC(query_formats),
 };
diff --git a/libavfilter/vsrc_sierpinski.c b/libavfilter/vsrc_sierpinski.c
index d3d136f7ae..a26542be42 100644
--- a/libavfilter/vsrc_sierpinski.c
+++ b/libavfilter/vsrc_sierpinski.c
@@ -225,8 +225,8 @@  const AVFilter ff_vsrc_sierpinski = {
     .description   = NULL_IF_CONFIG_SMALL("Render a Sierpinski fractal."),
     .priv_size     = sizeof(SierpinskiContext),
     .priv_class    = &sierpinski_class,
-    .query_formats = query_formats,
     .inputs        = NULL,
     FILTER_OUTPUTS(sierpinski_outputs),
+    FILTER_QUERY_FUNC(query_formats),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 414950c442..72d3fd4456 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -273,9 +273,9 @@  const AVFilter ff_vsrc_color = {
     .init            = color_init,
     .uninit          = uninit,
     .activate        = activate,
-    .query_formats   = color_query_formats,
     .inputs          = NULL,
     FILTER_OUTPUTS(color_outputs),
+    FILTER_QUERY_FUNC(color_query_formats),
     .process_command = color_process_command,
 };
 
@@ -402,10 +402,10 @@  const AVFilter ff_vsrc_haldclutsrc = {
     .priv_size     = sizeof(TestSourceContext),
     .init          = haldclutsrc_init,
     .uninit        = uninit,
-    .query_formats = haldclutsrc_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(haldclutsrc_outputs),
+    FILTER_QUERY_FUNC(haldclutsrc_query_formats),
 };
 #endif /* CONFIG_HALDCLUTSRC_FILTER */
 
@@ -670,10 +670,10 @@  const AVFilter ff_vsrc_testsrc = {
     .priv_class    = &testsrc_class,
     .init          = test_init,
     .uninit        = uninit,
-    .query_formats = test_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_testsrc_outputs),
+    FILTER_QUERY_FUNC(test_query_formats),
 };
 
 #endif /* CONFIG_TESTSRC_FILTER */
@@ -942,10 +942,10 @@  const AVFilter ff_vsrc_testsrc2 = {
     .priv_class    = &testsrc2_class,
     .init          = test2_init,
     .uninit        = uninit,
-    .query_formats = test2_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_testsrc2_outputs),
+    FILTER_QUERY_FUNC(test2_query_formats),
 };
 
 #endif /* CONFIG_TESTSRC2_FILTER */
@@ -1113,10 +1113,10 @@  const AVFilter ff_vsrc_rgbtestsrc = {
     .priv_class    = &rgbtestsrc_class,
     .init          = rgbtest_init,
     .uninit        = uninit,
-    .query_formats = rgbtest_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_rgbtestsrc_outputs),
+    FILTER_QUERY_FUNC(rgbtest_query_formats),
 };
 
 #endif /* CONFIG_RGBTESTSRC_FILTER */
@@ -1282,10 +1282,10 @@  const AVFilter ff_vsrc_yuvtestsrc = {
     .priv_class    = &nullsrc_yuvtestsrc_class,
     .init          = yuvtest_init,
     .uninit        = uninit,
-    .query_formats = yuvtest_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_yuvtestsrc_outputs),
+    FILTER_QUERY_FUNC(yuvtest_query_formats),
 };
 
 #endif /* CONFIG_YUVTESTSRC_FILTER */
@@ -1454,10 +1454,10 @@  const AVFilter ff_vsrc_pal75bars = {
     .priv_size     = sizeof(TestSourceContext),
     .init          = pal75bars_init,
     .uninit        = uninit,
-    .query_formats = smptebars_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(smptebars_outputs),
+    FILTER_QUERY_FUNC(smptebars_query_formats),
 };
 
 #endif  /* CONFIG_PAL75BARS_FILTER */
@@ -1498,10 +1498,10 @@  const AVFilter ff_vsrc_pal100bars = {
     .priv_size     = sizeof(TestSourceContext),
     .init          = pal100bars_init,
     .uninit        = uninit,
-    .query_formats = smptebars_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(smptebars_outputs),
+    FILTER_QUERY_FUNC(smptebars_query_formats),
 };
 
 #endif  /* CONFIG_PAL100BARS_FILTER */
@@ -1565,10 +1565,10 @@  const AVFilter ff_vsrc_smptebars = {
     .priv_class    = &smptebars_class,
     .init          = smptebars_init,
     .uninit        = uninit,
-    .query_formats = smptebars_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(smptebars_outputs),
+    FILTER_QUERY_FUNC(smptebars_query_formats),
 };
 
 #endif  /* CONFIG_SMPTEBARS_FILTER */
@@ -1668,10 +1668,10 @@  const AVFilter ff_vsrc_smptehdbars = {
     .priv_size     = sizeof(TestSourceContext),
     .init          = smptehdbars_init,
     .uninit        = uninit,
-    .query_formats = smptebars_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(smptebars_outputs),
+    FILTER_QUERY_FUNC(smptebars_query_formats),
 };
 
 #endif  /* CONFIG_SMPTEHDBARS_FILTER */
@@ -1742,10 +1742,10 @@  const AVFilter ff_vsrc_allyuv = {
     .priv_class    = &allyuv_allrgb_class,
     .init          = allyuv_init,
     .uninit        = uninit,
-    .query_formats = allyuv_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_allyuv_outputs),
+    FILTER_QUERY_FUNC(allyuv_query_formats),
 };
 
 #endif /* CONFIG_ALLYUV_FILTER */
@@ -1812,10 +1812,10 @@  const AVFilter ff_vsrc_allrgb = {
     .priv_class    = &allyuv_allrgb_class,
     .init          = allrgb_init,
     .uninit        = uninit,
-    .query_formats = allrgb_query_formats,
     .activate      = activate,
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_vsrc_allrgb_outputs),
+    FILTER_QUERY_FUNC(allrgb_query_formats),
 };
 
 #endif /* CONFIG_ALLRGB_FILTER */