diff --git a/libavfilter/aeval.c b/libavfilter/aeval.c
index 007758bf57..b6906454a6 100644
--- a/libavfilter/aeval.c
+++ b/libavfilter/aeval.c
@@ -318,7 +318,6 @@ static const AVFilterPad aevalsrc_outputs[] = {
         .config_props  = config_props,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_aevalsrc = {
@@ -330,6 +329,7 @@ const AVFilter ff_asrc_aevalsrc = {
     .priv_size     = sizeof(EvalContext),
     .inputs        = NULL,
     .outputs       = aevalsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aevalsrc_outputs),
     .priv_class    = &aevalsrc_class,
 };
 
@@ -460,7 +460,6 @@ static const AVFilterPad aeval_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad aeval_outputs[] = {
@@ -469,7 +468,6 @@ static const AVFilterPad aeval_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = aeval_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aeval = {
@@ -480,7 +478,9 @@ const AVFilter ff_af_aeval = {
     .uninit        = uninit,
     .priv_size     = sizeof(EvalContext),
     .inputs        = aeval_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(aeval_inputs),
     .outputs       = aeval_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aeval_outputs),
     .priv_class    = &aeval_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_acontrast.c b/libavfilter/af_acontrast.c
index 69fe6b7e22..b1eab4e187 100644
--- a/libavfilter/af_acontrast.c
+++ b/libavfilter/af_acontrast.c
@@ -197,7 +197,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -205,7 +204,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acontrast = {
@@ -215,5 +213,7 @@ const AVFilter ff_af_acontrast = {
     .priv_size      = sizeof(AudioContrastContext),
     .priv_class     = &acontrast_class,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/af_acopy.c b/libavfilter/af_acopy.c
index 29551996d9..022a3a4dcc 100644
--- a/libavfilter/af_acopy.c
+++ b/libavfilter/af_acopy.c
@@ -51,7 +51,6 @@ static const AVFilterPad acopy_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad acopy_outputs[] = {
@@ -59,12 +58,13 @@ static const AVFilterPad acopy_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acopy = {
     .name          = "acopy",
     .description   = NULL_IF_CONFIG_SMALL("Copy the input audio unchanged to the output."),
     .inputs        = acopy_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(acopy_inputs),
     .outputs       = acopy_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(acopy_outputs),
 };
diff --git a/libavfilter/af_acrossover.c b/libavfilter/af_acrossover.c
index 3ba67b30e1..5687f74380 100644
--- a/libavfilter/af_acrossover.c
+++ b/libavfilter/af_acrossover.c
@@ -566,7 +566,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acrossover = {
@@ -578,6 +577,7 @@ const AVFilter ff_af_acrossover = {
     .uninit         = uninit,
     .query_formats  = query_formats,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = NULL,
     .flags          = AVFILTER_FLAG_DYNAMIC_OUTPUTS |
                       AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/af_acrusher.c b/libavfilter/af_acrusher.c
index ce337013ab..5213980e6d 100644
--- a/libavfilter/af_acrusher.c
+++ b/libavfilter/af_acrusher.c
@@ -353,7 +353,6 @@ static const AVFilterPad avfilter_af_acrusher_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_acrusher_outputs[] = {
@@ -361,7 +360,6 @@ static const AVFilterPad avfilter_af_acrusher_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acrusher = {
@@ -372,6 +370,8 @@ const AVFilter ff_af_acrusher = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_af_acrusher_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_af_acrusher_inputs),
     .outputs       = avfilter_af_acrusher_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_acrusher_outputs),
     .process_command = process_command,
 };
diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c
index 798838f522..89afa72f88 100644
--- a/libavfilter/af_adeclick.c
+++ b/libavfilter/af_adeclick.c
@@ -751,7 +751,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -759,7 +758,6 @@ static const AVFilterPad outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_adeclick = {
@@ -772,7 +770,9 @@ const AVFilter ff_af_adeclick = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
 
@@ -808,6 +808,8 @@ const AVFilter ff_af_adeclip = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_adelay.c b/libavfilter/af_adelay.c
index c6450cb2b9..c7b165b4ed 100644
--- a/libavfilter/af_adelay.c
+++ b/libavfilter/af_adelay.c
@@ -339,7 +339,6 @@ static const AVFilterPad adelay_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad adelay_outputs[] = {
@@ -347,7 +346,6 @@ static const AVFilterPad adelay_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_adelay = {
@@ -359,6 +357,8 @@ const AVFilter ff_af_adelay = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = adelay_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(adelay_inputs),
     .outputs       = adelay_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(adelay_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_adenorm.c b/libavfilter/af_adenorm.c
index ee8d26ee73..fed7268174 100644
--- a/libavfilter/af_adenorm.c
+++ b/libavfilter/af_adenorm.c
@@ -291,7 +291,6 @@ static const AVFilterPad adenorm_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad adenorm_outputs[] = {
@@ -300,7 +299,6 @@ static const AVFilterPad adenorm_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ADenormContext, x)
@@ -324,7 +322,9 @@ const AVFilter ff_af_adenorm = {
     .query_formats   = query_formats,
     .priv_size       = sizeof(ADenormContext),
     .inputs          = adenorm_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(adenorm_inputs),
     .outputs         = adenorm_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(adenorm_outputs),
     .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 6b3e4dd0e4..1f53146d7d 100644
--- a/libavfilter/af_aderivative.c
+++ b/libavfilter/af_aderivative.c
@@ -175,7 +175,6 @@ static const AVFilterPad aderivative_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad aderivative_outputs[] = {
@@ -183,7 +182,6 @@ static const AVFilterPad aderivative_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aderivative = {
@@ -193,7 +191,9 @@ const AVFilter ff_af_aderivative = {
     .priv_size     = sizeof(ADerivativeContext),
     .uninit        = uninit,
     .inputs        = aderivative_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(aderivative_inputs),
     .outputs       = aderivative_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aderivative_outputs),
 };
 
 const AVFilter ff_af_aintegral = {
@@ -203,5 +203,7 @@ const AVFilter ff_af_aintegral = {
     .priv_size     = sizeof(ADerivativeContext),
     .uninit        = uninit,
     .inputs        = aderivative_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(aderivative_inputs),
     .outputs       = aderivative_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aderivative_outputs),
 };
diff --git a/libavfilter/af_aecho.c b/libavfilter/af_aecho.c
index 4e45ab9a8b..67f92b5ad8 100644
--- a/libavfilter/af_aecho.c
+++ b/libavfilter/af_aecho.c
@@ -364,7 +364,6 @@ static const AVFilterPad aecho_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad aecho_outputs[] = {
@@ -373,7 +372,6 @@ static const AVFilterPad aecho_outputs[] = {
         .config_props  = config_output,
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aecho = {
@@ -386,5 +384,7 @@ const AVFilter ff_af_aecho = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = aecho_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(aecho_inputs),
     .outputs       = aecho_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aecho_outputs),
 };
diff --git a/libavfilter/af_aemphasis.c b/libavfilter/af_aemphasis.c
index 66fe7036fa..d423ea94d6 100644
--- a/libavfilter/af_aemphasis.c
+++ b/libavfilter/af_aemphasis.c
@@ -389,7 +389,6 @@ static const AVFilterPad avfilter_af_aemphasis_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_aemphasis_outputs[] = {
@@ -397,7 +396,6 @@ static const AVFilterPad avfilter_af_aemphasis_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aemphasis = {
@@ -408,7 +406,9 @@ const AVFilter ff_af_aemphasis = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_af_aemphasis_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_af_aemphasis_inputs),
     .outputs       = avfilter_af_aemphasis_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_aemphasis_outputs),
     .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 e7f72cca38..f9bee525b3 100644
--- a/libavfilter/af_aexciter.c
+++ b/libavfilter/af_aexciter.c
@@ -292,7 +292,6 @@ static const AVFilterPad avfilter_af_aexciter_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_aexciter_outputs[] = {
@@ -300,7 +299,6 @@ static const AVFilterPad avfilter_af_aexciter_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aexciter = {
@@ -311,7 +309,9 @@ const AVFilter ff_af_aexciter = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_af_aexciter_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_af_aexciter_inputs),
     .outputs       = avfilter_af_aexciter_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_aexciter_outputs),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index b22432f2e7..a74359327f 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -353,7 +353,6 @@ static const AVFilterPad avfilter_af_afade_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_afade_outputs[] = {
@@ -362,7 +361,6 @@ static const AVFilterPad avfilter_af_afade_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_afade = {
@@ -372,7 +370,9 @@ const AVFilter ff_af_afade = {
     .priv_size     = sizeof(AudioFadeContext),
     .init          = init,
     .inputs        = avfilter_af_afade_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_af_afade_inputs),
     .outputs       = avfilter_af_afade_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_afade_outputs),
     .priv_class    = &afade_class,
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
@@ -641,7 +641,6 @@ static const AVFilterPad avfilter_af_acrossfade_inputs[] = {
         .name         = "crossfade1",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_acrossfade_outputs[] = {
@@ -650,7 +649,6 @@ static const AVFilterPad avfilter_af_acrossfade_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = acrossfade_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acrossfade = {
@@ -661,7 +659,9 @@ const AVFilter ff_af_acrossfade = {
     .activate      = activate,
     .priv_class    = &acrossfade_class,
     .inputs        = avfilter_af_acrossfade_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_acrossfade_inputs),
     .outputs       = avfilter_af_acrossfade_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_acrossfade_outputs),
 };
 
 #endif /* CONFIG_ACROSSFADE_FILTER */
diff --git a/libavfilter/af_afftdn.c b/libavfilter/af_afftdn.c
index 693585439b..69c7335341 100644
--- a/libavfilter/af_afftdn.c
+++ b/libavfilter/af_afftdn.c
@@ -1412,7 +1412,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1420,7 +1419,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_afftdn = {
@@ -1432,7 +1430,9 @@ const AVFilter ff_af_afftdn = {
     .activate        = activate,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 877ccc5be0..4ea3e8667b 100644
--- a/libavfilter/af_afftfilt.c
+++ b/libavfilter/af_afftfilt.c
@@ -479,7 +479,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -487,7 +486,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_afftfilt = {
@@ -496,7 +494,9 @@ const AVFilter ff_af_afftfilt = {
     .priv_size       = sizeof(AFFTFiltContext),
     .priv_class      = &afftfilt_class,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .activate        = activate,
     .query_formats   = query_formats,
     .uninit          = uninit,
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index e9cc4738fd..9395f7bf9d 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -146,7 +146,6 @@ static const AVFilterPad avfilter_af_aformat_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_aformat_outputs[] = {
@@ -154,7 +153,6 @@ static const AVFilterPad avfilter_af_aformat_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aformat = {
@@ -166,5 +164,7 @@ const AVFilter ff_af_aformat = {
     .priv_size     = sizeof(AFormatContext),
     .priv_class    = &aformat_class,
     .inputs        = avfilter_af_aformat_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_aformat_inputs),
     .outputs       = avfilter_af_aformat_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_aformat_outputs),
 };
diff --git a/libavfilter/af_afreqshift.c b/libavfilter/af_afreqshift.c
index 85a1e65a96..9fcccabf13 100644
--- a/libavfilter/af_afreqshift.c
+++ b/libavfilter/af_afreqshift.c
@@ -379,7 +379,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -387,7 +386,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_afreqshift = {
@@ -398,7 +396,9 @@ const AVFilter ff_af_afreqshift = {
     .priv_class      = &afreqshift_class,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = ff_filter_process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -420,7 +420,9 @@ const AVFilter ff_af_aphaseshift = {
     .priv_class      = &aphaseshift_class,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 a23bb902ea..48ebafc744 100644
--- a/libavfilter/af_afwtdn.c
+++ b/libavfilter/af_afwtdn.c
@@ -1323,7 +1323,6 @@ static const AVFilterPad inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1332,7 +1331,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_afwtdn = {
@@ -1344,7 +1342,9 @@ const AVFilter ff_af_afwtdn = {
     .activate        = activate,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c
index 3c858021d1..b7ef6c697f 100644
--- a/libavfilter/af_agate.c
+++ b/libavfilter/af_agate.c
@@ -248,7 +248,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = agate_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -256,7 +255,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_agate = {
@@ -266,7 +264,9 @@ const AVFilter ff_af_agate = {
     .priv_size      = sizeof(AudioGateContext),
     .priv_class     = &agate_class,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = ff_filter_process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -424,7 +424,6 @@ static const AVFilterPad sidechaingate_inputs[] = {
         .name           = "sidechain",
         .type           = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad sidechaingate_outputs[] = {
@@ -433,7 +432,6 @@ static const AVFilterPad sidechaingate_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = scconfig_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_sidechaingate = {
@@ -445,7 +443,9 @@ const AVFilter ff_af_sidechaingate = {
     .activate       = activate,
     .uninit         = uninit,
     .inputs         = sidechaingate_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(sidechaingate_inputs),
     .outputs        = sidechaingate_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(sidechaingate_outputs),
     .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 6ac39872ef..3875f144b2 100644
--- a/libavfilter/af_aiir.c
+++ b/libavfilter/af_aiir.c
@@ -1528,7 +1528,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(AudioIIRContext, x)
@@ -1585,6 +1584,7 @@ const AVFilter ff_af_aiir = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS |
                      AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_alimiter.c b/libavfilter/af_alimiter.c
index 30f1a4cba5..8c43785bb0 100644
--- a/libavfilter/af_alimiter.c
+++ b/libavfilter/af_alimiter.c
@@ -350,7 +350,6 @@ static const AVFilterPad alimiter_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad alimiter_outputs[] = {
@@ -358,7 +357,6 @@ static const AVFilterPad alimiter_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_alimiter = {
@@ -370,5 +368,7 @@ const AVFilter ff_af_alimiter = {
     .uninit         = uninit,
     .query_formats  = query_formats,
     .inputs         = alimiter_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(alimiter_inputs),
     .outputs        = alimiter_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(alimiter_outputs),
 };
diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c
index 2e45b7c277..3c04438dac 100644
--- a/libavfilter/af_amerge.c
+++ b/libavfilter/af_amerge.c
@@ -344,7 +344,6 @@ static const AVFilterPad amerge_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_amerge = {
@@ -358,6 +357,7 @@ const AVFilter ff_af_amerge = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = amerge_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(amerge_outputs),
     .priv_class    = &amerge_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index 2296b49243..04374db146 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -634,7 +634,6 @@ static const AVFilterPad avfilter_af_amix_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_amix = {
@@ -648,6 +647,7 @@ const AVFilter ff_af_amix = {
     .query_formats  = query_formats,
     .inputs         = NULL,
     .outputs        = avfilter_af_amix_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_amix_outputs),
     .process_command = process_command,
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_amultiply.c b/libavfilter/af_amultiply.c
index b50bbfb6ce..da78d19c59 100644
--- a/libavfilter/af_amultiply.c
+++ b/libavfilter/af_amultiply.c
@@ -192,7 +192,6 @@ static const AVFilterPad inputs[] = {
         .name = "multiply1",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -201,7 +200,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_amultiply = {
@@ -213,5 +211,7 @@ const AVFilter ff_af_amultiply = {
     .activate       = activate,
     .query_formats  = query_formats,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/af_anequalizer.c b/libavfilter/af_anequalizer.c
index faa0e2a230..f61ee6c648 100644
--- a/libavfilter/af_anequalizer.c
+++ b/libavfilter/af_anequalizer.c
@@ -761,7 +761,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame   = filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_anequalizer = {
@@ -773,6 +772,7 @@ const AVFilter ff_af_anequalizer = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = NULL,
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS |
diff --git a/libavfilter/af_anlmdn.c b/libavfilter/af_anlmdn.c
index 05e84282f0..ac117ccd9d 100644
--- a/libavfilter/af_anlmdn.c
+++ b/libavfilter/af_anlmdn.c
@@ -400,7 +400,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -410,7 +409,6 @@ static const AVFilterPad outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_anlmdn = {
@@ -421,7 +419,9 @@ const AVFilter ff_af_anlmdn = {
     .priv_class    = &anlmdn_class,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 26df40107f..510751463a 100644
--- a/libavfilter/af_anlms.c
+++ b/libavfilter/af_anlms.c
@@ -301,7 +301,6 @@ static const AVFilterPad inputs[] = {
         .name = "desired",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -310,7 +309,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_anlms = {
@@ -323,7 +321,9 @@ const AVFilter ff_af_anlms = {
     .activate       = activate,
     .query_formats  = query_formats,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .flags          = AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index 74f915778f..eda47d7296 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -32,7 +32,6 @@ static const AVFilterPad avfilter_af_anull_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_anull_outputs[] = {
@@ -40,12 +39,13 @@ static const AVFilterPad avfilter_af_anull_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_anull = {
     .name          = "anull",
     .description   = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
     .inputs        = avfilter_af_anull_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_anull_inputs),
     .outputs       = avfilter_af_anull_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_anull_outputs),
 };
diff --git a/libavfilter/af_apad.c b/libavfilter/af_apad.c
index 8628c0c2e2..bd9329a013 100644
--- a/libavfilter/af_apad.c
+++ b/libavfilter/af_apad.c
@@ -155,7 +155,6 @@ static const AVFilterPad apad_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad apad_outputs[] = {
@@ -165,7 +164,6 @@ static const AVFilterPad apad_outputs[] = {
         .config_props  = config_output,
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_apad = {
@@ -174,7 +172,9 @@ const AVFilter ff_af_apad = {
     .init          = init,
     .priv_size     = sizeof(APadContext),
     .inputs        = apad_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(apad_inputs),
     .outputs       = apad_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(apad_outputs),
     .priv_class    = &apad_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_aphaser.c b/libavfilter/af_aphaser.c
index e033a6d904..588d304552 100644
--- a/libavfilter/af_aphaser.c
+++ b/libavfilter/af_aphaser.c
@@ -278,7 +278,6 @@ static const AVFilterPad aphaser_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad aphaser_outputs[] = {
@@ -287,7 +286,6 @@ static const AVFilterPad aphaser_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aphaser = {
@@ -298,6 +296,8 @@ const AVFilter ff_af_aphaser = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = aphaser_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(aphaser_inputs),
     .outputs       = aphaser_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aphaser_outputs),
     .priv_class    = &aphaser_class,
 };
diff --git a/libavfilter/af_apulsator.c b/libavfilter/af_apulsator.c
index 56ff4579d6..eb61e5f173 100644
--- a/libavfilter/af_apulsator.c
+++ b/libavfilter/af_apulsator.c
@@ -236,7 +236,6 @@ static const AVFilterPad inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -244,7 +243,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_apulsator = {
@@ -254,5 +252,7 @@ const AVFilter ff_af_apulsator = {
     .priv_class    = &apulsator_class,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index 1127ad2718..4fd5c1287c 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -329,7 +329,6 @@ static const AVFilterPad aresample_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad aresample_outputs[] = {
@@ -339,7 +338,6 @@ static const AVFilterPad aresample_outputs[] = {
         .request_frame = request_frame,
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aresample = {
@@ -351,5 +349,7 @@ const AVFilter ff_af_aresample = {
     .priv_size     = sizeof(AResampleContext),
     .priv_class    = &aresample_class,
     .inputs        = aresample_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(aresample_inputs),
     .outputs       = aresample_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aresample_outputs),
 };
diff --git a/libavfilter/af_arnndn.c b/libavfilter/af_arnndn.c
index 0c70a32271..d081209266 100644
--- a/libavfilter/af_arnndn.c
+++ b/libavfilter/af_arnndn.c
@@ -1596,7 +1596,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1604,7 +1603,6 @@ static const AVFilterPad outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(AudioRNNContext, x)
@@ -1629,7 +1627,9 @@ const AVFilter ff_af_arnndn = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/af_asetnsamples.c b/libavfilter/af_asetnsamples.c
index 9987eff8a2..82d7cc7beb 100644
--- a/libavfilter/af_asetnsamples.c
+++ b/libavfilter/af_asetnsamples.c
@@ -106,7 +106,6 @@ static const AVFilterPad asetnsamples_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad asetnsamples_outputs[] = {
@@ -114,7 +113,6 @@ static const AVFilterPad asetnsamples_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asetnsamples = {
@@ -123,6 +121,8 @@ const AVFilter ff_af_asetnsamples = {
     .priv_size   = sizeof(ASNSContext),
     .priv_class  = &asetnsamples_class,
     .inputs      = asetnsamples_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(asetnsamples_inputs),
     .outputs     = asetnsamples_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(asetnsamples_outputs),
     .activate    = activate,
 };
diff --git a/libavfilter/af_asetrate.c b/libavfilter/af_asetrate.c
index f89185d936..379654c0d2 100644
--- a/libavfilter/af_asetrate.c
+++ b/libavfilter/af_asetrate.c
@@ -94,7 +94,6 @@ static const AVFilterPad asetrate_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad asetrate_outputs[] = {
@@ -103,7 +102,6 @@ static const AVFilterPad asetrate_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asetrate = {
@@ -113,6 +111,8 @@ const AVFilter ff_af_asetrate = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ASetRateContext),
     .inputs        = asetrate_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(asetrate_inputs),
     .outputs       = asetrate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(asetrate_outputs),
     .priv_class    = &asetrate_class,
 };
diff --git a/libavfilter/af_ashowinfo.c b/libavfilter/af_ashowinfo.c
index 72d795f8ee..53192e62df 100644
--- a/libavfilter/af_ashowinfo.c
+++ b/libavfilter/af_ashowinfo.c
@@ -243,7 +243,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -251,7 +250,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_ashowinfo = {
@@ -260,5 +258,7 @@ const AVFilter ff_af_ashowinfo = {
     .priv_size   = sizeof(AShowInfoContext),
     .uninit      = uninit,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/af_asoftclip.c b/libavfilter/af_asoftclip.c
index 17361ba3a2..942bb02456 100644
--- a/libavfilter/af_asoftclip.c
+++ b/libavfilter/af_asoftclip.c
@@ -463,7 +463,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -471,7 +470,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asoftclip = {
@@ -481,7 +479,9 @@ const AVFilter ff_af_asoftclip = {
     .priv_size      = sizeof(ASoftClipContext),
     .priv_class     = &asoftclip_class,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 b34cdd38ee..fd277c033d 100644
--- a/libavfilter/af_asr.c
+++ b/libavfilter/af_asr.c
@@ -156,7 +156,6 @@ static const AVFilterPad asr_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad asr_outputs[] = {
@@ -164,7 +163,6 @@ static const AVFilterPad asr_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asr = {
@@ -176,5 +174,7 @@ const AVFilter ff_af_asr = {
     .uninit        = asr_uninit,
     .query_formats = query_formats,
     .inputs        = asr_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(asr_inputs),
     .outputs       = asr_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(asr_outputs),
 };
diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c
index 23a5785d5a..0c821ac67a 100644
--- a/libavfilter/af_astats.c
+++ b/libavfilter/af_astats.c
@@ -827,7 +827,6 @@ static const AVFilterPad astats_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad astats_outputs[] = {
@@ -836,7 +835,6 @@ static const AVFilterPad astats_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_astats = {
@@ -847,6 +845,8 @@ const AVFilter ff_af_astats = {
     .priv_class    = &astats_class,
     .uninit        = uninit,
     .inputs        = astats_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(astats_inputs),
     .outputs       = astats_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(astats_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_asubboost.c b/libavfilter/af_asubboost.c
index f36ce81552..f5f88c0ba4 100644
--- a/libavfilter/af_asubboost.c
+++ b/libavfilter/af_asubboost.c
@@ -233,7 +233,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -241,7 +240,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asubboost = {
@@ -252,7 +250,9 @@ const AVFilter ff_af_asubboost = {
     .priv_class     = &asubboost_class,
     .uninit         = uninit,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 54921cf4c3..bbc341a310 100644
--- a/libavfilter/af_asupercut.c
+++ b/libavfilter/af_asupercut.c
@@ -357,7 +357,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -365,7 +364,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asupercut = {
@@ -376,7 +374,9 @@ const AVFilter ff_af_asupercut = {
     .priv_class      = &asupercut_class,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -399,7 +399,9 @@ const AVFilter ff_af_asubcut = {
     .priv_class      = &asubcut_class,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -424,7 +426,9 @@ const AVFilter ff_af_asuperpass = {
     .priv_class      = &asuperpass_class,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
@@ -441,7 +445,9 @@ const AVFilter ff_af_asuperstop = {
     .priv_class      = &asuperstop_class,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 80a33c43ed..d410ac9513 100644
--- a/libavfilter/af_atempo.c
+++ b/libavfilter/af_atempo.c
@@ -1190,7 +1190,6 @@ static const AVFilterPad atempo_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad atempo_outputs[] = {
@@ -1199,7 +1198,6 @@ static const AVFilterPad atempo_outputs[] = {
         .request_frame = request_frame,
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_atempo = {
@@ -1212,5 +1210,7 @@ const AVFilter ff_af_atempo = {
     .priv_size       = sizeof(ATempoContext),
     .priv_class      = &atempo_class,
     .inputs          = atempo_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(atempo_inputs),
     .outputs         = atempo_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(atempo_outputs),
 };
diff --git a/libavfilter/af_axcorrelate.c b/libavfilter/af_axcorrelate.c
index cec39dee76..04f76f8ef2 100644
--- a/libavfilter/af_axcorrelate.c
+++ b/libavfilter/af_axcorrelate.c
@@ -339,7 +339,6 @@ static const AVFilterPad inputs[] = {
         .name = "axcorrelate1",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -348,7 +347,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
@@ -373,5 +371,7 @@ const AVFilter ff_af_axcorrelate = {
     .activate       = activate,
     .uninit         = uninit,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c
index 0baf5541fd..efef5e8115 100644
--- a/libavfilter/af_biquads.c
+++ b/libavfilter/af_biquads.c
@@ -853,7 +853,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -862,7 +861,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(BiquadsContext, x)
@@ -886,7 +884,9 @@ const AVFilter ff_af_##name_ = {                               \
     .uninit        = uninit,                             \
     .query_formats = query_formats,                      \
     .inputs        = inputs,                             \
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),           \
     .outputs       = outputs,                            \
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),          \
     .priv_class    = &name_##_class,                     \
     .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 7b9958325f..9552649ceb 100644
--- a/libavfilter/af_bs2b.c
+++ b/libavfilter/af_bs2b.c
@@ -199,7 +199,6 @@ static const AVFilterPad bs2b_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad bs2b_outputs[] = {
@@ -208,7 +207,6 @@ static const AVFilterPad bs2b_outputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .config_props   = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_bs2b = {
@@ -220,5 +218,7 @@ const AVFilter ff_af_bs2b = {
     .init           = init,
     .uninit         = uninit,
     .inputs         = bs2b_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(bs2b_inputs),
     .outputs        = bs2b_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(bs2b_outputs),
 };
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index 3cdf8b2bd8..6fa2335203 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -387,7 +387,6 @@ static const AVFilterPad avfilter_af_channelmap_inputs[] = {
         .config_props   = channelmap_config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_channelmap_outputs[] = {
@@ -395,7 +394,6 @@ static const AVFilterPad avfilter_af_channelmap_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO
     },
-    { NULL }
 };
 
 const AVFilter ff_af_channelmap = {
@@ -406,5 +404,7 @@ const AVFilter ff_af_channelmap = {
     .priv_size     = sizeof(ChannelMapContext),
     .priv_class    = &channelmap_class,
     .inputs        = avfilter_af_channelmap_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_channelmap_inputs),
     .outputs       = avfilter_af_channelmap_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_channelmap_outputs),
 };
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index 3bd3355d88..63a86e8106 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -165,7 +165,6 @@ static const AVFilterPad avfilter_af_channelsplit_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_channelsplit = {
@@ -176,6 +175,7 @@ const AVFilter ff_af_channelsplit = {
     .init           = init,
     .query_formats  = query_formats,
     .inputs         = avfilter_af_channelsplit_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(avfilter_af_channelsplit_inputs),
     .outputs        = NULL,
     .flags          = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/af_chorus.c b/libavfilter/af_chorus.c
index 72e684bd3a..7d636af778 100644
--- a/libavfilter/af_chorus.c
+++ b/libavfilter/af_chorus.c
@@ -356,7 +356,6 @@ static const AVFilterPad chorus_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad chorus_outputs[] = {
@@ -366,7 +365,6 @@ static const AVFilterPad chorus_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_chorus = {
@@ -378,5 +376,7 @@ const AVFilter ff_af_chorus = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = chorus_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(chorus_inputs),
     .outputs       = chorus_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(chorus_outputs),
 };
diff --git a/libavfilter/af_compand.c b/libavfilter/af_compand.c
index 62d9c2e941..0b1319ce8a 100644
--- a/libavfilter/af_compand.c
+++ b/libavfilter/af_compand.c
@@ -571,7 +571,6 @@ static const AVFilterPad compand_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad compand_outputs[] = {
@@ -581,7 +580,6 @@ static const AVFilterPad compand_outputs[] = {
         .config_props  = config_output,
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 
@@ -595,5 +593,7 @@ const AVFilter ff_af_compand = {
     .init           = init,
     .uninit         = uninit,
     .inputs         = compand_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(compand_inputs),
     .outputs        = compand_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(compand_outputs),
 };
diff --git a/libavfilter/af_compensationdelay.c b/libavfilter/af_compensationdelay.c
index f2e0dcd467..88f3f6eaaa 100644
--- a/libavfilter/af_compensationdelay.c
+++ b/libavfilter/af_compensationdelay.c
@@ -175,7 +175,6 @@ static const AVFilterPad compensationdelay_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad compensationdelay_outputs[] = {
@@ -183,7 +182,6 @@ static const AVFilterPad compensationdelay_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_compensationdelay = {
@@ -194,5 +192,7 @@ const AVFilter ff_af_compensationdelay = {
     .priv_class    = &compensationdelay_class,
     .uninit        = uninit,
     .inputs        = compensationdelay_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(compensationdelay_inputs),
     .outputs       = compensationdelay_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(compensationdelay_outputs),
 };
diff --git a/libavfilter/af_crossfeed.c b/libavfilter/af_crossfeed.c
index 7ad9c4f483..e37bfe45f5 100644
--- a/libavfilter/af_crossfeed.c
+++ b/libavfilter/af_crossfeed.c
@@ -164,7 +164,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -172,7 +171,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_crossfeed = {
@@ -182,7 +180,9 @@ const AVFilter ff_af_crossfeed = {
     .priv_size      = sizeof(CrossfeedContext),
     .priv_class     = &crossfeed_class,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = process_command,
 };
diff --git a/libavfilter/af_crystalizer.c b/libavfilter/af_crystalizer.c
index f4ad326ede..71b1d10f07 100644
--- a/libavfilter/af_crystalizer.c
+++ b/libavfilter/af_crystalizer.c
@@ -445,7 +445,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -453,7 +452,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_crystalizer = {
@@ -464,7 +462,9 @@ const AVFilter ff_af_crystalizer = {
     .priv_class     = &crystalizer_class,
     .uninit         = uninit,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 1384ad87bf..e2e12a218d 100644
--- a/libavfilter/af_dcshift.c
+++ b/libavfilter/af_dcshift.c
@@ -149,7 +149,6 @@ static const AVFilterPad dcshift_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad dcshift_outputs[] = {
@@ -157,7 +156,6 @@ static const AVFilterPad dcshift_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_dcshift = {
@@ -168,6 +166,8 @@ const AVFilter ff_af_dcshift = {
     .priv_class     = &dcshift_class,
     .init           = init,
     .inputs         = dcshift_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(dcshift_inputs),
     .outputs        = dcshift_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(dcshift_outputs),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/af_deesser.c b/libavfilter/af_deesser.c
index e05ee9f10b..e4455c81b1 100644
--- a/libavfilter/af_deesser.c
+++ b/libavfilter/af_deesser.c
@@ -220,7 +220,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -228,7 +227,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_deesser = {
@@ -239,6 +237,8 @@ const AVFilter ff_af_deesser = {
     .priv_class    = &deesser_class,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_drmeter.c b/libavfilter/af_drmeter.c
index 58932fe6c5..9e046f1a6a 100644
--- a/libavfilter/af_drmeter.c
+++ b/libavfilter/af_drmeter.c
@@ -214,7 +214,6 @@ static const AVFilterPad drmeter_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad drmeter_outputs[] = {
@@ -223,7 +222,6 @@ static const AVFilterPad drmeter_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_drmeter = {
@@ -234,5 +232,7 @@ const AVFilter ff_af_drmeter = {
     .priv_class    = &drmeter_class,
     .uninit        = uninit,
     .inputs        = drmeter_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(drmeter_inputs),
     .outputs       = drmeter_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(drmeter_outputs),
 };
diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c
index 01c99788af..021e41ee41 100644
--- a/libavfilter/af_dynaudnorm.c
+++ b/libavfilter/af_dynaudnorm.c
@@ -857,7 +857,6 @@ static const AVFilterPad avfilter_af_dynaudnorm_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_dynaudnorm_outputs[] = {
@@ -865,7 +864,6 @@ static const AVFilterPad avfilter_af_dynaudnorm_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_dynaudnorm = {
@@ -877,7 +875,9 @@ const AVFilter ff_af_dynaudnorm = {
     .uninit        = uninit,
     .activate      = activate,
     .inputs        = avfilter_af_dynaudnorm_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_af_dynaudnorm_inputs),
     .outputs       = avfilter_af_dynaudnorm_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_dynaudnorm_outputs),
     .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 a5a7e6a5d2..7133c3defb 100644
--- a/libavfilter/af_earwax.c
+++ b/libavfilter/af_earwax.c
@@ -220,7 +220,6 @@ static const AVFilterPad earwax_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad earwax_outputs[] = {
@@ -228,7 +227,6 @@ static const AVFilterPad earwax_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_earwax = {
@@ -238,5 +236,7 @@ const AVFilter ff_af_earwax = {
     .priv_size      = sizeof(EarwaxContext),
     .uninit         = uninit,
     .inputs         = earwax_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(earwax_inputs),
     .outputs        = earwax_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(earwax_outputs),
 };
diff --git a/libavfilter/af_extrastereo.c b/libavfilter/af_extrastereo.c
index 0555aa6610..3b3f4d1aa4 100644
--- a/libavfilter/af_extrastereo.c
+++ b/libavfilter/af_extrastereo.c
@@ -109,7 +109,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -117,7 +116,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_extrastereo = {
@@ -127,7 +125,9 @@ const AVFilter ff_af_extrastereo = {
     .priv_size      = sizeof(ExtraStereoContext),
     .priv_class     = &extrastereo_class,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
     .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 77de69e3ef..bc3f918c6e 100644
--- a/libavfilter/af_firequalizer.c
+++ b/libavfilter/af_firequalizer.c
@@ -957,7 +957,6 @@ static const AVFilterPad firequalizer_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad firequalizer_outputs[] = {
@@ -966,7 +965,6 @@ static const AVFilterPad firequalizer_outputs[] = {
         .request_frame  = request_frame,
         .type           = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_firequalizer = {
@@ -977,6 +975,8 @@ const AVFilter ff_af_firequalizer = {
     .process_command    = process_command,
     .priv_size          = sizeof(FIREqualizerContext),
     .inputs             = firequalizer_inputs,
+    .nb_inputs          = FF_ARRAY_ELEMS(firequalizer_inputs),
     .outputs            = firequalizer_outputs,
+    .nb_outputs         = FF_ARRAY_ELEMS(firequalizer_outputs),
     .priv_class         = &firequalizer_class,
 };
diff --git a/libavfilter/af_flanger.c b/libavfilter/af_flanger.c
index 6984ab12d3..183e5d39ed 100644
--- a/libavfilter/af_flanger.c
+++ b/libavfilter/af_flanger.c
@@ -222,7 +222,6 @@ static const AVFilterPad flanger_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad flanger_outputs[] = {
@@ -230,7 +229,6 @@ static const AVFilterPad flanger_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_flanger = {
@@ -242,5 +240,7 @@ const AVFilter ff_af_flanger = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = flanger_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(flanger_inputs),
     .outputs       = flanger_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(flanger_outputs),
 };
diff --git a/libavfilter/af_haas.c b/libavfilter/af_haas.c
index b1a207f808..d339491421 100644
--- a/libavfilter/af_haas.c
+++ b/libavfilter/af_haas.c
@@ -205,7 +205,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -213,7 +212,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_haas = {
@@ -224,5 +222,7 @@ const AVFilter ff_af_haas = {
     .priv_class     = &haas_class,
     .uninit         = uninit,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index 144c0d31ed..f5eacc127b 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1762,7 +1762,6 @@ static const AVFilterPad avfilter_af_hdcd_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_hdcd_outputs[] = {
@@ -1770,7 +1769,6 @@ static const AVFilterPad avfilter_af_hdcd_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_hdcd = {
@@ -1782,5 +1780,7 @@ const AVFilter ff_af_hdcd = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_af_hdcd_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_hdcd_inputs),
     .outputs       = avfilter_af_hdcd_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_hdcd_outputs),
 };
diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c
index 5e8fadb6cd..9b2f62c379 100644
--- a/libavfilter/af_headphone.c
+++ b/libavfilter/af_headphone.c
@@ -762,7 +762,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_headphone = {
@@ -776,5 +775,6 @@ const AVFilter ff_af_headphone = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index 6a4b449021..269f34a043 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -536,7 +536,6 @@ static const AVFilterPad avfilter_af_join_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = join_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_join = {
@@ -551,5 +550,6 @@ const AVFilter ff_af_join = {
     .query_formats  = join_query_formats,
     .inputs         = NULL,
     .outputs        = avfilter_af_join_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(avfilter_af_join_outputs),
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_ladspa.c b/libavfilter/af_ladspa.c
index 4060251670..d9e55bfc8f 100644
--- a/libavfilter/af_ladspa.c
+++ b/libavfilter/af_ladspa.c
@@ -788,7 +788,6 @@ static const AVFilterPad ladspa_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_ladspa = {
@@ -802,5 +801,6 @@ const AVFilter ff_af_ladspa = {
     .process_command = process_command,
     .inputs        = 0,
     .outputs       = ladspa_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(ladspa_outputs),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_loudnorm.c b/libavfilter/af_loudnorm.c
index a07e8a3c93..f57e51990b 100644
--- a/libavfilter/af_loudnorm.c
+++ b/libavfilter/af_loudnorm.c
@@ -905,7 +905,6 @@ static const AVFilterPad avfilter_af_loudnorm_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_loudnorm_outputs[] = {
@@ -914,7 +913,6 @@ static const AVFilterPad avfilter_af_loudnorm_outputs[] = {
         .request_frame = request_frame,
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_loudnorm = {
@@ -926,5 +924,7 @@ const AVFilter ff_af_loudnorm = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = avfilter_af_loudnorm_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_loudnorm_inputs),
     .outputs       = avfilter_af_loudnorm_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_loudnorm_outputs),
 };
diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c
index 28b729691d..71677da07c 100644
--- a/libavfilter/af_lv2.c
+++ b/libavfilter/af_lv2.c
@@ -584,7 +584,6 @@ static const AVFilterPad lv2_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_lv2 = {
@@ -597,5 +596,6 @@ const AVFilter ff_af_lv2 = {
     .query_formats = query_formats,
     .inputs        = 0,
     .outputs       = lv2_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(lv2_outputs),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_mcompand.c b/libavfilter/af_mcompand.c
index 08d93f8c6a..27793e5967 100644
--- a/libavfilter/af_mcompand.c
+++ b/libavfilter/af_mcompand.c
@@ -651,7 +651,6 @@ static const AVFilterPad mcompand_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad mcompand_outputs[] = {
@@ -661,7 +660,6 @@ static const AVFilterPad mcompand_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 
@@ -674,5 +672,7 @@ const AVFilter ff_af_mcompand = {
     .priv_class     = &mcompand_class,
     .uninit         = uninit,
     .inputs         = mcompand_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(mcompand_inputs),
     .outputs        = mcompand_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(mcompand_outputs),
 };
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index 7ae18e9bfe..116be53c4f 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -437,7 +437,6 @@ static const AVFilterPad pan_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad pan_outputs[] = {
@@ -445,7 +444,6 @@ static const AVFilterPad pan_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_pan = {
@@ -457,5 +455,7 @@ const AVFilter ff_af_pan = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = pan_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(pan_inputs),
     .outputs       = pan_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(pan_outputs),
 };
diff --git a/libavfilter/af_replaygain.c b/libavfilter/af_replaygain.c
index fd642297f8..aa56ff4a71 100644
--- a/libavfilter/af_replaygain.c
+++ b/libavfilter/af_replaygain.c
@@ -592,7 +592,6 @@ static const AVFilterPad replaygain_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad replaygain_outputs[] = {
@@ -600,7 +599,6 @@ static const AVFilterPad replaygain_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_replaygain = {
@@ -610,5 +608,7 @@ const AVFilter ff_af_replaygain = {
     .uninit        = uninit,
     .priv_size     = sizeof(ReplayGainContext),
     .inputs        = replaygain_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(replaygain_inputs),
     .outputs       = replaygain_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(replaygain_outputs),
 };
diff --git a/libavfilter/af_rubberband.c b/libavfilter/af_rubberband.c
index bfacbcd245..cff0f85797 100644
--- a/libavfilter/af_rubberband.c
+++ b/libavfilter/af_rubberband.c
@@ -223,7 +223,6 @@ static const AVFilterPad rubberband_inputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad rubberband_outputs[] = {
@@ -231,7 +230,6 @@ static const AVFilterPad rubberband_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_rubberband = {
@@ -243,6 +241,8 @@ const AVFilter ff_af_rubberband = {
     .uninit        = uninit,
     .activate      = activate,
     .inputs        = rubberband_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(rubberband_inputs),
     .outputs       = rubberband_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(rubberband_outputs),
     .process_command = process_command,
 };
diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c
index 71e27d4530..1f1a3a1623 100644
--- a/libavfilter/af_sidechaincompress.c
+++ b/libavfilter/af_sidechaincompress.c
@@ -374,7 +374,6 @@ static const AVFilterPad sidechaincompress_inputs[] = {
         .name           = "sidechain",
         .type           = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad sidechaincompress_outputs[] = {
@@ -383,7 +382,6 @@ static const AVFilterPad sidechaincompress_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_sidechaincompress = {
@@ -395,7 +393,9 @@ const AVFilter ff_af_sidechaincompress = {
     .activate       = activate,
     .uninit         = uninit,
     .inputs         = sidechaincompress_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(sidechaincompress_inputs),
     .outputs        = sidechaincompress_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(sidechaincompress_outputs),
     .process_command = process_command,
 };
 #endif  /* CONFIG_SIDECHAINCOMPRESS_FILTER */
@@ -470,7 +470,6 @@ static const AVFilterPad acompressor_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = acompressor_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad acompressor_outputs[] = {
@@ -479,7 +478,6 @@ static const AVFilterPad acompressor_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = compressor_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acompressor = {
@@ -489,7 +487,9 @@ const AVFilter ff_af_acompressor = {
     .priv_class     = &acompressor_class,
     .query_formats  = acompressor_query_formats,
     .inputs         = acompressor_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(acompressor_inputs),
     .outputs        = acompressor_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(acompressor_outputs),
     .process_command = process_command,
 };
 #endif  /* CONFIG_ACOMPRESSOR_FILTER */
diff --git a/libavfilter/af_silencedetect.c b/libavfilter/af_silencedetect.c
index 53f54d1834..82bc7325f7 100644
--- a/libavfilter/af_silencedetect.c
+++ b/libavfilter/af_silencedetect.c
@@ -247,7 +247,6 @@ static const AVFilterPad silencedetect_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad silencedetect_outputs[] = {
@@ -255,7 +254,6 @@ static const AVFilterPad silencedetect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_silencedetect = {
@@ -265,6 +263,8 @@ const AVFilter ff_af_silencedetect = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = silencedetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(silencedetect_inputs),
     .outputs       = silencedetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(silencedetect_outputs),
     .priv_class    = &silencedetect_class,
 };
diff --git a/libavfilter/af_silenceremove.c b/libavfilter/af_silenceremove.c
index 9d6d683688..8ba373dc15 100644
--- a/libavfilter/af_silenceremove.c
+++ b/libavfilter/af_silenceremove.c
@@ -936,7 +936,6 @@ static const AVFilterPad silenceremove_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad silenceremove_outputs[] = {
@@ -945,7 +944,6 @@ static const AVFilterPad silenceremove_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_silenceremove = {
@@ -957,5 +955,7 @@ const AVFilter ff_af_silenceremove = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = silenceremove_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(silenceremove_inputs),
     .outputs       = silenceremove_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(silenceremove_outputs),
 };
diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c
index 1bffd57de9..42f7875a6a 100644
--- a/libavfilter/af_sofalizer.c
+++ b/libavfilter/af_sofalizer.c
@@ -1102,7 +1102,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1110,7 +1109,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_sofalizer = {
@@ -1123,6 +1121,8 @@ const AVFilter ff_af_sofalizer = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_speechnorm.c b/libavfilter/af_speechnorm.c
index d044177352..677d355540 100644
--- a/libavfilter/af_speechnorm.c
+++ b/libavfilter/af_speechnorm.c
@@ -555,7 +555,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -563,7 +562,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_speechnorm = {
@@ -575,6 +573,8 @@ const AVFilter ff_af_speechnorm = {
     .activate        = activate,
     .uninit          = uninit,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = process_command,
 };
diff --git a/libavfilter/af_stereotools.c b/libavfilter/af_stereotools.c
index d60fa55ccd..be743024d0 100644
--- a/libavfilter/af_stereotools.c
+++ b/libavfilter/af_stereotools.c
@@ -364,7 +364,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -372,7 +371,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_stereotools = {
@@ -383,7 +381,9 @@ const AVFilter ff_af_stereotools = {
     .priv_class     = &stereotools_class,
     .uninit         = uninit,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .process_command = process_command,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_stereowiden.c b/libavfilter/af_stereowiden.c
index 1fbb635841..27f516a46d 100644
--- a/libavfilter/af_stereowiden.c
+++ b/libavfilter/af_stereowiden.c
@@ -145,7 +145,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -153,7 +152,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_stereowiden = {
@@ -164,7 +162,9 @@ const AVFilter ff_af_stereowiden = {
     .priv_class     = &stereowiden_class,
     .uninit         = uninit,
     .inputs         = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 aa8b6376b0..eceba41482 100644
--- a/libavfilter/af_superequalizer.c
+++ b/libavfilter/af_superequalizer.c
@@ -335,7 +335,6 @@ static const AVFilterPad superequalizer_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad superequalizer_outputs[] = {
@@ -344,7 +343,6 @@ static const AVFilterPad superequalizer_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
@@ -384,5 +382,7 @@ const AVFilter ff_af_superequalizer = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = superequalizer_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(superequalizer_inputs),
     .outputs       = superequalizer_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(superequalizer_outputs),
 };
diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c
index 3fb7a1bbba..024864991a 100644
--- a/libavfilter/af_surround.c
+++ b/libavfilter/af_surround.c
@@ -1773,7 +1773,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1782,7 +1781,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_surround = {
@@ -1795,6 +1793,8 @@ const AVFilter ff_af_surround = {
     .uninit         = uninit,
     .activate       = activate,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
     .flags          = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/af_tremolo.c b/libavfilter/af_tremolo.c
index 8f9e310040..b87cad86d7 100644
--- a/libavfilter/af_tremolo.c
+++ b/libavfilter/af_tremolo.c
@@ -149,7 +149,6 @@ static const AVFilterPad avfilter_af_tremolo_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_tremolo_outputs[] = {
@@ -157,7 +156,6 @@ static const AVFilterPad avfilter_af_tremolo_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_tremolo = {
@@ -168,5 +166,7 @@ const AVFilter ff_af_tremolo = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_af_tremolo_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_tremolo_inputs),
     .outputs       = avfilter_af_tremolo_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_tremolo_outputs),
 };
diff --git a/libavfilter/af_vibrato.c b/libavfilter/af_vibrato.c
index fe4d194531..cd8a1156fe 100644
--- a/libavfilter/af_vibrato.c
+++ b/libavfilter/af_vibrato.c
@@ -187,7 +187,6 @@ static const AVFilterPad avfilter_af_vibrato_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_vibrato_outputs[] = {
@@ -195,7 +194,6 @@ static const AVFilterPad avfilter_af_vibrato_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_vibrato = {
@@ -206,5 +204,7 @@ const AVFilter ff_af_vibrato = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_af_vibrato_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_af_vibrato_inputs),
     .outputs       = avfilter_af_vibrato_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_af_vibrato_outputs),
 };
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index 844ddbeff7..b746a76e80 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -465,7 +465,6 @@ static const AVFilterPad avfilter_af_volume_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_volume_outputs[] = {
@@ -474,7 +473,6 @@ static const AVFilterPad avfilter_af_volume_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_volume = {
@@ -486,7 +484,9 @@ const AVFilter ff_af_volume = {
     .init           = init,
     .uninit         = uninit,
     .inputs         = avfilter_af_volume_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_af_volume_inputs),
     .outputs        = avfilter_af_volume_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_af_volume_outputs),
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
index 61af21797c..e15361e4bc 100644
--- a/libavfilter/af_volumedetect.c
+++ b/libavfilter/af_volumedetect.c
@@ -144,7 +144,6 @@ static const AVFilterPad volumedetect_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad volumedetect_outputs[] = {
@@ -152,7 +151,6 @@ static const AVFilterPad volumedetect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_volumedetect = {
@@ -162,5 +160,7 @@ const AVFilter ff_af_volumedetect = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = volumedetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(volumedetect_inputs),
     .outputs       = volumedetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(volumedetect_outputs),
 };
diff --git a/libavfilter/asink_anullsink.c b/libavfilter/asink_anullsink.c
index dce0204839..e0cc13630d 100644
--- a/libavfilter/asink_anullsink.c
+++ b/libavfilter/asink_anullsink.c
@@ -34,7 +34,6 @@ static const AVFilterPad avfilter_asink_anullsink_inputs[] = {
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = null_filter_frame,
     },
-    { NULL },
 };
 
 const AVFilter ff_asink_anullsink = {
@@ -42,5 +41,6 @@ const AVFilter ff_asink_anullsink = {
     .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input audio."),
     .priv_size   = 0,
     .inputs      = avfilter_asink_anullsink_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_asink_anullsink_inputs),
     .outputs     = NULL,
 };
diff --git a/libavfilter/asrc_afirsrc.c b/libavfilter/asrc_afirsrc.c
index 0ede722ba1..54a2b0fa30 100644
--- a/libavfilter/asrc_afirsrc.c
+++ b/libavfilter/asrc_afirsrc.c
@@ -315,7 +315,6 @@ static const AVFilterPad afirsrc_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_afirsrc = {
@@ -327,5 +326,6 @@ const AVFilter ff_asrc_afirsrc = {
     .priv_size     = sizeof(AudioFIRSourceContext),
     .inputs        = NULL,
     .outputs       = afirsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(afirsrc_outputs),
     .priv_class    = &afirsrc_class,
 };
diff --git a/libavfilter/asrc_anoisesrc.c b/libavfilter/asrc_anoisesrc.c
index 0aab14b58f..1af82bd849 100644
--- a/libavfilter/asrc_anoisesrc.c
+++ b/libavfilter/asrc_anoisesrc.c
@@ -244,7 +244,6 @@ static const AVFilterPad anoisesrc_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_anoisesrc = {
@@ -255,5 +254,6 @@ const AVFilter ff_asrc_anoisesrc = {
     .inputs        = NULL,
     .activate      = activate,
     .outputs       = anoisesrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(anoisesrc_outputs),
     .priv_class    = &anoisesrc_class,
 };
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 45d830e3a2..74b208276e 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -134,7 +134,6 @@ static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_anullsrc = {
@@ -145,6 +144,7 @@ const AVFilter ff_asrc_anullsrc = {
     .priv_size     = sizeof(ANullContext),
     .inputs        = NULL,
     .outputs       = avfilter_asrc_anullsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_asrc_anullsrc_outputs),
     .activate      = activate,
     .priv_class    = &anullsrc_class,
 };
diff --git a/libavfilter/asrc_flite.c b/libavfilter/asrc_flite.c
index 1478cc07fa..6095b3f972 100644
--- a/libavfilter/asrc_flite.c
+++ b/libavfilter/asrc_flite.c
@@ -271,7 +271,6 @@ static const AVFilterPad flite_outputs[] = {
         .config_props  = config_props,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_flite = {
@@ -283,5 +282,6 @@ const AVFilter ff_asrc_flite = {
     .priv_size     = sizeof(FliteContext),
     .inputs        = NULL,
     .outputs       = flite_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(flite_outputs),
     .priv_class    = &flite_class,
 };
diff --git a/libavfilter/asrc_hilbert.c b/libavfilter/asrc_hilbert.c
index e7d596ee46..b04bedcd5d 100644
--- a/libavfilter/asrc_hilbert.c
+++ b/libavfilter/asrc_hilbert.c
@@ -185,7 +185,6 @@ static const AVFilterPad hilbert_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_hilbert = {
@@ -197,5 +196,6 @@ const AVFilter ff_asrc_hilbert = {
     .priv_size     = sizeof(HilbertContext),
     .inputs        = NULL,
     .outputs       = hilbert_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(hilbert_outputs),
     .priv_class    = &hilbert_class,
 };
diff --git a/libavfilter/asrc_sinc.c b/libavfilter/asrc_sinc.c
index 5397d89c77..f7c002e48c 100644
--- a/libavfilter/asrc_sinc.c
+++ b/libavfilter/asrc_sinc.c
@@ -421,7 +421,6 @@ static const AVFilterPad sinc_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
@@ -454,4 +453,5 @@ const AVFilter ff_asrc_sinc = {
     .uninit        = uninit,
     .inputs        = NULL,
     .outputs       = sinc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(sinc_outputs),
 };
diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c
index f75a5fc728..7b95efd79d 100644
--- a/libavfilter/asrc_sine.c
+++ b/libavfilter/asrc_sine.c
@@ -266,7 +266,6 @@ static const AVFilterPad sine_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_sine = {
@@ -278,5 +277,6 @@ const AVFilter ff_asrc_sine = {
     .priv_size     = sizeof(SineContext),
     .inputs        = NULL,
     .outputs       = sine_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(sine_outputs),
     .priv_class    = &sine_class,
 };
diff --git a/libavfilter/avf_abitscope.c b/libavfilter/avf_abitscope.c
index 481a218e6e..b835c1b860 100644
--- a/libavfilter/avf_abitscope.c
+++ b/libavfilter/avf_abitscope.c
@@ -248,7 +248,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -257,7 +256,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_abitscope = {
@@ -266,7 +264,9 @@ const AVFilter ff_avf_abitscope = {
     .query_formats = query_formats,
     .priv_size     = sizeof(AudioBitScopeContext),
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .activate      = activate,
     .priv_class    = &abitscope_class,
 };
diff --git a/libavfilter/avf_ahistogram.c b/libavfilter/avf_ahistogram.c
index 864c061c2f..1c370bca13 100644
--- a/libavfilter/avf_ahistogram.c
+++ b/libavfilter/avf_ahistogram.c
@@ -412,7 +412,6 @@ static const AVFilterPad ahistogram_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad ahistogram_outputs[] = {
@@ -421,7 +420,6 @@ static const AVFilterPad ahistogram_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_ahistogram = {
@@ -432,6 +430,8 @@ const AVFilter ff_avf_ahistogram = {
     .priv_size     = sizeof(AudioHistogramContext),
     .activate      = activate,
     .inputs        = ahistogram_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ahistogram_inputs),
     .outputs       = ahistogram_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(ahistogram_outputs),
     .priv_class    = &ahistogram_class,
 };
diff --git a/libavfilter/avf_aphasemeter.c b/libavfilter/avf_aphasemeter.c
index a31805f204..7ddea3bd79 100644
--- a/libavfilter/avf_aphasemeter.c
+++ b/libavfilter/avf_aphasemeter.c
@@ -380,7 +380,6 @@ static const AVFilterPad inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_aphasemeter = {
@@ -391,6 +390,7 @@ const AVFilter ff_avf_aphasemeter = {
     .query_formats = query_formats,
     .priv_size     = sizeof(AudioPhaseMeterContext),
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = NULL,
     .priv_class    = &aphasemeter_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c
index a0011fe33b..9db86e82b0 100644
--- a/libavfilter/avf_avectorscope.c
+++ b/libavfilter/avf_avectorscope.c
@@ -403,7 +403,6 @@ static const AVFilterPad audiovectorscope_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad audiovectorscope_outputs[] = {
@@ -412,7 +411,6 @@ static const AVFilterPad audiovectorscope_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_avectorscope = {
@@ -423,6 +421,8 @@ const AVFilter ff_avf_avectorscope = {
     .priv_size     = sizeof(AudioVectorScopeContext),
     .activate      = activate,
     .inputs        = audiovectorscope_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(audiovectorscope_inputs),
     .outputs       = audiovectorscope_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(audiovectorscope_outputs),
     .priv_class    = &avectorscope_class,
 };
diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
index aa9900ebe0..b3ce81e9e2 100644
--- a/libavfilter/avf_showcqt.c
+++ b/libavfilter/avf_showcqt.c
@@ -1577,7 +1577,6 @@ static const AVFilterPad showcqt_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad showcqt_outputs[] = {
@@ -1587,7 +1586,6 @@ static const AVFilterPad showcqt_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showcqt = {
@@ -1598,6 +1596,8 @@ const AVFilter ff_avf_showcqt = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowCQTContext),
     .inputs        = showcqt_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showcqt_inputs),
     .outputs       = showcqt_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showcqt_outputs),
     .priv_class    = &showcqt_class,
 };
diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c
index 5dee3445a8..c49749f20d 100644
--- a/libavfilter/avf_showfreqs.c
+++ b/libavfilter/avf_showfreqs.c
@@ -552,7 +552,6 @@ static const AVFilterPad showfreqs_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad showfreqs_outputs[] = {
@@ -561,7 +560,6 @@ static const AVFilterPad showfreqs_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showfreqs = {
@@ -573,6 +571,8 @@ const AVFilter ff_avf_showfreqs = {
     .priv_size     = sizeof(ShowFreqsContext),
     .activate      = activate,
     .inputs        = showfreqs_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showfreqs_inputs),
     .outputs       = showfreqs_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showfreqs_outputs),
     .priv_class    = &showfreqs_class,
 };
diff --git a/libavfilter/avf_showspatial.c b/libavfilter/avf_showspatial.c
index 82d202a817..070edf87a0 100644
--- a/libavfilter/avf_showspatial.c
+++ b/libavfilter/avf_showspatial.c
@@ -346,7 +346,6 @@ static const AVFilterPad showspatial_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad showspatial_outputs[] = {
@@ -355,7 +354,6 @@ static const AVFilterPad showspatial_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showspatial = {
@@ -365,7 +363,9 @@ const AVFilter ff_avf_showspatial = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowSpatialContext),
     .inputs        = showspatial_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showspatial_inputs),
     .outputs       = showspatial_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showspatial_outputs),
     .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 1c94a06e3f..2f5161b204 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -1608,7 +1608,6 @@ static const AVFilterPad showspectrum_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad showspectrum_outputs[] = {
@@ -1617,7 +1616,6 @@ static const AVFilterPad showspectrum_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showspectrum = {
@@ -1627,7 +1625,9 @@ const AVFilter ff_avf_showspectrum = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowSpectrumContext),
     .inputs        = showspectrum_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showspectrum_inputs),
     .outputs       = showspectrum_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showspectrum_outputs),
     .activate      = activate,
     .priv_class    = &showspectrum_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
@@ -1792,7 +1792,6 @@ static const AVFilterPad showspectrumpic_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = showspectrumpic_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad showspectrumpic_outputs[] = {
@@ -1802,7 +1801,6 @@ static const AVFilterPad showspectrumpic_outputs[] = {
         .config_props  = config_output,
         .request_frame = showspectrumpic_request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showspectrumpic = {
@@ -1812,7 +1810,9 @@ const AVFilter ff_avf_showspectrumpic = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowSpectrumContext),
     .inputs        = showspectrumpic_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showspectrumpic_inputs),
     .outputs       = showspectrumpic_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showspectrumpic_outputs),
     .priv_class    = &showspectrumpic_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/avf_showvolume.c b/libavfilter/avf_showvolume.c
index d4b8c48297..c15e17b8ff 100644
--- a/libavfilter/avf_showvolume.c
+++ b/libavfilter/avf_showvolume.c
@@ -486,7 +486,6 @@ static const AVFilterPad showvolume_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad showvolume_outputs[] = {
@@ -495,7 +494,6 @@ static const AVFilterPad showvolume_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showvolume = {
@@ -507,6 +505,8 @@ const AVFilter ff_avf_showvolume = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowVolumeContext),
     .inputs        = showvolume_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showvolume_inputs),
     .outputs       = showvolume_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showvolume_outputs),
     .priv_class    = &showvolume_class,
 };
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index b3639f46a5..3e2787df38 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -763,7 +763,6 @@ static const AVFilterPad showwaves_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad showwaves_outputs[] = {
@@ -772,7 +771,6 @@ static const AVFilterPad showwaves_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showwaves = {
@@ -783,8 +781,10 @@ const AVFilter ff_avf_showwaves = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowWavesContext),
     .inputs        = showwaves_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showwaves_inputs),
     .activate      = activate,
     .outputs       = showwaves_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showwaves_outputs),
     .priv_class    = &showwaves_class,
 };
 
@@ -877,7 +877,6 @@ static const AVFilterPad showwavespic_inputs[] = {
         .config_props = showwavespic_config_input,
         .filter_frame = showwavespic_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad showwavespic_outputs[] = {
@@ -887,7 +886,6 @@ static const AVFilterPad showwavespic_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_showwavespic = {
@@ -898,7 +896,9 @@ const AVFilter ff_avf_showwavespic = {
     .query_formats = query_formats,
     .priv_size     = sizeof(ShowWavesContext),
     .inputs        = showwavespic_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showwavespic_inputs),
     .outputs       = showwavespic_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showwavespic_outputs),
     .priv_class    = &showwavespic_class,
 };
 
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index f9d7226386..85fbba8080 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -547,14 +547,20 @@ int avfilter_process_command(AVFilterContext *filter, const char *cmd, const cha
 
 int avfilter_pad_count(const AVFilterPad *pads)
 {
-    int count;
+    const AVFilter *filter;
+    void *opaque = NULL;
 
     if (!pads)
         return 0;
 
-    for (count = 0; pads->name; count++)
-        pads++;
-    return count;
+    while (filter = av_filter_iterate(&opaque)) {
+        if (pads == filter->inputs)
+            return filter->nb_inputs;
+        if (pads == filter->outputs)
+            return filter->nb_outputs;
+    }
+
+    av_assert0(!"AVFilterPad list not from a filter");
 }
 
 static const char *default_filter_name(void *filter_ctx)
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 360f63bc45..f436110b19 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -71,8 +71,7 @@ typedef struct AVFilterFormats AVFilterFormats;
 typedef struct AVFilterChannelLayouts AVFilterChannelLayouts;
 
 /**
- * Get the number of elements in a NULL-terminated array of AVFilterPads (e.g.
- * AVFilter.inputs/outputs).
+ * Get the number of elements in an AVFilter's inputs or outputs array.
  */
 int avfilter_pad_count(const AVFilterPad *pads);
 
@@ -156,15 +155,26 @@ typedef struct AVFilter {
     const char *description;
 
     /**
-     * List of inputs, terminated by a zeroed element.
+     * List of static inputs.
      *
      * NULL if there are no (static) inputs. Instances of filters with
      * AVFILTER_FLAG_DYNAMIC_INPUTS set may have more inputs than present in
      * this list.
      */
     const AVFilterPad *inputs;
+
+    /**
+     * The number of entries in the above list of inputs.
+     */
+    unsigned nb_inputs;
+
+    /**
+     * The number of entries in the list of outputs below.
+     */
+    unsigned nb_outputs;
+
     /**
-     * List of outputs, terminated by a zeroed element.
+     * List of static outputs.
      *
      * NULL if there are no (static) outputs. Instances of filters with
      * AVFILTER_FLAG_DYNAMIC_OUTPUTS set may have more outputs than present in
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 07c4812f29..be356943ff 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -331,7 +331,6 @@ static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsink_buffer = {
@@ -343,6 +342,7 @@ const AVFilter ff_vsink_buffer = {
     .query_formats = vsink_query_formats,
     .activate      = activate,
     .inputs        = avfilter_vsink_buffer_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vsink_buffer_inputs),
     .outputs       = NULL,
 };
 
@@ -351,7 +351,6 @@ static const AVFilterPad avfilter_asink_abuffer_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_asink_abuffer = {
@@ -363,5 +362,6 @@ const AVFilter ff_asink_abuffer = {
     .query_formats = asink_query_formats,
     .activate      = activate,
     .inputs        = avfilter_asink_abuffer_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_asink_abuffer_inputs),
     .outputs       = NULL,
 };
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 4d0bb4f91d..adad5dc928 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -434,7 +434,6 @@ static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_buffer = {
@@ -448,6 +447,7 @@ const AVFilter ff_vsrc_buffer = {
 
     .inputs    = NULL,
     .outputs   = avfilter_vsrc_buffer_outputs,
+    .nb_outputs = FF_ARRAY_ELEMS(avfilter_vsrc_buffer_outputs),
     .priv_class = &buffer_class,
 };
 
@@ -458,7 +458,6 @@ static const AVFilterPad avfilter_asrc_abuffer_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_asrc_abuffer = {
@@ -472,5 +471,6 @@ const AVFilter ff_asrc_abuffer = {
 
     .inputs    = NULL,
     .outputs   = avfilter_asrc_abuffer_outputs,
+    .nb_outputs = FF_ARRAY_ELEMS(avfilter_asrc_abuffer_outputs),
     .priv_class = &abuffer_class,
 };
diff --git a/libavfilter/f_bench.c b/libavfilter/f_bench.c
index e7d7c5e299..28bd424041 100644
--- a/libavfilter/f_bench.c
+++ b/libavfilter/f_bench.c
@@ -96,7 +96,6 @@ static const AVFilterPad bench_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad bench_outputs[] = {
@@ -104,7 +103,6 @@ static const AVFilterPad bench_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_bench = {
@@ -113,7 +111,9 @@ const AVFilter ff_vf_bench = {
     .priv_size     = sizeof(BenchContext),
     .init          = init,
     .inputs        = bench_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(bench_inputs),
     .outputs       = bench_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(bench_outputs),
     .priv_class    = &bench_class,
 };
 #endif /* CONFIG_BENCH_FILTER */
@@ -128,7 +128,6 @@ static const AVFilterPad abench_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad abench_outputs[] = {
@@ -136,7 +135,6 @@ static const AVFilterPad abench_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_abench = {
@@ -145,7 +143,9 @@ const AVFilter ff_af_abench = {
     .priv_size     = sizeof(BenchContext),
     .init          = init,
     .inputs        = abench_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(abench_inputs),
     .outputs       = abench_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(abench_outputs),
     .priv_class    = &abench_class,
 };
 #endif /* CONFIG_ABENCH_FILTER */
diff --git a/libavfilter/f_cue.c b/libavfilter/f_cue.c
index 03804f1667..a9c736b2ef 100644
--- a/libavfilter/f_cue.c
+++ b/libavfilter/f_cue.c
@@ -103,7 +103,6 @@ static const AVFilterPad cue_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad cue_outputs[] = {
@@ -111,7 +110,6 @@ static const AVFilterPad cue_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_cue = {
@@ -120,7 +118,9 @@ const AVFilter ff_vf_cue = {
     .priv_size   = sizeof(CueContext),
     .priv_class  = &cue_class,
     .inputs      = cue_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(cue_inputs),
     .outputs     = cue_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(cue_outputs),
     .activate    = activate,
 };
 #endif /* CONFIG_CUE_FILTER */
@@ -134,7 +134,6 @@ static const AVFilterPad acue_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad acue_outputs[] = {
@@ -142,7 +141,6 @@ static const AVFilterPad acue_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_acue = {
@@ -151,7 +149,9 @@ const AVFilter ff_af_acue = {
     .priv_size   = sizeof(CueContext),
     .priv_class  = &acue_class,
     .inputs      = acue_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(acue_inputs),
     .outputs     = acue_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(acue_outputs),
     .activate    = activate,
 };
 #endif /* CONFIG_ACUE_FILTER */
diff --git a/libavfilter/f_drawgraph.c b/libavfilter/f_drawgraph.c
index 70701e330e..93811ca6ac 100644
--- a/libavfilter/f_drawgraph.c
+++ b/libavfilter/f_drawgraph.c
@@ -458,7 +458,6 @@ static const AVFilterPad drawgraph_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad drawgraph_outputs[] = {
@@ -468,7 +467,6 @@ static const AVFilterPad drawgraph_outputs[] = {
         .config_props = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_drawgraph = {
@@ -480,7 +478,9 @@ const AVFilter ff_vf_drawgraph = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = drawgraph_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(drawgraph_inputs),
     .outputs       = drawgraph_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(drawgraph_outputs),
 };
 
 #endif // CONFIG_DRAWGRAPH_FILTER
@@ -496,7 +496,6 @@ static const AVFilterPad adrawgraph_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad adrawgraph_outputs[] = {
@@ -506,7 +505,6 @@ static const AVFilterPad adrawgraph_outputs[] = {
         .config_props = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_adrawgraph = {
@@ -518,6 +516,8 @@ const AVFilter ff_avf_adrawgraph = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = adrawgraph_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(adrawgraph_inputs),
     .outputs       = adrawgraph_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(adrawgraph_outputs),
 };
 #endif // CONFIG_ADRAWGRAPH_FILTER
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
index 47ea9b59d7..b8979db834 100644
--- a/libavfilter/f_ebur128.c
+++ b/libavfilter/f_ebur128.c
@@ -1017,7 +1017,6 @@ static const AVFilterPad ebur128_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_audio_input,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_ebur128 = {
@@ -1028,6 +1027,7 @@ const AVFilter ff_af_ebur128 = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = ebur128_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ebur128_inputs),
     .outputs       = NULL,
     .priv_class    = &ebur128_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
diff --git a/libavfilter/f_graphmonitor.c b/libavfilter/f_graphmonitor.c
index 90e93a4ac3..cdfe7c2232 100644
--- a/libavfilter/f_graphmonitor.c
+++ b/libavfilter/f_graphmonitor.c
@@ -395,7 +395,6 @@ static const AVFilterPad graphmonitor_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad graphmonitor_outputs[] = {
@@ -404,7 +403,6 @@ static const AVFilterPad graphmonitor_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_graphmonitor = {
@@ -415,7 +413,9 @@ const AVFilter ff_vf_graphmonitor = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = graphmonitor_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(graphmonitor_inputs),
     .outputs       = graphmonitor_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(graphmonitor_outputs),
 };
 
 #endif // CONFIG_GRAPHMONITOR_FILTER
@@ -430,7 +430,6 @@ static const AVFilterPad agraphmonitor_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad agraphmonitor_outputs[] = {
@@ -439,7 +438,6 @@ static const AVFilterPad agraphmonitor_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_avf_agraphmonitor = {
@@ -450,6 +448,8 @@ const AVFilter ff_avf_agraphmonitor = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = agraphmonitor_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(agraphmonitor_inputs),
     .outputs       = agraphmonitor_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(agraphmonitor_outputs),
 };
 #endif // CONFIG_AGRAPHMONITOR_FILTER
diff --git a/libavfilter/f_interleave.c b/libavfilter/f_interleave.c
index 259952b591..97b523573f 100644
--- a/libavfilter/f_interleave.c
+++ b/libavfilter/f_interleave.c
@@ -235,7 +235,6 @@ static const AVFilterPad interleave_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_interleave = {
@@ -246,6 +245,7 @@ const AVFilter ff_vf_interleave = {
     .uninit      = uninit,
     .activate    = activate,
     .outputs     = interleave_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(interleave_outputs),
     .priv_class  = &interleave_class,
     .flags       = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
@@ -263,7 +263,6 @@ static const AVFilterPad ainterleave_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_ainterleave = {
@@ -274,6 +273,7 @@ const AVFilter ff_af_ainterleave = {
     .uninit      = uninit,
     .activate    = activate,
     .outputs     = ainterleave_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(ainterleave_outputs),
     .priv_class  = &ainterleave_class,
     .flags       = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/f_loop.c b/libavfilter/f_loop.c
index a06e8172d3..a3f91b51e8 100644
--- a/libavfilter/f_loop.c
+++ b/libavfilter/f_loop.c
@@ -269,7 +269,6 @@ static const AVFilterPad ainputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = aconfig_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad aoutputs[] = {
@@ -277,7 +276,6 @@ static const AVFilterPad aoutputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aloop = {
@@ -288,7 +286,9 @@ const AVFilter ff_af_aloop = {
     .activate      = aactivate,
     .uninit        = auninit,
     .inputs        = ainputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ainputs),
     .outputs       = aoutputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aoutputs),
 };
 #endif /* CONFIG_ALOOP_FILTER */
 
@@ -442,7 +442,6 @@ static const AVFilterPad inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -450,7 +449,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_loop = {
@@ -462,6 +460,8 @@ const AVFilter ff_vf_loop = {
     .uninit      = uninit,
     .activate    = activate,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
 };
 #endif /* CONFIG_LOOP_FILTER */
diff --git a/libavfilter/f_metadata.c b/libavfilter/f_metadata.c
index d0a78b00d0..45c319a1d9 100644
--- a/libavfilter/f_metadata.c
+++ b/libavfilter/f_metadata.c
@@ -373,7 +373,6 @@ static const AVFilterPad ainputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad aoutputs[] = {
@@ -381,7 +380,6 @@ static const AVFilterPad aoutputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_ametadata = {
@@ -392,7 +390,9 @@ const AVFilter ff_af_ametadata = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = ainputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ainputs),
     .outputs       = aoutputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aoutputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
 #endif /* CONFIG_AMETADATA_FILTER */
@@ -408,7 +408,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -416,7 +415,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_metadata = {
@@ -427,7 +425,9 @@ const AVFilter ff_vf_metadata = {
     .init        = init,
     .uninit      = uninit,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
     .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
 #endif /* CONFIG_METADATA_FILTER */
diff --git a/libavfilter/f_perms.c b/libavfilter/f_perms.c
index 0302ed765b..aaa466d717 100644
--- a/libavfilter/f_perms.c
+++ b/libavfilter/f_perms.c
@@ -122,7 +122,6 @@ static const AVFilterPad aperms_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad aperms_outputs[] = {
@@ -130,7 +129,6 @@ static const AVFilterPad aperms_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aperms = {
@@ -139,7 +137,9 @@ const AVFilter ff_af_aperms = {
     .init        = init,
     .priv_size   = sizeof(PermsContext),
     .inputs      = aperms_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(aperms_inputs),
     .outputs     = aperms_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(aperms_outputs),
     .priv_class  = &aperms_class,
     .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -156,7 +156,6 @@ static const AVFilterPad perms_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad perms_outputs[] = {
@@ -164,7 +163,6 @@ static const AVFilterPad perms_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_perms = {
@@ -173,7 +171,9 @@ const AVFilter ff_vf_perms = {
     .init        = init,
     .priv_size   = sizeof(PermsContext),
     .inputs      = perms_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(perms_inputs),
     .outputs     = perms_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(perms_outputs),
     .priv_class  = &perms_class,
     .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/f_realtime.c b/libavfilter/f_realtime.c
index 332ef21ac5..19002d8265 100644
--- a/libavfilter/f_realtime.c
+++ b/libavfilter/f_realtime.c
@@ -81,7 +81,6 @@ static const AVFilterPad avfilter_vf_realtime_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_realtime_outputs[] = {
@@ -89,7 +88,6 @@ static const AVFilterPad avfilter_vf_realtime_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_realtime = {
@@ -98,7 +96,9 @@ const AVFilter ff_vf_realtime = {
     .priv_size   = sizeof(RealtimeContext),
     .priv_class  = &realtime_class,
     .inputs      = avfilter_vf_realtime_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_realtime_inputs),
     .outputs     = avfilter_vf_realtime_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_realtime_outputs),
 };
 #endif /* CONFIG_REALTIME_FILTER */
 
@@ -113,7 +113,6 @@ static const AVFilterPad arealtime_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad arealtime_outputs[] = {
@@ -121,7 +120,6 @@ static const AVFilterPad arealtime_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_arealtime = {
@@ -130,6 +128,8 @@ const AVFilter ff_af_arealtime = {
     .priv_size   = sizeof(RealtimeContext),
     .priv_class  = &arealtime_class,
     .inputs      = arealtime_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(arealtime_inputs),
     .outputs     = arealtime_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(arealtime_outputs),
 };
 #endif /* CONFIG_AREALTIME_FILTER */
diff --git a/libavfilter/f_reverse.c b/libavfilter/f_reverse.c
index 2a85e6966e..f59d114a57 100644
--- a/libavfilter/f_reverse.c
+++ b/libavfilter/f_reverse.c
@@ -121,7 +121,6 @@ static const AVFilterPad reverse_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad reverse_outputs[] = {
@@ -130,7 +129,6 @@ static const AVFilterPad reverse_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_reverse = {
@@ -140,7 +138,9 @@ const AVFilter ff_vf_reverse = {
     .init        = init,
     .uninit      = uninit,
     .inputs      = reverse_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(reverse_inputs),
     .outputs     = reverse_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(reverse_outputs),
 };
 
 #endif /* CONFIG_REVERSE_FILTER */
@@ -282,7 +282,6 @@ static const AVFilterPad areverse_inputs[] = {
         .filter_frame   = filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad areverse_outputs[] = {
@@ -291,7 +290,6 @@ static const AVFilterPad areverse_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .request_frame = areverse_request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_areverse = {
@@ -302,7 +300,9 @@ const AVFilter ff_af_areverse = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = areverse_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(areverse_inputs),
     .outputs       = areverse_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(areverse_outputs),
 };
 
 #endif /* CONFIG_AREVERSE_FILTER */
diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c
index f0468078e8..594b2c85f2 100644
--- a/libavfilter/f_select.c
+++ b/libavfilter/f_select.c
@@ -473,7 +473,6 @@ static const AVFilterPad avfilter_af_aselect_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_aselect = {
@@ -483,6 +482,7 @@ const AVFilter ff_af_aselect = {
     .uninit      = uninit,
     .priv_size   = sizeof(SelectContext),
     .inputs      = avfilter_af_aselect_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_af_aselect_inputs),
     .priv_class  = &aselect_class,
     .flags       = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
@@ -537,7 +537,6 @@ static const AVFilterPad avfilter_vf_select_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_select = {
@@ -549,6 +548,7 @@ const AVFilter ff_vf_select = {
     .priv_size     = sizeof(SelectContext),
     .priv_class    = &select_class,
     .inputs        = avfilter_vf_select_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_select_inputs),
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
 #endif /* CONFIG_SELECT_FILTER */
diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c
index 71b0a5c411..c5b05ec503 100644
--- a/libavfilter/f_sendcmd.c
+++ b/libavfilter/f_sendcmd.c
@@ -583,7 +583,6 @@ static const AVFilterPad sendcmd_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad sendcmd_outputs[] = {
@@ -591,7 +590,6 @@ static const AVFilterPad sendcmd_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_sendcmd = {
@@ -601,7 +599,9 @@ const AVFilter ff_vf_sendcmd = {
     .uninit      = uninit,
     .priv_size   = sizeof(SendCmdContext),
     .inputs      = sendcmd_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(sendcmd_inputs),
     .outputs     = sendcmd_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(sendcmd_outputs),
     .priv_class  = &sendcmd_class,
 };
 
@@ -618,7 +618,6 @@ static const AVFilterPad asendcmd_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad asendcmd_outputs[] = {
@@ -626,7 +625,6 @@ static const AVFilterPad asendcmd_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asendcmd = {
@@ -636,7 +634,9 @@ const AVFilter ff_af_asendcmd = {
     .uninit      = uninit,
     .priv_size   = sizeof(SendCmdContext),
     .inputs      = asendcmd_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(asendcmd_inputs),
     .outputs     = asendcmd_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(asendcmd_outputs),
     .priv_class  = &asendcmd_class,
 };
 
diff --git a/libavfilter/f_sidedata.c b/libavfilter/f_sidedata.c
index 9133fcb1e3..4fa6572e73 100644
--- a/libavfilter/f_sidedata.c
+++ b/libavfilter/f_sidedata.c
@@ -130,7 +130,6 @@ static const AVFilterPad ainputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad aoutputs[] = {
@@ -138,7 +137,6 @@ static const AVFilterPad aoutputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asidedata = {
@@ -148,7 +146,9 @@ const AVFilter ff_af_asidedata = {
     .priv_class    = &asidedata_class,
     .init          = init,
     .inputs        = ainputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ainputs),
     .outputs       = aoutputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(aoutputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
 #endif /* CONFIG_ASIDEDATA_FILTER */
@@ -164,7 +164,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -172,7 +171,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_sidedata = {
@@ -182,7 +180,9 @@ const AVFilter ff_vf_sidedata = {
     .priv_class  = &sidedata_class,
     .init        = init,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
     .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
 #endif /* CONFIG_SIDEDATA_FILTER */
diff --git a/libavfilter/f_zmq.c b/libavfilter/f_zmq.c
index 774a890871..a14843c6bf 100644
--- a/libavfilter/f_zmq.c
+++ b/libavfilter/f_zmq.c
@@ -214,7 +214,6 @@ static const AVFilterPad zmq_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad zmq_outputs[] = {
@@ -222,7 +221,6 @@ static const AVFilterPad zmq_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_zmq = {
@@ -232,7 +230,9 @@ const AVFilter ff_vf_zmq = {
     .uninit      = uninit,
     .priv_size   = sizeof(ZMQContext),
     .inputs      = zmq_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(zmq_inputs),
     .outputs     = zmq_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(zmq_outputs),
     .priv_class  = &zmq_class,
 };
 
@@ -249,7 +249,6 @@ static const AVFilterPad azmq_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad azmq_outputs[] = {
@@ -257,7 +256,6 @@ static const AVFilterPad azmq_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_azmq = {
@@ -267,7 +265,9 @@ const AVFilter ff_af_azmq = {
     .uninit      = uninit,
     .priv_size   = sizeof(ZMQContext),
     .inputs      = azmq_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(azmq_inputs),
     .outputs     = azmq_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(azmq_outputs),
     .priv_class  = &azmq_class,
 };
 
diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c
index e0996ba501..f5ec7505de 100644
--- a/libavfilter/fifo.c
+++ b/libavfilter/fifo.c
@@ -116,7 +116,6 @@ static const AVFilterPad avfilter_vf_fifo_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = add_to_queue,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_fifo_outputs[] = {
@@ -125,7 +124,6 @@ static const AVFilterPad avfilter_vf_fifo_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fifo = {
@@ -135,7 +133,9 @@ const AVFilter ff_vf_fifo = {
     .uninit      = uninit,
     .priv_size   = sizeof(FifoContext),
     .inputs      = avfilter_vf_fifo_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_fifo_inputs),
     .outputs     = avfilter_vf_fifo_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_fifo_outputs),
 };
 
 static const AVFilterPad avfilter_af_afifo_inputs[] = {
@@ -144,7 +144,6 @@ static const AVFilterPad avfilter_af_afifo_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = add_to_queue,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_afifo_outputs[] = {
@@ -153,7 +152,6 @@ static const AVFilterPad avfilter_af_afifo_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_afifo = {
@@ -163,5 +161,7 @@ const AVFilter ff_af_afifo = {
     .uninit      = uninit,
     .priv_size   = sizeof(FifoContext),
     .inputs      = avfilter_af_afifo_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_af_afifo_inputs),
     .outputs     = avfilter_af_afifo_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_af_afifo_outputs),
 };
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
index ac98974312..03a3759a38 100644
--- a/libavfilter/setpts.c
+++ b/libavfilter/setpts.c
@@ -279,7 +279,6 @@ static const AVFilterPad avfilter_vf_setpts_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_setpts_outputs[] = {
@@ -287,7 +286,6 @@ static const AVFilterPad avfilter_vf_setpts_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_setpts = {
@@ -301,7 +299,9 @@ const AVFilter ff_vf_setpts = {
     .priv_class = &setpts_class,
 
     .inputs    = avfilter_vf_setpts_inputs,
+    .nb_inputs  = FF_ARRAY_ELEMS(avfilter_vf_setpts_inputs),
     .outputs   = avfilter_vf_setpts_outputs,
+    .nb_outputs = FF_ARRAY_ELEMS(avfilter_vf_setpts_outputs),
 };
 #endif /* CONFIG_SETPTS_FILTER */
 
@@ -319,7 +319,6 @@ static const AVFilterPad asetpts_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad asetpts_outputs[] = {
@@ -327,7 +326,6 @@ static const AVFilterPad asetpts_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asetpts = {
@@ -339,6 +337,8 @@ const AVFilter ff_af_asetpts = {
     .priv_size   = sizeof(SetPTSContext),
     .priv_class  = &asetpts_class,
     .inputs      = asetpts_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(asetpts_inputs),
     .outputs     = asetpts_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(asetpts_outputs),
 };
 #endif /* CONFIG_ASETPTS_FILTER */
diff --git a/libavfilter/settb.c b/libavfilter/settb.c
index 2f68e44c5b..93d88cad5e 100644
--- a/libavfilter/settb.c
+++ b/libavfilter/settb.c
@@ -167,7 +167,6 @@ static const AVFilterPad avfilter_vf_settb_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_settb_outputs[] = {
@@ -176,7 +175,6 @@ static const AVFilterPad avfilter_vf_settb_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_settb = {
@@ -185,7 +183,9 @@ const AVFilter ff_vf_settb = {
     .priv_size   = sizeof(SetTBContext),
     .priv_class  = &settb_class,
     .inputs      = avfilter_vf_settb_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_settb_inputs),
     .outputs     = avfilter_vf_settb_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_settb_outputs),
     .activate    = activate,
 };
 #endif /* CONFIG_SETTB_FILTER */
@@ -200,7 +200,6 @@ static const AVFilterPad avfilter_af_asettb_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_af_asettb_outputs[] = {
@@ -209,7 +208,6 @@ static const AVFilterPad avfilter_af_asettb_outputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .config_props = config_output_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asettb = {
@@ -217,7 +215,9 @@ const AVFilter ff_af_asettb = {
     .description = NULL_IF_CONFIG_SMALL("Set timebase for the audio output link."),
     .priv_size   = sizeof(SetTBContext),
     .inputs      = avfilter_af_asettb_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_af_asettb_inputs),
     .outputs     = avfilter_af_asettb_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_af_asettb_outputs),
     .priv_class  = &asettb_class,
     .activate    = activate,
 };
diff --git a/libavfilter/split.c b/libavfilter/split.c
index da5f681af8..9723160ed5 100644
--- a/libavfilter/split.c
+++ b/libavfilter/split.c
@@ -116,7 +116,6 @@ static const AVFilterPad avfilter_vf_split_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_split = {
@@ -127,6 +126,7 @@ const AVFilter ff_vf_split = {
     .init        = split_init,
     .uninit      = split_uninit,
     .inputs      = avfilter_vf_split_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_split_inputs),
     .outputs     = NULL,
     .flags       = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
@@ -137,7 +137,6 @@ static const AVFilterPad avfilter_af_asplit_inputs[] = {
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_asplit = {
@@ -148,6 +147,7 @@ const AVFilter ff_af_asplit = {
     .init        = split_init,
     .uninit      = split_uninit,
     .inputs      = avfilter_af_asplit_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_af_asplit_inputs),
     .outputs     = NULL,
     .flags       = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/trim.c b/libavfilter/trim.c
index 261dacbc5c..a867373732 100644
--- a/libavfilter/trim.c
+++ b/libavfilter/trim.c
@@ -195,7 +195,6 @@ static const AVFilterPad trim_inputs[] = {
         .filter_frame = trim_filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad trim_outputs[] = {
@@ -203,7 +202,6 @@ static const AVFilterPad trim_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_trim = {
@@ -213,7 +211,9 @@ const AVFilter ff_vf_trim = {
     .priv_size   = sizeof(TrimContext),
     .priv_class  = &trim_class,
     .inputs      = trim_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(trim_inputs),
     .outputs     = trim_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(trim_outputs),
 };
 #endif // CONFIG_TRIM_FILTER
 
@@ -350,7 +350,6 @@ static const AVFilterPad atrim_inputs[] = {
         .filter_frame = atrim_filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad atrim_outputs[] = {
@@ -358,7 +357,6 @@ static const AVFilterPad atrim_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
     },
-    { NULL }
 };
 
 const AVFilter ff_af_atrim = {
@@ -368,6 +366,8 @@ const AVFilter ff_af_atrim = {
     .priv_size   = sizeof(TrimContext),
     .priv_class  = &atrim_class,
     .inputs      = atrim_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(atrim_inputs),
     .outputs     = atrim_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(atrim_outputs),
 };
 #endif // CONFIG_ATRIM_FILTER
diff --git a/libavfilter/vaf_spectrumsynth.c b/libavfilter/vaf_spectrumsynth.c
index d44d01cd33..78b822df57 100644
--- a/libavfilter/vaf_spectrumsynth.c
+++ b/libavfilter/vaf_spectrumsynth.c
@@ -532,7 +532,6 @@ static const AVFilterPad spectrumsynth_inputs[] = {
         .name         = "phase",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad spectrumsynth_outputs[] = {
@@ -541,7 +540,6 @@ static const AVFilterPad spectrumsynth_outputs[] = {
         .type          = AVMEDIA_TYPE_AUDIO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vaf_spectrumsynth = {
@@ -552,6 +550,8 @@ const AVFilter ff_vaf_spectrumsynth = {
     .activate      = activate,
     .priv_size     = sizeof(SpectrumSynthContext),
     .inputs        = spectrumsynth_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(spectrumsynth_inputs),
     .outputs       = spectrumsynth_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(spectrumsynth_outputs),
     .priv_class    = &spectrumsynth_class,
 };
diff --git a/libavfilter/vf_addroi.c b/libavfilter/vf_addroi.c
index 1d09f31879..08901db2c7 100644
--- a/libavfilter/vf_addroi.c
+++ b/libavfilter/vf_addroi.c
@@ -244,7 +244,6 @@ static const AVFilterPad addroi_inputs[] = {
         .config_props = addroi_config_input,
         .filter_frame = addroi_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad addroi_outputs[] = {
@@ -252,7 +251,6 @@ static const AVFilterPad addroi_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_addroi = {
@@ -265,5 +263,7 @@ const AVFilter ff_vf_addroi = {
     .priv_class  = &addroi_class,
 
     .inputs      = addroi_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(addroi_inputs),
     .outputs     = addroi_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(addroi_outputs),
 };
diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
index 9b01db6605..f58a70dc11 100644
--- a/libavfilter/vf_alphamerge.c
+++ b/libavfilter/vf_alphamerge.c
@@ -170,7 +170,6 @@ static const AVFilterPad alphamerge_inputs[] = {
         .name             = "alpha",
         .type             = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad alphamerge_outputs[] = {
@@ -179,7 +178,6 @@ static const AVFilterPad alphamerge_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 static const AVOption alphamerge_options[] = {
@@ -198,7 +196,9 @@ const AVFilter ff_vf_alphamerge = {
     .init           = init,
     .query_formats  = query_formats,
     .inputs         = alphamerge_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(alphamerge_inputs),
     .outputs        = alphamerge_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(alphamerge_outputs),
     .uninit         = uninit,
     .activate       = activate,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
diff --git a/libavfilter/vf_amplify.c b/libavfilter/vf_amplify.c
index e9e0a90b41..a8544434ae 100644
--- a/libavfilter/vf_amplify.c
+++ b/libavfilter/vf_amplify.c
@@ -299,7 +299,6 @@ static const AVFilterPad inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -308,7 +307,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(amplify);
@@ -320,7 +318,9 @@ const AVFilter ff_vf_amplify = {
     .priv_class    = &amplify_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .init          = init,
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index f0467b5247..8e7a08777f 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -173,7 +173,6 @@ static const AVFilterPad avfilter_vf_setdar_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_setdar_outputs[] = {
@@ -182,7 +181,6 @@ static const AVFilterPad avfilter_vf_setdar_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = setdar_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_setdar = {
@@ -191,7 +189,9 @@ const AVFilter ff_vf_setdar = {
     .priv_size   = sizeof(AspectContext),
     .priv_class  = &setdar_class,
     .inputs      = avfilter_vf_setdar_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_setdar_inputs),
     .outputs     = avfilter_vf_setdar_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_setdar_outputs),
 };
 
 #endif /* CONFIG_SETDAR_FILTER */
@@ -237,7 +237,6 @@ static const AVFilterPad avfilter_vf_setsar_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_setsar_outputs[] = {
@@ -246,7 +245,6 @@ static const AVFilterPad avfilter_vf_setsar_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = setsar_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_setsar = {
@@ -255,7 +253,9 @@ const AVFilter ff_vf_setsar = {
     .priv_size   = sizeof(AspectContext),
     .priv_class  = &setsar_class,
     .inputs      = avfilter_vf_setsar_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_setsar_inputs),
     .outputs     = avfilter_vf_setsar_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_setsar_outputs),
 };
 
 #endif /* CONFIG_SETSAR_FILTER */
diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c
index 6b2f4a4e50..834e42ae79 100644
--- a/libavfilter/vf_atadenoise.c
+++ b/libavfilter/vf_atadenoise.c
@@ -560,7 +560,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -569,7 +568,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_atadenoise = {
@@ -581,7 +579,9 @@ const AVFilter ff_vf_atadenoise = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 361801e8fd..cb2f2cebc2 100644
--- a/libavfilter/vf_avgblur.c
+++ b/libavfilter/vf_avgblur.c
@@ -302,7 +302,6 @@ static const AVFilterPad avgblur_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avgblur_outputs[] = {
@@ -310,7 +309,6 @@ static const AVFilterPad avgblur_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_avgblur = {
@@ -321,7 +319,9 @@ const AVFilter ff_vf_avgblur = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avgblur_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avgblur_inputs),
     .outputs       = avgblur_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avgblur_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_avgblur_opencl.c b/libavfilter/vf_avgblur_opencl.c
index 3b9e56b879..8197dde723 100644
--- a/libavfilter/vf_avgblur_opencl.c
+++ b/libavfilter/vf_avgblur_opencl.c
@@ -311,7 +311,6 @@ static const AVFilterPad avgblur_opencl_inputs[] = {
         .filter_frame = &avgblur_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 
@@ -321,7 +320,6 @@ static const AVFilterPad avgblur_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 
@@ -349,7 +347,9 @@ const AVFilter ff_vf_avgblur_opencl = {
     .uninit         = &avgblur_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = avgblur_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(avgblur_opencl_inputs),
     .outputs        = avgblur_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(avgblur_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -388,7 +388,9 @@ const AVFilter ff_vf_boxblur_opencl = {
     .uninit         = &avgblur_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = avgblur_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(avgblur_opencl_inputs),
     .outputs        = avgblur_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(avgblur_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_avgblur_vulkan.c b/libavfilter/vf_avgblur_vulkan.c
index 1e485061cd..354070deed 100644
--- a/libavfilter/vf_avgblur_vulkan.c
+++ b/libavfilter/vf_avgblur_vulkan.c
@@ -386,7 +386,6 @@ static const AVFilterPad avgblur_vulkan_inputs[] = {
         .filter_frame = &avgblur_vulkan_filter_frame,
         .config_props = &ff_vk_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avgblur_vulkan_outputs[] = {
@@ -395,7 +394,6 @@ static const AVFilterPad avgblur_vulkan_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_vk_filter_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_avgblur_vulkan = {
@@ -406,7 +404,9 @@ const AVFilter ff_vf_avgblur_vulkan = {
     .uninit         = &avgblur_vulkan_uninit,
     .query_formats  = &ff_vk_filter_query_formats,
     .inputs         = avgblur_vulkan_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(avgblur_vulkan_inputs),
     .outputs        = avgblur_vulkan_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(avgblur_vulkan_outputs),
     .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 849e75646b..e710c9b94a 100644
--- a/libavfilter/vf_bbox.c
+++ b/libavfilter/vf_bbox.c
@@ -141,7 +141,6 @@ static const AVFilterPad bbox_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad bbox_outputs[] = {
@@ -150,7 +149,6 @@ static const AVFilterPad bbox_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_bbox = {
@@ -160,7 +158,9 @@ const AVFilter ff_vf_bbox = {
     .priv_class    = &bbox_class,
     .query_formats = query_formats,
     .inputs        = bbox_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(bbox_inputs),
     .outputs       = bbox_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(bbox_outputs),
     .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 7b9bd9737a..1081a5450d 100644
--- a/libavfilter/vf_bilateral.c
+++ b/libavfilter/vf_bilateral.c
@@ -368,7 +368,6 @@ static const AVFilterPad bilateral_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad bilateral_outputs[] = {
@@ -376,7 +375,6 @@ static const AVFilterPad bilateral_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_bilateral = {
@@ -387,7 +385,9 @@ const AVFilter ff_vf_bilateral = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = bilateral_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(bilateral_inputs),
     .outputs       = bilateral_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(bilateral_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_bitplanenoise.c b/libavfilter/vf_bitplanenoise.c
index 284c2966cf..494f93b558 100644
--- a/libavfilter/vf_bitplanenoise.c
+++ b/libavfilter/vf_bitplanenoise.c
@@ -203,7 +203,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -211,7 +210,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_bitplanenoise = {
@@ -220,7 +218,9 @@ const AVFilter ff_vf_bitplanenoise = {
     .priv_size      = sizeof(BPNContext),
     .query_formats  = query_formats,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
     .priv_class     = &bitplanenoise_class,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c
index 9f6b293b54..3ab4789162 100644
--- a/libavfilter/vf_blackdetect.c
+++ b/libavfilter/vf_blackdetect.c
@@ -247,7 +247,6 @@ static const AVFilterPad blackdetect_inputs[] = {
         .config_props  = config_input,
         .filter_frame  = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad blackdetect_outputs[] = {
@@ -255,7 +254,6 @@ static const AVFilterPad blackdetect_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_blackdetect = {
@@ -264,7 +262,9 @@ const AVFilter ff_vf_blackdetect = {
     .priv_size     = sizeof(BlackDetectContext),
     .query_formats = query_formats,
     .inputs        = blackdetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(blackdetect_inputs),
     .outputs       = blackdetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(blackdetect_outputs),
     .uninit        = uninit,
     .priv_class    = &blackdetect_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index b82c044f3e..aa72451ebe 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -121,7 +121,6 @@ static const AVFilterPad avfilter_vf_blackframe_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_blackframe_outputs[] = {
@@ -129,7 +128,6 @@ static const AVFilterPad avfilter_vf_blackframe_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_blackframe = {
@@ -139,5 +137,7 @@ const AVFilter ff_vf_blackframe = {
     .priv_class    = &blackframe_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_blackframe_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_blackframe_inputs),
     .outputs       = avfilter_vf_blackframe_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_blackframe_outputs),
 };
diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
index 0b33107b79..a4c30787ac 100644
--- a/libavfilter/vf_blend.c
+++ b/libavfilter/vf_blend.c
@@ -894,7 +894,6 @@ static const AVFilterPad blend_inputs[] = {
         .name          = "bottom",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad blend_outputs[] = {
@@ -903,7 +902,6 @@ static const AVFilterPad blend_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_blend = {
@@ -916,7 +914,9 @@ const AVFilter ff_vf_blend = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = blend_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(blend_inputs),
     .outputs       = blend_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(blend_outputs),
     .priv_class    = &blend_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -956,7 +956,6 @@ static const AVFilterPad tblend_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = tblend_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad tblend_outputs[] = {
@@ -965,7 +964,6 @@ static const AVFilterPad tblend_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tblend = {
@@ -977,7 +975,9 @@ const AVFilter ff_vf_tblend = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = tblend_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(tblend_inputs),
     .outputs       = tblend_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(tblend_outputs),
     .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 f719e79cb0..d809024d1f 100644
--- a/libavfilter/vf_bm3d.c
+++ b/libavfilter/vf_bm3d.c
@@ -1051,7 +1051,6 @@ static const AVFilterPad bm3d_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_bm3d = {
@@ -1064,6 +1063,7 @@ const AVFilter ff_vf_bm3d = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = bm3d_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(bm3d_outputs),
     .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 bebbd4ef08..108710b8e0 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -293,7 +293,6 @@ static const AVFilterPad avfilter_vf_boxblur_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_boxblur_outputs[] = {
@@ -301,7 +300,6 @@ static const AVFilterPad avfilter_vf_boxblur_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_boxblur = {
@@ -312,6 +310,8 @@ const AVFilter ff_vf_boxblur = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_boxblur_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_boxblur_inputs),
     .outputs       = avfilter_vf_boxblur_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_boxblur_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c
index 228067c8e5..ab7560b985 100644
--- a/libavfilter/vf_bwdif.c
+++ b/libavfilter/vf_bwdif.c
@@ -395,7 +395,6 @@ static const AVFilterPad avfilter_vf_bwdif_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = ff_yadif_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_bwdif_outputs[] = {
@@ -405,7 +404,6 @@ static const AVFilterPad avfilter_vf_bwdif_outputs[] = {
         .request_frame = ff_yadif_request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_bwdif = {
@@ -416,6 +414,8 @@ const AVFilter ff_vf_bwdif = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_bwdif_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_bwdif_inputs),
     .outputs       = avfilter_vf_bwdif_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_bwdif_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_cas.c b/libavfilter/vf_cas.c
index c5a53adfe9..3698d062ac 100644
--- a/libavfilter/vf_cas.c
+++ b/libavfilter/vf_cas.c
@@ -264,7 +264,6 @@ static const AVFilterPad cas_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad cas_outputs[] = {
@@ -272,7 +271,6 @@ static const AVFilterPad cas_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(CASContext, x)
@@ -293,7 +291,9 @@ const AVFilter ff_vf_cas = {
     .priv_class    = &cas_class,
     .query_formats = query_formats,
     .inputs        = cas_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(cas_inputs),
     .outputs       = cas_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(cas_outputs),
     .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 2f5bf7bbb9..ac2d22074d 100644
--- a/libavfilter/vf_chromaber_vulkan.c
+++ b/libavfilter/vf_chromaber_vulkan.c
@@ -321,7 +321,6 @@ static const AVFilterPad chromaber_vulkan_inputs[] = {
         .filter_frame = &chromaber_vulkan_filter_frame,
         .config_props = &ff_vk_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad chromaber_vulkan_outputs[] = {
@@ -330,7 +329,6 @@ static const AVFilterPad chromaber_vulkan_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_vk_filter_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_chromaber_vulkan = {
@@ -341,7 +339,9 @@ const AVFilter ff_vf_chromaber_vulkan = {
     .uninit         = &chromaber_vulkan_uninit,
     .query_formats  = &ff_vk_filter_query_formats,
     .inputs         = chromaber_vulkan_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(chromaber_vulkan_inputs),
     .outputs        = chromaber_vulkan_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(chromaber_vulkan_outputs),
     .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 45d8e43c2c..3d93e67dc0 100644
--- a/libavfilter/vf_chromakey.c
+++ b/libavfilter/vf_chromakey.c
@@ -373,7 +373,6 @@ static const AVFilterPad chromakey_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad chromakey_outputs[] = {
@@ -382,7 +381,6 @@ static const AVFilterPad chromakey_outputs[] = {
         .type           = AVMEDIA_TYPE_VIDEO,
         .config_props   = config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ChromakeyContext, x)
@@ -405,7 +403,9 @@ const AVFilter ff_vf_chromakey = {
     .priv_class    = &chromakey_class,
     .query_formats = query_formats,
     .inputs        = chromakey_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(chromakey_inputs),
     .outputs       = chromakey_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(chromakey_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -426,7 +426,6 @@ static const AVFilterPad chromahold_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad chromahold_outputs[] = {
@@ -435,7 +434,6 @@ static const AVFilterPad chromahold_outputs[] = {
         .type           = AVMEDIA_TYPE_VIDEO,
         .config_props   = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(chromahold);
@@ -447,7 +445,9 @@ const AVFilter ff_vf_chromahold = {
     .priv_class    = &chromahold_class,
     .query_formats = query_formats,
     .inputs        = chromahold_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(chromahold_inputs),
     .outputs       = chromahold_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(chromahold_outputs),
     .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 810fd2ce9d..a6dabc5e46 100644
--- a/libavfilter/vf_chromanr.c
+++ b/libavfilter/vf_chromanr.c
@@ -267,7 +267,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -275,7 +274,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(chromanr);
@@ -287,7 +285,9 @@ const AVFilter ff_vf_chromanr = {
     .priv_class    = &chromanr_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .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 3f172a8e2b..d4d5f136fb 100644
--- a/libavfilter/vf_chromashift.c
+++ b/libavfilter/vf_chromashift.c
@@ -433,7 +433,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -441,7 +440,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(chromashift);
@@ -453,7 +451,9 @@ const AVFilter ff_vf_chromashift = {
     .priv_class    = &chromashift_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -482,7 +482,9 @@ const AVFilter ff_vf_rgbashift = {
     .priv_class    = &rgbashift_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .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 cafdb915ea..2723e3d662 100644
--- a/libavfilter/vf_ciescope.c
+++ b/libavfilter/vf_ciescope.c
@@ -1492,7 +1492,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1501,7 +1500,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_ciescope = {
@@ -1512,5 +1510,7 @@ const AVFilter ff_vf_ciescope = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c
index e3c613f10c..6eeb9c2f33 100644
--- a/libavfilter/vf_codecview.c
+++ b/libavfilter/vf_codecview.c
@@ -307,7 +307,6 @@ static const AVFilterPad codecview_inputs[] = {
         .config_props   = config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad codecview_outputs[] = {
@@ -315,7 +314,6 @@ static const AVFilterPad codecview_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_codecview = {
@@ -324,7 +322,9 @@ const AVFilter ff_vf_codecview = {
     .priv_size     = sizeof(CodecViewContext),
     .query_formats = query_formats,
     .inputs        = codecview_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(codecview_inputs),
     .outputs       = codecview_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(codecview_outputs),
     .priv_class    = &codecview_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c
index 4e13ce97b9..2d83cc4bc2 100644
--- a/libavfilter/vf_colorbalance.c
+++ b/libavfilter/vf_colorbalance.c
@@ -427,7 +427,6 @@ static const AVFilterPad colorbalance_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorbalance_outputs[] = {
@@ -436,7 +435,6 @@ static const AVFilterPad colorbalance_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_colorbalance = {
@@ -446,7 +444,9 @@ const AVFilter ff_vf_colorbalance = {
     .priv_class    = &colorbalance_class,
     .query_formats = query_formats,
     .inputs        = colorbalance_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorbalance_inputs),
     .outputs       = colorbalance_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorbalance_outputs),
     .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 9a538ddf5f..0146fb6ee3 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -787,7 +787,6 @@ static const AVFilterPad colorchannelmixer_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorchannelmixer_outputs[] = {
@@ -796,7 +795,6 @@ static const AVFilterPad colorchannelmixer_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_colorchannelmixer = {
@@ -807,7 +805,9 @@ const AVFilter ff_vf_colorchannelmixer = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = colorchannelmixer_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorchannelmixer_inputs),
     .outputs       = colorchannelmixer_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorchannelmixer_outputs),
     .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 e44d9afa01..c5ca6ba0f4 100644
--- a/libavfilter/vf_colorconstancy.c
+++ b/libavfilter/vf_colorconstancy.c
@@ -725,7 +725,6 @@ static const AVFilterPad colorconstancy_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorconstancy_outputs[] = {
@@ -733,7 +732,6 @@ static const AVFilterPad colorconstancy_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #if CONFIG_GREYEDGE_FILTER
@@ -755,7 +753,9 @@ const AVFilter ff_vf_greyedge = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = colorconstancy_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(colorconstancy_inputs),
     .outputs       = colorconstancy_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(colorconstancy_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
 
diff --git a/libavfilter/vf_colorcontrast.c b/libavfilter/vf_colorcontrast.c
index b5b547b46f..6e981709d6 100644
--- a/libavfilter/vf_colorcontrast.c
+++ b/libavfilter/vf_colorcontrast.c
@@ -368,7 +368,6 @@ static const AVFilterPad colorcontrast_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorcontrast_outputs[] = {
@@ -376,7 +375,6 @@ static const AVFilterPad colorcontrast_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ColorContrastContext, x)
@@ -402,7 +400,9 @@ const AVFilter ff_vf_colorcontrast = {
     .priv_class    = &colorcontrast_class,
     .query_formats = query_formats,
     .inputs        = colorcontrast_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorcontrast_inputs),
     .outputs       = colorcontrast_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorcontrast_outputs),
     .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 13ef50ad1d..f86811369f 100644
--- a/libavfilter/vf_colorcorrect.c
+++ b/libavfilter/vf_colorcorrect.c
@@ -179,7 +179,6 @@ static const AVFilterPad colorcorrect_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorcorrect_outputs[] = {
@@ -187,7 +186,6 @@ static const AVFilterPad colorcorrect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ColorCorrectContext, x)
@@ -211,7 +209,9 @@ const AVFilter ff_vf_colorcorrect = {
     .priv_class    = &colorcorrect_class,
     .query_formats = query_formats,
     .inputs        = colorcorrect_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorcorrect_inputs),
     .outputs       = colorcorrect_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorcorrect_outputs),
     .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 653832ab92..b5bd24419f 100644
--- a/libavfilter/vf_colorize.c
+++ b/libavfilter/vf_colorize.c
@@ -269,7 +269,6 @@ static const AVFilterPad colorize_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorize_outputs[] = {
@@ -277,7 +276,6 @@ static const AVFilterPad colorize_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ColorizeContext, x)
@@ -300,7 +298,9 @@ const AVFilter ff_vf_colorize = {
     .priv_class    = &colorize_class,
     .query_formats = query_formats,
     .inputs        = colorize_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorize_inputs),
     .outputs       = colorize_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorize_outputs),
     .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 e0b4372842..ea14ef4dbe 100644
--- a/libavfilter/vf_colorkey.c
+++ b/libavfilter/vf_colorkey.c
@@ -186,7 +186,6 @@ static const AVFilterPad colorkey_inputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorkey_outputs[] = {
@@ -195,7 +194,6 @@ static const AVFilterPad colorkey_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ColorkeyContext, x)
@@ -220,7 +218,9 @@ const AVFilter ff_vf_colorkey = {
     .query_formats = query_formats,
     .init          = init_filter,
     .inputs        = colorkey_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorkey_inputs),
     .outputs       = colorkey_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorkey_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
@@ -245,7 +245,9 @@ const AVFilter ff_vf_colorhold = {
     .query_formats = query_formats,
     .init          = init_filter,
     .inputs        = colorkey_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorkey_inputs),
     .outputs       = colorkey_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorkey_outputs),
     .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 cd312ea53e..e14204de8f 100644
--- a/libavfilter/vf_colorkey_opencl.c
+++ b/libavfilter/vf_colorkey_opencl.c
@@ -206,7 +206,6 @@ static const AVFilterPad colorkey_opencl_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorkey_opencl_outputs[] = {
@@ -215,7 +214,6 @@ static const AVFilterPad colorkey_opencl_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ColorkeyOpenCLContext, x)
@@ -239,6 +237,8 @@ const AVFilter ff_vf_colorkey_opencl = {
     .uninit         = &colorkey_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = colorkey_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(colorkey_opencl_inputs),
     .outputs        = colorkey_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(colorkey_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE
 };
diff --git a/libavfilter/vf_colorlevels.c b/libavfilter/vf_colorlevels.c
index 8bc0d96df0..8b126295de 100644
--- a/libavfilter/vf_colorlevels.c
+++ b/libavfilter/vf_colorlevels.c
@@ -304,7 +304,6 @@ static const AVFilterPad colorlevels_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad colorlevels_outputs[] = {
@@ -312,7 +311,6 @@ static const AVFilterPad colorlevels_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_colorlevels = {
@@ -322,7 +320,9 @@ const AVFilter ff_vf_colorlevels = {
     .priv_class    = &colorlevels_class,
     .query_formats = query_formats,
     .inputs        = colorlevels_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(colorlevels_inputs),
     .outputs       = colorlevels_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(colorlevels_outputs),
     .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 c304f2dba8..cdd4d11ff4 100644
--- a/libavfilter/vf_colormatrix.c
+++ b/libavfilter/vf_colormatrix.c
@@ -496,7 +496,6 @@ static const AVFilterPad colormatrix_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad colormatrix_outputs[] = {
@@ -504,7 +503,6 @@ static const AVFilterPad colormatrix_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_colormatrix = {
@@ -514,7 +512,9 @@ const AVFilter ff_vf_colormatrix = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = colormatrix_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(colormatrix_inputs),
     .outputs       = colormatrix_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(colormatrix_outputs),
     .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 65e072d137..0c23cf3cda 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -1057,7 +1057,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1066,7 +1065,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_colorspace = {
@@ -1078,6 +1076,8 @@ const AVFilter ff_vf_colorspace = {
     .priv_size       = sizeof(ColorSpaceContext),
     .priv_class      = &colorspace_class,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_colortemperature.c b/libavfilter/vf_colortemperature.c
index 1a4c9261f6..b0cfa85556 100644
--- a/libavfilter/vf_colortemperature.c
+++ b/libavfilter/vf_colortemperature.c
@@ -334,7 +334,6 @@ static const AVFilterPad inputs[] = {
         .config_props   = config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -342,7 +341,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ColorTemperatureContext, x)
@@ -364,7 +362,9 @@ const AVFilter ff_vf_colortemperature = {
     .priv_class    = &colortemperature_class,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 c0fc7356bd..3123cd523e 100644
--- a/libavfilter/vf_convolution.c
+++ b/libavfilter/vf_convolution.c
@@ -889,7 +889,6 @@ static const AVFilterPad convolution_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad convolution_outputs[] = {
@@ -897,7 +896,6 @@ static const AVFilterPad convolution_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #if CONFIG_CONVOLUTION_FILTER
@@ -910,7 +908,9 @@ const AVFilter ff_vf_convolution = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = convolution_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(convolution_inputs),
     .outputs       = convolution_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(convolution_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -939,7 +939,9 @@ const AVFilter ff_vf_prewitt = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = convolution_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(convolution_inputs),
     .outputs       = convolution_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(convolution_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -959,7 +961,9 @@ const AVFilter ff_vf_sobel = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = convolution_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(convolution_inputs),
     .outputs       = convolution_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(convolution_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -979,7 +983,9 @@ const AVFilter ff_vf_roberts = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = convolution_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(convolution_inputs),
     .outputs       = convolution_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(convolution_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -999,7 +1005,9 @@ const AVFilter ff_vf_kirsch = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = convolution_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(convolution_inputs),
     .outputs       = convolution_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(convolution_outputs),
     .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 c6218d3cd6..ef525e7e94 100644
--- a/libavfilter/vf_convolution_opencl.c
+++ b/libavfilter/vf_convolution_opencl.c
@@ -327,7 +327,6 @@ static const AVFilterPad convolution_opencl_inputs[] = {
         .filter_frame = &convolution_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad convolution_opencl_outputs[] = {
@@ -336,7 +335,6 @@ static const AVFilterPad convolution_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ConvolutionOpenCLContext, x)
@@ -371,7 +369,9 @@ const AVFilter ff_vf_convolution_opencl = {
     .uninit         = &convolution_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = convolution_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(convolution_opencl_inputs),
     .outputs        = convolution_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(convolution_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -397,7 +397,9 @@ const AVFilter ff_vf_sobel_opencl = {
     .uninit         = &convolution_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = convolution_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(convolution_opencl_inputs),
     .outputs        = convolution_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(convolution_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -423,7 +425,9 @@ const AVFilter ff_vf_prewitt_opencl = {
     .uninit         = &convolution_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = convolution_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(convolution_opencl_inputs),
     .outputs        = convolution_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(convolution_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -449,7 +453,9 @@ const AVFilter ff_vf_roberts_opencl = {
     .uninit         = &convolution_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = convolution_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(convolution_opencl_inputs),
     .outputs        = convolution_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(convolution_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_convolve.c b/libavfilter/vf_convolve.c
index a0066bbd39..62a2798215 100644
--- a/libavfilter/vf_convolve.c
+++ b/libavfilter/vf_convolve.c
@@ -609,7 +609,6 @@ static const AVFilterPad convolve_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_input_impulse,
     },
-    { NULL }
 };
 
 static const AVFilterPad convolve_outputs[] = {
@@ -618,7 +617,6 @@ static const AVFilterPad convolve_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #if CONFIG_CONVOLVE_FILTER
@@ -636,7 +634,9 @@ const AVFilter ff_vf_convolve = {
     .priv_size     = sizeof(ConvolveContext),
     .priv_class    = &convolve_class,
     .inputs        = convolve_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(convolve_inputs),
     .outputs       = convolve_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(convolve_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
@@ -666,7 +666,9 @@ const AVFilter ff_vf_deconvolve = {
     .priv_size     = sizeof(ConvolveContext),
     .priv_class    = &deconvolve_class,
     .inputs        = convolve_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(convolve_inputs),
     .outputs       = convolve_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(convolve_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index f50ac70c92..2d243fa155 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -70,7 +70,6 @@ static const AVFilterPad avfilter_vf_copy_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_copy_outputs[] = {
@@ -78,13 +77,14 @@ static const AVFilterPad avfilter_vf_copy_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_copy = {
     .name        = "copy",
     .description = NULL_IF_CONFIG_SMALL("Copy the input video unchanged to the output."),
     .inputs      = avfilter_vf_copy_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_copy_inputs),
     .outputs     = avfilter_vf_copy_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_copy_outputs),
     .query_formats = query_formats,
 };
diff --git a/libavfilter/vf_cover_rect.c b/libavfilter/vf_cover_rect.c
index 337778224d..0b7f6169de 100644
--- a/libavfilter/vf_cover_rect.c
+++ b/libavfilter/vf_cover_rect.c
@@ -236,7 +236,6 @@ static const AVFilterPad cover_rect_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad cover_rect_outputs[] = {
@@ -244,7 +243,6 @@ static const AVFilterPad cover_rect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_cover_rect = {
@@ -255,6 +253,8 @@ const AVFilter ff_vf_cover_rect = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = cover_rect_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(cover_rect_inputs),
     .outputs         = cover_rect_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(cover_rect_outputs),
     .priv_class      = &cover_rect_class,
 };
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 9cc9ec2844..b2e2a5b23a 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -380,7 +380,6 @@ static const AVFilterPad avfilter_vf_crop_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_crop_outputs[] = {
@@ -389,7 +388,6 @@ static const AVFilterPad avfilter_vf_crop_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_crop = {
@@ -400,6 +398,8 @@ const AVFilter ff_vf_crop = {
     .query_formats   = query_formats,
     .uninit          = uninit,
     .inputs          = avfilter_vf_crop_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_crop_inputs),
     .outputs         = avfilter_vf_crop_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_crop_outputs),
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index deeb9e480a..35f03f5995 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -263,7 +263,6 @@ static const AVFilterPad avfilter_vf_cropdetect_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_cropdetect_outputs[] = {
@@ -271,7 +270,6 @@ static const AVFilterPad avfilter_vf_cropdetect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_cropdetect = {
@@ -282,6 +280,8 @@ const AVFilter ff_vf_cropdetect = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_cropdetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_cropdetect_inputs),
     .outputs       = avfilter_vf_cropdetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_cropdetect_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 64cfea1527..e309354c36 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -802,7 +802,6 @@ static const AVFilterPad curves_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad curves_outputs[] = {
@@ -810,7 +809,6 @@ static const AVFilterPad curves_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_curves = {
@@ -821,7 +819,9 @@ const AVFilter ff_vf_curves = {
     .uninit        = curves_uninit,
     .query_formats = query_formats,
     .inputs        = curves_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(curves_inputs),
     .outputs       = curves_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(curves_outputs),
     .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 63c93fd98d..d45cd2d659 100644
--- a/libavfilter/vf_datascope.c
+++ b/libavfilter/vf_datascope.c
@@ -437,7 +437,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -446,7 +445,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_datascope = {
@@ -456,7 +454,9 @@ const AVFilter ff_vf_datascope = {
     .priv_class    = &datascope_class,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
@@ -727,7 +727,6 @@ static const AVFilterPad pixscope_inputs[] = {
         .filter_frame   = pixscope_filter_frame,
         .config_props   = pixscope_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad pixscope_outputs[] = {
@@ -735,7 +734,6 @@ static const AVFilterPad pixscope_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_pixscope = {
@@ -745,7 +743,9 @@ const AVFilter ff_vf_pixscope = {
     .priv_class    = &pixscope_class,
     .query_formats = query_formats,
     .inputs        = pixscope_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(pixscope_inputs),
     .outputs       = pixscope_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(pixscope_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = pixscope_process_command,
 };
@@ -1133,7 +1133,6 @@ static const AVFilterPad oscilloscope_inputs[] = {
         .config_props   = oscilloscope_config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad oscilloscope_outputs[] = {
@@ -1141,7 +1140,6 @@ static const AVFilterPad oscilloscope_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_oscilloscope = {
@@ -1152,7 +1150,9 @@ const AVFilter ff_vf_oscilloscope = {
     .query_formats = query_formats,
     .uninit        = oscilloscope_uninit,
     .inputs        = oscilloscope_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(oscilloscope_inputs),
     .outputs       = oscilloscope_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(oscilloscope_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = oscilloscope_process_command,
 };
diff --git a/libavfilter/vf_dblur.c b/libavfilter/vf_dblur.c
index dcb6635c95..ee1ff56c61 100644
--- a/libavfilter/vf_dblur.c
+++ b/libavfilter/vf_dblur.c
@@ -281,7 +281,6 @@ static const AVFilterPad dblur_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad dblur_outputs[] = {
@@ -289,7 +288,6 @@ static const AVFilterPad dblur_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_dblur = {
@@ -300,7 +298,9 @@ const AVFilter ff_vf_dblur = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = dblur_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(dblur_inputs),
     .outputs       = dblur_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(dblur_outputs),
     .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 c7f949f9f5..f200ff87bd 100644
--- a/libavfilter/vf_dctdnoiz.c
+++ b/libavfilter/vf_dctdnoiz.c
@@ -814,7 +814,6 @@ static const AVFilterPad dctdnoiz_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad dctdnoiz_outputs[] = {
@@ -822,7 +821,6 @@ static const AVFilterPad dctdnoiz_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_dctdnoiz = {
@@ -833,7 +831,9 @@ const AVFilter ff_vf_dctdnoiz = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = dctdnoiz_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(dctdnoiz_inputs),
     .outputs       = dctdnoiz_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(dctdnoiz_outputs),
     .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 aa560bd9fb..611397a6d2 100644
--- a/libavfilter/vf_deband.c
+++ b/libavfilter/vf_deband.c
@@ -460,7 +460,6 @@ static const AVFilterPad avfilter_vf_deband_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_deband_outputs[] = {
@@ -468,7 +467,6 @@ static const AVFilterPad avfilter_vf_deband_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_deband = {
@@ -479,7 +477,9 @@ const AVFilter ff_vf_deband = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_deband_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_deband_inputs),
     .outputs       = avfilter_vf_deband_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_deband_outputs),
     .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 2d91fe358b..05bb98a463 100644
--- a/libavfilter/vf_deblock.c
+++ b/libavfilter/vf_deblock.c
@@ -401,7 +401,6 @@ static const AVFilterPad inputs[] = {
         .type           = AVMEDIA_TYPE_VIDEO,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -410,7 +409,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(deblock);
@@ -422,7 +420,9 @@ const AVFilter ff_vf_deblock = {
     .priv_class    = &deblock_class,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
index 72ed349427..bbd7e1955f 100644
--- a/libavfilter/vf_decimate.c
+++ b/libavfilter/vf_decimate.c
@@ -431,7 +431,6 @@ static const AVFilterPad decimate_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_decimate = {
@@ -443,6 +442,7 @@ const AVFilter ff_vf_decimate = {
     .priv_size     = sizeof(DecimateContext),
     .query_formats = query_formats,
     .outputs       = decimate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(decimate_outputs),
     .priv_class    = &decimate_class,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_dedot.c b/libavfilter/vf_dedot.c
index b79d4a51c4..df60dc1dbe 100644
--- a/libavfilter/vf_dedot.c
+++ b/libavfilter/vf_dedot.c
@@ -387,7 +387,6 @@ static const AVFilterPad inputs[] = {
         .name           = "default",
         .type           = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -396,7 +395,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(dedot);
@@ -410,6 +408,8 @@ const AVFilter ff_vf_dedot = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_deflicker.c b/libavfilter/vf_deflicker.c
index 1ce8a482e8..51dbadb715 100644
--- a/libavfilter/vf_deflicker.c
+++ b/libavfilter/vf_deflicker.c
@@ -454,7 +454,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -463,7 +462,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_deflicker = {
@@ -474,5 +472,7 @@ const AVFilter ff_vf_deflicker = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c
index 3c2d87c7c8..b51dc598fc 100644
--- a/libavfilter/vf_deinterlace_qsv.c
+++ b/libavfilter/vf_deinterlace_qsv.c
@@ -581,7 +581,6 @@ static const AVFilterPad qsvdeint_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = qsvdeint_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad qsvdeint_outputs[] = {
@@ -591,7 +590,6 @@ static const AVFilterPad qsvdeint_outputs[] = {
         .config_props  = qsvdeint_config_props,
         .request_frame = qsvdeint_request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_deinterlace_qsv = {
@@ -605,7 +603,9 @@ const AVFilter ff_vf_deinterlace_qsv = {
     .priv_class = &qsvdeint_class,
 
     .inputs    = qsvdeint_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(qsvdeint_inputs),
     .outputs   = qsvdeint_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(qsvdeint_outputs),
 
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c
index fa71947098..3f60f40b94 100644
--- a/libavfilter/vf_deinterlace_vaapi.c
+++ b/libavfilter/vf_deinterlace_vaapi.c
@@ -369,7 +369,6 @@ static const AVFilterPad deint_vaapi_inputs[] = {
         .filter_frame = &deint_vaapi_filter_frame,
         .config_props = &ff_vaapi_vpp_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad deint_vaapi_outputs[] = {
@@ -378,7 +377,6 @@ static const AVFilterPad deint_vaapi_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &deint_vaapi_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_deinterlace_vaapi = {
@@ -389,7 +387,9 @@ const AVFilter ff_vf_deinterlace_vaapi = {
     .uninit         = &ff_vaapi_vpp_ctx_uninit,
     .query_formats  = &ff_vaapi_vpp_query_formats,
     .inputs         = deint_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(deint_vaapi_inputs),
     .outputs        = deint_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(deint_vaapi_outputs),
     .priv_class     = &deint_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_dejudder.c b/libavfilter/vf_dejudder.c
index 5816f82322..f18158ff62 100644
--- a/libavfilter/vf_dejudder.c
+++ b/libavfilter/vf_dejudder.c
@@ -163,7 +163,6 @@ static const AVFilterPad dejudder_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad dejudder_outputs[] = {
@@ -172,7 +171,6 @@ static const AVFilterPad dejudder_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = config_out_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_dejudder = {
@@ -181,7 +179,9 @@ const AVFilter ff_vf_dejudder = {
     .priv_size   = sizeof(DejudderContext),
     .priv_class  = &dejudder_class,
     .inputs      = dejudder_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(dejudder_inputs),
     .outputs     = dejudder_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(dejudder_outputs),
     .init        = dejudder_init,
     .uninit      = dejudder_uninit,
 };
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index 9838301702..ba814bdeac 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -387,7 +387,6 @@ static const AVFilterPad avfilter_vf_delogo_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_delogo_outputs[] = {
@@ -395,7 +394,6 @@ static const AVFilterPad avfilter_vf_delogo_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_delogo = {
@@ -407,6 +405,8 @@ const AVFilter ff_vf_delogo = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_delogo_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_delogo_inputs),
     .outputs       = avfilter_vf_delogo_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_delogo_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_derain.c b/libavfilter/vf_derain.c
index 5037f3a5f7..4d93232640 100644
--- a/libavfilter/vf_derain.c
+++ b/libavfilter/vf_derain.c
@@ -115,7 +115,6 @@ static const AVFilterPad derain_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad derain_outputs[] = {
@@ -123,7 +122,6 @@ static const AVFilterPad derain_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_derain = {
@@ -134,7 +132,9 @@ const AVFilter ff_vf_derain = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = derain_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(derain_inputs),
     .outputs       = derain_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(derain_outputs),
     .priv_class    = &derain_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index 4ff6a94702..bd8531ba13 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -540,7 +540,6 @@ static const AVFilterPad deshake_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad deshake_outputs[] = {
@@ -548,7 +547,6 @@ static const AVFilterPad deshake_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_deshake = {
@@ -559,6 +557,8 @@ const AVFilter ff_vf_deshake = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = deshake_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(deshake_inputs),
     .outputs       = deshake_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(deshake_outputs),
     .priv_class    = &deshake_class,
 };
diff --git a/libavfilter/vf_deshake_opencl.c b/libavfilter/vf_deshake_opencl.c
index 2fd682003f..cecca78249 100644
--- a/libavfilter/vf_deshake_opencl.c
+++ b/libavfilter/vf_deshake_opencl.c
@@ -2141,7 +2141,6 @@ static const AVFilterPad deshake_opencl_inputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad deshake_opencl_outputs[] = {
@@ -2150,7 +2149,6 @@ static const AVFilterPad deshake_opencl_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(DeshakeOpenCLContext, x)
@@ -2197,6 +2195,8 @@ const AVFilter ff_vf_deshake_opencl = {
     .query_formats  = &ff_opencl_filter_query_formats,
     .activate       = activate,
     .inputs         = deshake_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(deshake_opencl_inputs),
     .outputs        = deshake_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(deshake_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE
 };
diff --git a/libavfilter/vf_despill.c b/libavfilter/vf_despill.c
index e0990d7443..8eaede1dad 100644
--- a/libavfilter/vf_despill.c
+++ b/libavfilter/vf_despill.c
@@ -140,7 +140,6 @@ static const AVFilterPad despill_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad despill_outputs[] = {
@@ -149,7 +148,6 @@ static const AVFilterPad despill_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(DespillContext, x)
@@ -178,7 +176,9 @@ const AVFilter ff_vf_despill = {
     .priv_class    = &despill_class,
     .query_formats = query_formats,
     .inputs        = despill_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(despill_inputs),
     .outputs       = despill_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(despill_outputs),
     .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 e345e3062a..fdda60954b 100644
--- a/libavfilter/vf_detelecine.c
+++ b/libavfilter/vf_detelecine.c
@@ -360,7 +360,6 @@ static const AVFilterPad detelecine_inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad detelecine_outputs[] = {
@@ -369,7 +368,6 @@ static const AVFilterPad detelecine_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_detelecine = {
@@ -381,5 +379,7 @@ const AVFilter ff_vf_detelecine = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = detelecine_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(detelecine_inputs),
     .outputs       = detelecine_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(detelecine_outputs),
 };
diff --git a/libavfilter/vf_displace.c b/libavfilter/vf_displace.c
index 9c310e1740..71da73a022 100644
--- a/libavfilter/vf_displace.c
+++ b/libavfilter/vf_displace.c
@@ -388,7 +388,6 @@ static const AVFilterPad displace_inputs[] = {
         .name         = "ymap",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad displace_outputs[] = {
@@ -397,7 +396,6 @@ static const AVFilterPad displace_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_displace = {
@@ -408,7 +406,9 @@ const AVFilter ff_vf_displace = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = displace_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(displace_inputs),
     .outputs       = displace_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(displace_outputs),
     .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 7900255cfe..14ad008265 100644
--- a/libavfilter/vf_dnn_classify.c
+++ b/libavfilter/vf_dnn_classify.c
@@ -309,7 +309,6 @@ static const AVFilterPad dnn_classify_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad dnn_classify_outputs[] = {
@@ -317,7 +316,6 @@ static const AVFilterPad dnn_classify_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_dnn_classify = {
@@ -328,7 +326,9 @@ const AVFilter ff_vf_dnn_classify = {
     .uninit        = dnn_classify_uninit,
     .query_formats = dnn_classify_query_formats,
     .inputs        = dnn_classify_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(dnn_classify_inputs),
     .outputs       = dnn_classify_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(dnn_classify_outputs),
     .priv_class    = &dnn_classify_class,
     .activate      = dnn_classify_activate,
 };
diff --git a/libavfilter/vf_dnn_detect.c b/libavfilter/vf_dnn_detect.c
index d23e30aedd..43f3003d07 100644
--- a/libavfilter/vf_dnn_detect.c
+++ b/libavfilter/vf_dnn_detect.c
@@ -519,7 +519,6 @@ static const AVFilterPad dnn_detect_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad dnn_detect_outputs[] = {
@@ -527,7 +526,6 @@ static const AVFilterPad dnn_detect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_dnn_detect = {
@@ -538,7 +536,9 @@ const AVFilter ff_vf_dnn_detect = {
     .uninit        = dnn_detect_uninit,
     .query_formats = dnn_detect_query_formats,
     .inputs        = dnn_detect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(dnn_detect_inputs),
     .outputs       = dnn_detect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(dnn_detect_outputs),
     .priv_class    = &dnn_detect_class,
     .activate      = dnn_detect_activate,
 };
diff --git a/libavfilter/vf_dnn_processing.c b/libavfilter/vf_dnn_processing.c
index e1d9d24683..eeb5c356e4 100644
--- a/libavfilter/vf_dnn_processing.c
+++ b/libavfilter/vf_dnn_processing.c
@@ -435,7 +435,6 @@ static const AVFilterPad dnn_processing_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad dnn_processing_outputs[] = {
@@ -444,7 +443,6 @@ static const AVFilterPad dnn_processing_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_dnn_processing = {
@@ -455,7 +453,9 @@ const AVFilter ff_vf_dnn_processing = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = dnn_processing_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(dnn_processing_inputs),
     .outputs       = dnn_processing_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(dnn_processing_outputs),
     .priv_class    = &dnn_processing_class,
     .activate      = activate,
 };
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index 1e9e028650..4b5e1a58f6 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -391,7 +391,6 @@ static const AVFilterPad drawbox_inputs[] = {
         .filter_frame   = filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad drawbox_outputs[] = {
@@ -399,7 +398,6 @@ static const AVFilterPad drawbox_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_drawbox = {
@@ -410,7 +408,9 @@ const AVFilter ff_vf_drawbox = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = drawbox_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(drawbox_inputs),
     .outputs       = drawbox_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(drawbox_outputs),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -475,7 +475,6 @@ static const AVFilterPad drawgrid_inputs[] = {
         .filter_frame   = drawgrid_filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad drawgrid_outputs[] = {
@@ -483,7 +482,6 @@ static const AVFilterPad drawgrid_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_drawgrid = {
@@ -494,7 +492,9 @@ const AVFilter ff_vf_drawgrid = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = drawgrid_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(drawgrid_inputs),
     .outputs       = drawgrid_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(drawgrid_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index c4c09894e4..9fabdc665d 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -1619,7 +1619,6 @@ static const AVFilterPad avfilter_vf_drawtext_inputs[] = {
         .config_props   = config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_drawtext_outputs[] = {
@@ -1627,7 +1626,6 @@ static const AVFilterPad avfilter_vf_drawtext_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_drawtext = {
@@ -1639,7 +1637,9 @@ const AVFilter ff_vf_drawtext = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_drawtext_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_drawtext_inputs),
     .outputs       = avfilter_vf_drawtext_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_drawtext_outputs),
     .process_command = command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c
index e21d341fd2..9283f77738 100644
--- a/libavfilter/vf_edgedetect.c
+++ b/libavfilter/vf_edgedetect.c
@@ -420,7 +420,6 @@ static const AVFilterPad edgedetect_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad edgedetect_outputs[] = {
@@ -428,7 +427,6 @@ static const AVFilterPad edgedetect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_edgedetect = {
@@ -439,7 +437,9 @@ const AVFilter ff_vf_edgedetect = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = edgedetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(edgedetect_inputs),
     .outputs       = edgedetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(edgedetect_outputs),
     .priv_class    = &edgedetect_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_elbg.c b/libavfilter/vf_elbg.c
index 008f470068..d4d02487da 100644
--- a/libavfilter/vf_elbg.c
+++ b/libavfilter/vf_elbg.c
@@ -242,7 +242,6 @@ static const AVFilterPad elbg_inputs[] = {
         .filter_frame   = filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad elbg_outputs[] = {
@@ -250,7 +249,6 @@ static const AVFilterPad elbg_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_elbg = {
@@ -262,5 +260,7 @@ const AVFilter ff_vf_elbg = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = elbg_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(elbg_inputs),
     .outputs       = elbg_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(elbg_outputs),
 };
diff --git a/libavfilter/vf_entropy.c b/libavfilter/vf_entropy.c
index 32f4bac95d..87b4edd37f 100644
--- a/libavfilter/vf_entropy.c
+++ b/libavfilter/vf_entropy.c
@@ -182,7 +182,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -190,7 +189,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_entropy = {
@@ -200,7 +198,9 @@ const AVFilter ff_vf_entropy = {
     .uninit         = uninit,
     .query_formats  = query_formats,
     .inputs         = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs        = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
     .priv_class     = &entropy_class,
     .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_epx.c b/libavfilter/vf_epx.c
index 676513c302..df6b2c2632 100644
--- a/libavfilter/vf_epx.c
+++ b/libavfilter/vf_epx.c
@@ -262,7 +262,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -271,14 +270,15 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_epx = {
     .name          = "epx",
     .description   = NULL_IF_CONFIG_SMALL("Scale the input using EPX algorithm."),
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .query_formats = query_formats,
     .priv_size     = sizeof(EPXContext),
     .priv_class    = &epx_class,
diff --git a/libavfilter/vf_eq.c b/libavfilter/vf_eq.c
index 7d740d501a..5f33b564dd 100644
--- a/libavfilter/vf_eq.c
+++ b/libavfilter/vf_eq.c
@@ -338,7 +338,6 @@ static const AVFilterPad eq_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad eq_outputs[] = {
@@ -346,7 +345,6 @@ static const AVFilterPad eq_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(EQContext, x)
@@ -383,7 +381,9 @@ const AVFilter ff_vf_eq = {
     .priv_size       = sizeof(EQContext),
     .priv_class      = &eq_class,
     .inputs          = eq_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(eq_inputs),
     .outputs         = eq_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(eq_outputs),
     .process_command = process_command,
     .query_formats   = query_formats,
     .init            = initialize,
diff --git a/libavfilter/vf_estdif.c b/libavfilter/vf_estdif.c
index 863d453775..724c5e43bb 100644
--- a/libavfilter/vf_estdif.c
+++ b/libavfilter/vf_estdif.c
@@ -562,7 +562,6 @@ static const AVFilterPad estdif_inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad estdif_outputs[] = {
@@ -572,7 +571,6 @@ static const AVFilterPad estdif_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_estdif = {
@@ -583,7 +581,9 @@ const AVFilter ff_vf_estdif = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = estdif_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(estdif_inputs),
     .outputs       = estdif_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(estdif_outputs),
     .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 5374a8396e..e7520405dc 100644
--- a/libavfilter/vf_exposure.c
+++ b/libavfilter/vf_exposure.c
@@ -109,7 +109,6 @@ static const AVFilterPad exposure_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad exposure_outputs[] = {
@@ -117,7 +116,6 @@ static const AVFilterPad exposure_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(ExposureContext, x)
@@ -138,7 +136,9 @@ const AVFilter ff_vf_exposure = {
     .priv_class    = &exposure_class,
     .query_formats = query_formats,
     .inputs        = exposure_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(exposure_inputs),
     .outputs       = exposure_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(exposure_outputs),
     .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 cede3d669e..68cbfe374a 100644
--- a/libavfilter/vf_extractplanes.c
+++ b/libavfilter/vf_extractplanes.c
@@ -376,7 +376,6 @@ static const AVFilterPad extractplanes_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_extractplanes = {
@@ -388,6 +387,7 @@ const AVFilter ff_vf_extractplanes = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = extractplanes_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(extractplanes_inputs),
     .outputs       = NULL,
     .flags         = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
@@ -412,6 +412,7 @@ const AVFilter ff_vf_alphaextract = {
     .uninit         = uninit,
     .query_formats  = query_formats,
     .inputs         = extractplanes_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(extractplanes_inputs),
     .outputs        = NULL,
     .flags          = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 3c65b0f2ac..d00277ed4e 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -557,7 +557,6 @@ static const AVFilterPad avfilter_vf_fade_inputs[] = {
         .filter_frame   = filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_fade_outputs[] = {
@@ -565,7 +564,6 @@ static const AVFilterPad avfilter_vf_fade_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fade = {
@@ -576,7 +574,9 @@ const AVFilter ff_vf_fade = {
     .priv_class    = &fade_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_fade_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_fade_inputs),
     .outputs       = avfilter_vf_fade_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_fade_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS |
                      AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_fftdnoiz.c b/libavfilter/vf_fftdnoiz.c
index 78dde44e80..3fbb65e4f1 100644
--- a/libavfilter/vf_fftdnoiz.c
+++ b/libavfilter/vf_fftdnoiz.c
@@ -672,7 +672,6 @@ static const AVFilterPad fftdnoiz_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad fftdnoiz_outputs[] = {
@@ -681,7 +680,6 @@ static const AVFilterPad fftdnoiz_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fftdnoiz = {
@@ -692,7 +690,9 @@ const AVFilter ff_vf_fftdnoiz = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = fftdnoiz_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(fftdnoiz_inputs),
     .outputs       = fftdnoiz_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(fftdnoiz_outputs),
     .priv_class    = &fftdnoiz_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_fftfilt.c b/libavfilter/vf_fftfilt.c
index bcef9ff7d2..fd3aa88420 100644
--- a/libavfilter/vf_fftfilt.c
+++ b/libavfilter/vf_fftfilt.c
@@ -417,7 +417,6 @@ static const AVFilterPad fftfilt_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad fftfilt_outputs[] = {
@@ -425,7 +424,6 @@ static const AVFilterPad fftfilt_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fftfilt = {
@@ -434,7 +432,9 @@ const AVFilter ff_vf_fftfilt = {
     .priv_size       = sizeof(FFTFILTContext),
     .priv_class      = &fftfilt_class,
     .inputs          = fftfilt_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(fftfilt_inputs),
     .outputs         = fftfilt_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(fftfilt_outputs),
     .query_formats   = query_formats,
     .init            = initialize,
     .uninit          = uninit,
diff --git a/libavfilter/vf_field.c b/libavfilter/vf_field.c
index 555e615d2e..75b67f2f5d 100644
--- a/libavfilter/vf_field.c
+++ b/libavfilter/vf_field.c
@@ -89,7 +89,6 @@ static const AVFilterPad field_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad field_outputs[] = {
@@ -98,7 +97,6 @@ static const AVFilterPad field_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_props_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_field = {
@@ -106,6 +104,8 @@ const AVFilter ff_vf_field = {
     .description = NULL_IF_CONFIG_SMALL("Extract a field from the input video."),
     .priv_size   = sizeof(FieldContext),
     .inputs      = field_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(field_inputs),
     .outputs     = field_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(field_outputs),
     .priv_class  = &field_class,
 };
diff --git a/libavfilter/vf_fieldhint.c b/libavfilter/vf_fieldhint.c
index a6c0237f02..64ca640611 100644
--- a/libavfilter/vf_fieldhint.c
+++ b/libavfilter/vf_fieldhint.c
@@ -284,7 +284,6 @@ static const AVFilterPad inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -293,7 +292,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fieldhint = {
@@ -305,5 +303,7 @@ const AVFilter ff_vf_fieldhint = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index 9626737b40..782f424631 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -1037,7 +1037,6 @@ static const AVFilterPad fieldmatch_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fieldmatch = {
@@ -1050,6 +1049,7 @@ const AVFilter ff_vf_fieldmatch = {
     .uninit         = fieldmatch_uninit,
     .inputs         = NULL,
     .outputs        = fieldmatch_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(fieldmatch_outputs),
     .priv_class     = &fieldmatch_class,
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index eefa417fb3..57b9aab197 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -173,7 +173,6 @@ static const AVFilterPad avfilter_vf_fieldorder_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_fieldorder_outputs[] = {
@@ -181,7 +180,6 @@ static const AVFilterPad avfilter_vf_fieldorder_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fieldorder = {
@@ -191,6 +189,8 @@ const AVFilter ff_vf_fieldorder = {
     .priv_class    = &fieldorder_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_fieldorder_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_fieldorder_inputs),
     .outputs       = avfilter_vf_fieldorder_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_fieldorder_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_fillborders.c b/libavfilter/vf_fillborders.c
index 2515bc9de9..6fb4a20255 100644
--- a/libavfilter/vf_fillborders.c
+++ b/libavfilter/vf_fillborders.c
@@ -712,7 +712,6 @@ static const AVFilterPad fillborders_inputs[] = {
         .filter_frame   = filter_frame,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad fillborders_outputs[] = {
@@ -720,7 +719,6 @@ static const AVFilterPad fillborders_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fillborders = {
@@ -730,7 +728,9 @@ const AVFilter ff_vf_fillborders = {
     .priv_class    = &fillborders_class,
     .query_formats = query_formats,
     .inputs        = fillborders_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(fillborders_inputs),
     .outputs       = fillborders_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(fillborders_outputs),
     .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 1a94655b6b..64d6e3532e 100644
--- a/libavfilter/vf_find_rect.c
+++ b/libavfilter/vf_find_rect.c
@@ -292,7 +292,6 @@ static const AVFilterPad foc_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad foc_outputs[] = {
@@ -300,7 +299,6 @@ static const AVFilterPad foc_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_find_rect = {
@@ -311,6 +309,8 @@ const AVFilter ff_vf_find_rect = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = foc_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(foc_inputs),
     .outputs         = foc_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(foc_outputs),
     .priv_class      = &find_rect_class,
 };
diff --git a/libavfilter/vf_floodfill.c b/libavfilter/vf_floodfill.c
index 3b17b04c61..fba5cf5d81 100644
--- a/libavfilter/vf_floodfill.c
+++ b/libavfilter/vf_floodfill.c
@@ -390,7 +390,6 @@ static const AVFilterPad floodfill_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad floodfill_outputs[] = {
@@ -398,7 +397,6 @@ static const AVFilterPad floodfill_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(FloodfillContext, x)
@@ -428,6 +426,8 @@ const AVFilter ff_vf_floodfill = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = floodfill_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(floodfill_inputs),
     .outputs       = floodfill_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(floodfill_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 960d4b0acf..d5cf0cd275 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -155,7 +155,6 @@ static const AVFilterPad avfilter_vf_format_inputs[] = {
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_format_outputs[] = {
@@ -163,7 +162,6 @@ static const AVFilterPad avfilter_vf_format_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_format = {
@@ -179,7 +177,9 @@ const AVFilter ff_vf_format = {
     .priv_class    = &format_class,
 
     .inputs        = avfilter_vf_format_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_format_inputs),
     .outputs       = avfilter_vf_format_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_format_outputs),
 };
 #endif /* CONFIG_FORMAT_FILTER */
 
@@ -194,7 +194,6 @@ static const AVFilterPad avfilter_vf_noformat_inputs[] = {
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_noformat_outputs[] = {
@@ -202,7 +201,6 @@ static const AVFilterPad avfilter_vf_noformat_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_noformat = {
@@ -218,6 +216,8 @@ const AVFilter ff_vf_noformat = {
     .priv_class    = &noformat_class,
 
     .inputs        = avfilter_vf_noformat_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_noformat_inputs),
     .outputs       = avfilter_vf_noformat_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_noformat_outputs),
 };
 #endif /* CONFIG_NOFORMAT_FILTER */
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index fbc845da1b..7ef1ac8a61 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -370,7 +370,6 @@ static const AVFilterPad avfilter_vf_fps_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_fps_outputs[] = {
@@ -379,7 +378,6 @@ static const AVFilterPad avfilter_vf_fps_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fps = {
@@ -391,5 +389,7 @@ const AVFilter ff_vf_fps = {
     .priv_class  = &fps_class,
     .activate    = activate,
     .inputs      = avfilter_vf_fps_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_fps_inputs),
     .outputs     = avfilter_vf_fps_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_fps_outputs),
 };
diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c
index 4fa9b4d144..d671ee7a55 100644
--- a/libavfilter/vf_framepack.c
+++ b/libavfilter/vf_framepack.c
@@ -457,7 +457,6 @@ static const AVFilterPad framepack_inputs[] = {
         .name         = "right",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad framepack_outputs[] = {
@@ -466,7 +465,6 @@ static const AVFilterPad framepack_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_framepack = {
@@ -476,7 +474,9 @@ const AVFilter ff_vf_framepack = {
     .priv_class    = &framepack_class,
     .query_formats = query_formats,
     .inputs        = framepack_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(framepack_inputs),
     .outputs       = framepack_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(framepack_outputs),
     .activate      = activate,
     .uninit        = framepack_uninit,
 };
diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c
index 6b509443a6..e5839e18a5 100644
--- a/libavfilter/vf_framerate.c
+++ b/libavfilter/vf_framerate.c
@@ -429,7 +429,6 @@ static const AVFilterPad framerate_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad framerate_outputs[] = {
@@ -438,7 +437,6 @@ static const AVFilterPad framerate_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_framerate = {
@@ -450,7 +448,9 @@ const AVFilter ff_vf_framerate = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = framerate_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(framerate_inputs),
     .outputs       = framerate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(framerate_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
     .activate      = activate,
 };
diff --git a/libavfilter/vf_framestep.c b/libavfilter/vf_framestep.c
index d61ce0dc56..a187b71cac 100644
--- a/libavfilter/vf_framestep.c
+++ b/libavfilter/vf_framestep.c
@@ -77,7 +77,6 @@ static const AVFilterPad framestep_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad framestep_outputs[] = {
@@ -86,7 +85,6 @@ static const AVFilterPad framestep_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_framestep = {
@@ -95,6 +93,8 @@ const AVFilter ff_vf_framestep = {
     .priv_size   = sizeof(FrameStepContext),
     .priv_class  = &framestep_class,
     .inputs      = framestep_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(framestep_inputs),
     .outputs     = framestep_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(framestep_outputs),
     .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
index 9cf8fbab15..0e7219223c 100644
--- a/libavfilter/vf_freezedetect.c
+++ b/libavfilter/vf_freezedetect.c
@@ -210,7 +210,6 @@ static const AVFilterPad freezedetect_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad freezedetect_outputs[] = {
@@ -218,7 +217,6 @@ static const AVFilterPad freezedetect_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_freezedetect = {
@@ -229,6 +227,8 @@ const AVFilter ff_vf_freezedetect = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = freezedetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(freezedetect_inputs),
     .outputs       = freezedetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(freezedetect_outputs),
     .activate      = activate,
 };
diff --git a/libavfilter/vf_freezeframes.c b/libavfilter/vf_freezeframes.c
index e29eb07cec..11875aad2b 100644
--- a/libavfilter/vf_freezeframes.c
+++ b/libavfilter/vf_freezeframes.c
@@ -142,7 +142,6 @@ static const AVFilterPad freezeframes_inputs[] = {
         .name = "replace",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL },
 };
 
 static const AVFilterPad freezeframes_outputs[] = {
@@ -151,7 +150,6 @@ static const AVFilterPad freezeframes_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL },
 };
 
 const AVFilter ff_vf_freezeframes = {
@@ -160,7 +158,9 @@ const AVFilter ff_vf_freezeframes = {
     .priv_size     = sizeof(FreezeFramesContext),
     .priv_class    = &freezeframes_class,
     .inputs        = freezeframes_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(freezeframes_inputs),
     .outputs       = freezeframes_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(freezeframes_outputs),
     .activate      = activate,
     .uninit        = uninit,
 };
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 00e5ff2444..b2fc6152c7 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -402,7 +402,6 @@ static const AVFilterPad avfilter_vf_frei0r_inputs[] = {
         .config_props = config_input_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_frei0r_outputs[] = {
@@ -410,7 +409,6 @@ static const AVFilterPad avfilter_vf_frei0r_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_frei0r = {
@@ -422,7 +420,9 @@ const AVFilter ff_vf_frei0r = {
     .priv_size     = sizeof(Frei0rContext),
     .priv_class    = &frei0r_class,
     .inputs        = avfilter_vf_frei0r_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_frei0r_inputs),
     .outputs       = avfilter_vf_frei0r_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_frei0r_outputs),
     .process_command = process_command,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
@@ -498,7 +498,6 @@ static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = {
         .request_frame = source_request_frame,
         .config_props  = source_config_props
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_frei0r_src = {
@@ -511,4 +510,5 @@ const AVFilter ff_vsrc_frei0r_src = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_frei0r_src_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_frei0r_src_outputs),
 };
diff --git a/libavfilter/vf_fspp.c b/libavfilter/vf_fspp.c
index 44d22fc1e4..60bd56ae54 100644
--- a/libavfilter/vf_fspp.c
+++ b/libavfilter/vf_fspp.c
@@ -656,7 +656,6 @@ static const AVFilterPad fspp_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad fspp_outputs[] = {
@@ -664,7 +663,6 @@ static const AVFilterPad fspp_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_fspp = {
@@ -674,7 +672,9 @@ const AVFilter ff_vf_fspp = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = fspp_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(fspp_inputs),
     .outputs         = fspp_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(fspp_outputs),
     .priv_class      = &fspp_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_gblur.c b/libavfilter/vf_gblur.c
index 3f61275658..c5cc4dca68 100644
--- a/libavfilter/vf_gblur.c
+++ b/libavfilter/vf_gblur.c
@@ -382,7 +382,6 @@ static const AVFilterPad gblur_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad gblur_outputs[] = {
@@ -390,7 +389,6 @@ static const AVFilterPad gblur_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_gblur = {
@@ -401,7 +399,9 @@ const AVFilter ff_vf_gblur = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = gblur_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(gblur_inputs),
     .outputs       = gblur_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(gblur_outputs),
     .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 d9bb6ac256..a5f32f1d6b 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -481,7 +481,6 @@ static const AVFilterPad geq_inputs[] = {
         .config_props = geq_config_props,
         .filter_frame = geq_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad geq_outputs[] = {
@@ -489,7 +488,6 @@ static const AVFilterPad geq_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_geq = {
@@ -500,7 +498,9 @@ const AVFilter ff_vf_geq = {
     .uninit        = geq_uninit,
     .query_formats = geq_query_formats,
     .inputs        = geq_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(geq_inputs),
     .outputs       = geq_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(geq_outputs),
     .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 af77b13d4d..dcbe1658d6 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -240,7 +240,6 @@ static const AVFilterPad avfilter_vf_gradfun_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_gradfun_outputs[] = {
@@ -248,7 +247,6 @@ static const AVFilterPad avfilter_vf_gradfun_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_gradfun = {
@@ -260,6 +258,8 @@ const AVFilter ff_vf_gradfun = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_gradfun_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_gradfun_inputs),
     .outputs       = avfilter_vf_gradfun_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_gradfun_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_guided.c b/libavfilter/vf_guided.c
index 202a6a0586..7ef05b8ab3 100644
--- a/libavfilter/vf_guided.c
+++ b/libavfilter/vf_guided.c
@@ -486,7 +486,6 @@ static const AVFilterPad guided_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_guided = {
@@ -500,6 +499,7 @@ const AVFilter ff_vf_guided = {
     .activate        = activate,
     .inputs          = NULL,
     .outputs         = guided_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(guided_outputs),
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index 2a0defda6c..2ecd26a975 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -234,7 +234,6 @@ static const AVFilterPad avfilter_vf_hflip_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_hflip_outputs[] = {
@@ -242,7 +241,6 @@ static const AVFilterPad avfilter_vf_hflip_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hflip = {
@@ -252,6 +250,8 @@ const AVFilter ff_vf_hflip = {
     .priv_class    = &hflip_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_hflip_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_hflip_inputs),
     .outputs       = avfilter_vf_hflip_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_hflip_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_histeq.c b/libavfilter/vf_histeq.c
index dea819e672..46f03008ac 100644
--- a/libavfilter/vf_histeq.c
+++ b/libavfilter/vf_histeq.c
@@ -259,7 +259,6 @@ static const AVFilterPad histeq_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad histeq_outputs[] = {
@@ -267,7 +266,6 @@ static const AVFilterPad histeq_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_histeq = {
@@ -277,7 +275,9 @@ const AVFilter ff_vf_histeq = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = histeq_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(histeq_inputs),
     .outputs       = histeq_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(histeq_outputs),
     .priv_class    = &histeq_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
index bd9408c42d..3137bb805d 100644
--- a/libavfilter/vf_histogram.c
+++ b/libavfilter/vf_histogram.c
@@ -488,7 +488,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -497,7 +496,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 #if CONFIG_HISTOGRAM_FILTER
@@ -508,7 +506,9 @@ const AVFilter ff_vf_histogram = {
     .priv_size     = sizeof(HistogramContext),
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .priv_class    = &histogram_class,
 };
 
@@ -550,7 +550,9 @@ const AVFilter ff_vf_thistogram = {
     .priv_size     = sizeof(HistogramContext),
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .uninit        = uninit,
     .priv_class    = &thistogram_class,
 };
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index bd3eb2d01c..2f8b72510f 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -386,7 +386,6 @@ static const AVFilterPad avfilter_vf_hqdn3d_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 
@@ -395,7 +394,6 @@ static const AVFilterPad avfilter_vf_hqdn3d_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hqdn3d = {
@@ -407,7 +405,9 @@ const AVFilter ff_vf_hqdn3d = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_hqdn3d_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_hqdn3d_inputs),
     .outputs       = avfilter_vf_hqdn3d_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_hqdn3d_outputs),
     .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 8b0d794b6e..36e16d6446 100644
--- a/libavfilter/vf_hqx.c
+++ b/libavfilter/vf_hqx.c
@@ -541,7 +541,6 @@ static const AVFilterPad hqx_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad hqx_outputs[] = {
@@ -550,7 +549,6 @@ static const AVFilterPad hqx_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hqx = {
@@ -560,7 +558,9 @@ const AVFilter ff_vf_hqx = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = hqx_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(hqx_inputs),
     .outputs       = hqx_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(hqx_outputs),
     .priv_class    = &hqx_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
index 3d250dbe25..c8f9a8c4ac 100644
--- a/libavfilter/vf_hue.c
+++ b/libavfilter/vf_hue.c
@@ -505,7 +505,6 @@ static const AVFilterPad hue_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad hue_outputs[] = {
@@ -513,7 +512,6 @@ static const AVFilterPad hue_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hue = {
@@ -525,7 +523,9 @@ const AVFilter ff_vf_hue = {
     .query_formats   = query_formats,
     .process_command = process_command,
     .inputs          = hue_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(hue_inputs),
     .outputs         = hue_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(hue_outputs),
     .priv_class      = &hue_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_hwdownload.c b/libavfilter/vf_hwdownload.c
index 4a8fed0688..8e5689ca15 100644
--- a/libavfilter/vf_hwdownload.c
+++ b/libavfilter/vf_hwdownload.c
@@ -180,7 +180,6 @@ static const AVFilterPad hwdownload_inputs[] = {
         .config_props = hwdownload_config_input,
         .filter_frame = hwdownload_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad hwdownload_outputs[] = {
@@ -189,7 +188,6 @@ static const AVFilterPad hwdownload_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = hwdownload_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hwdownload = {
@@ -200,6 +198,8 @@ const AVFilter ff_vf_hwdownload = {
     .priv_size     = sizeof(HWDownloadContext),
     .priv_class    = &hwdownload_class,
     .inputs        = hwdownload_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(hwdownload_inputs),
     .outputs       = hwdownload_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(hwdownload_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c
index d829b47b44..898837ad3b 100644
--- a/libavfilter/vf_hwmap.c
+++ b/libavfilter/vf_hwmap.c
@@ -407,7 +407,6 @@ static const AVFilterPad hwmap_inputs[] = {
         .get_video_buffer = hwmap_get_buffer,
         .filter_frame     = hwmap_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad hwmap_outputs[] = {
@@ -416,7 +415,6 @@ static const AVFilterPad hwmap_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = hwmap_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hwmap = {
@@ -427,6 +425,8 @@ const AVFilter ff_vf_hwmap = {
     .priv_class     = &hwmap_class,
     .query_formats  = hwmap_query_formats,
     .inputs         = hwmap_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(hwmap_inputs),
     .outputs        = hwmap_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(hwmap_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c
index 8263829a39..4aaec3633f 100644
--- a/libavfilter/vf_hwupload.c
+++ b/libavfilter/vf_hwupload.c
@@ -238,7 +238,6 @@ static const AVFilterPad hwupload_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = hwupload_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad hwupload_outputs[] = {
@@ -247,7 +246,6 @@ static const AVFilterPad hwupload_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = hwupload_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hwupload = {
@@ -258,6 +256,8 @@ const AVFilter ff_vf_hwupload = {
     .priv_size     = sizeof(HWUploadContext),
     .priv_class    = &hwupload_class,
     .inputs        = hwupload_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(hwupload_inputs),
     .outputs       = hwupload_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(hwupload_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c
index 138949a5ed..3a400c45db 100644
--- a/libavfilter/vf_hwupload_cuda.c
+++ b/libavfilter/vf_hwupload_cuda.c
@@ -171,7 +171,6 @@ static const AVFilterPad cudaupload_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = cudaupload_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad cudaupload_outputs[] = {
@@ -180,7 +179,6 @@ static const AVFilterPad cudaupload_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = cudaupload_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hwupload_cuda = {
@@ -196,7 +194,9 @@ const AVFilter ff_vf_hwupload_cuda = {
     .priv_class = &cudaupload_class,
 
     .inputs    = cudaupload_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(cudaupload_inputs),
     .outputs   = cudaupload_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(cudaupload_outputs),
 
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_hysteresis.c b/libavfilter/vf_hysteresis.c
index 3732ed5c22..b62abce49e 100644
--- a/libavfilter/vf_hysteresis.c
+++ b/libavfilter/vf_hysteresis.c
@@ -362,7 +362,6 @@ static const AVFilterPad hysteresis_inputs[] = {
         .name         = "alt",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad hysteresis_outputs[] = {
@@ -371,7 +370,6 @@ static const AVFilterPad hysteresis_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_hysteresis = {
@@ -383,7 +381,9 @@ const AVFilter ff_vf_hysteresis = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = hysteresis_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(hysteresis_inputs),
     .outputs       = hysteresis_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(hysteresis_outputs),
     .priv_class    = &hysteresis_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_identity.c b/libavfilter/vf_identity.c
index f47611924e..265698c961 100644
--- a/libavfilter/vf_identity.c
+++ b/libavfilter/vf_identity.c
@@ -392,7 +392,6 @@ static const AVFilterPad identity_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad identity_outputs[] = {
@@ -401,7 +400,6 @@ static const AVFilterPad identity_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 static const AVOption options[] = {
@@ -424,7 +422,9 @@ const AVFilter ff_vf_identity = {
     .priv_size     = sizeof(IdentityContext),
     .priv_class    = &identity_class,
     .inputs        = identity_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(identity_inputs),
     .outputs       = identity_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(identity_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
@@ -446,7 +446,9 @@ const AVFilter ff_vf_msad = {
     .priv_size     = sizeof(IdentityContext),
     .priv_class    = &msad_class,
     .inputs        = identity_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(identity_inputs),
     .outputs       = identity_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(identity_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
 
diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index 54fc08e915..1d62032835 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -428,7 +428,6 @@ static const AVFilterPad idet_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad idet_outputs[] = {
@@ -437,7 +436,6 @@ static const AVFilterPad idet_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_idet = {
@@ -448,6 +446,8 @@ const AVFilter ff_vf_idet = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = idet_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(idet_inputs),
     .outputs       = idet_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(idet_outputs),
     .priv_class    = &idet_class,
 };
diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c
index 9b21f2e7a7..059166907f 100644
--- a/libavfilter/vf_il.c
+++ b/libavfilter/vf_il.c
@@ -187,7 +187,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -195,7 +194,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_il = {
@@ -204,7 +202,9 @@ const AVFilter ff_vf_il = {
     .priv_size     = sizeof(IlContext),
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 a86407beb0..2b59e13129 100644
--- a/libavfilter/vf_kerndeint.c
+++ b/libavfilter/vf_kerndeint.c
@@ -295,7 +295,6 @@ static const AVFilterPad kerndeint_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad kerndeint_outputs[] = {
@@ -303,7 +302,6 @@ static const AVFilterPad kerndeint_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 
@@ -315,5 +313,7 @@ const AVFilter ff_vf_kerndeint = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = kerndeint_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(kerndeint_inputs),
     .outputs       = kerndeint_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(kerndeint_outputs),
 };
diff --git a/libavfilter/vf_lagfun.c b/libavfilter/vf_lagfun.c
index e147479671..c3870d84b6 100644
--- a/libavfilter/vf_lagfun.c
+++ b/libavfilter/vf_lagfun.c
@@ -205,7 +205,6 @@ static const AVFilterPad inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -214,7 +213,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(lagfun);
@@ -227,7 +225,9 @@ const AVFilter ff_vf_lagfun = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .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 7bd008d3d8..2125562cee 100644
--- a/libavfilter/vf_lenscorrection.c
+++ b/libavfilter/vf_lenscorrection.c
@@ -345,7 +345,6 @@ static const AVFilterPad lenscorrection_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad lenscorrection_outputs[] = {
@@ -354,7 +353,6 @@ static const AVFilterPad lenscorrection_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_lenscorrection = {
@@ -363,7 +361,9 @@ const AVFilter ff_vf_lenscorrection = {
     .priv_size     = sizeof(LenscorrectionCtx),
     .query_formats = query_formats,
     .inputs        = lenscorrection_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(lenscorrection_inputs),
     .outputs       = lenscorrection_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(lenscorrection_outputs),
     .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 f34add961a..6321ad13b0 100644
--- a/libavfilter/vf_lensfun.c
+++ b/libavfilter/vf_lensfun.c
@@ -524,7 +524,6 @@ static const AVFilterPad lensfun_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad lensfun_outputs[] = {
@@ -532,7 +531,6 @@ static const AVFilterPad lensfun_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_lensfun = {
@@ -543,7 +541,9 @@ const AVFilter ff_vf_lensfun = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = lensfun_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(lensfun_inputs),
     .outputs       = lensfun_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(lensfun_outputs),
     .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 221a8ac4c2..1932552c05 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -416,7 +416,6 @@ static const AVFilterPad avfilter_vf_ocv_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_ocv_outputs[] = {
@@ -424,7 +423,6 @@ static const AVFilterPad avfilter_vf_ocv_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_ocv = {
@@ -436,5 +434,7 @@ const AVFilter ff_vf_ocv = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = avfilter_vf_ocv_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_ocv_inputs),
     .outputs       = avfilter_vf_ocv_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_ocv_outputs),
 };
diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c
index d2621c7a9f..6d753b2e36 100644
--- a/libavfilter/vf_libvmaf.c
+++ b/libavfilter/vf_libvmaf.c
@@ -353,7 +353,6 @@ static const AVFilterPad libvmaf_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad libvmaf_outputs[] = {
@@ -362,7 +361,6 @@ static const AVFilterPad libvmaf_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_libvmaf = {
@@ -376,5 +374,7 @@ const AVFilter ff_vf_libvmaf = {
     .priv_size     = sizeof(LIBVMAFContext),
     .priv_class    = &libvmaf_class,
     .inputs        = libvmaf_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(libvmaf_inputs),
     .outputs       = libvmaf_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(libvmaf_outputs),
 };
diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c
index 04bfbb63d1..71475804ec 100644
--- a/libavfilter/vf_limiter.c
+++ b/libavfilter/vf_limiter.c
@@ -249,7 +249,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -257,7 +256,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_limiter = {
@@ -268,7 +266,9 @@ const AVFilter ff_vf_limiter = {
     .init          = init,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 3f98d5077d..b7f4161225 100644
--- a/libavfilter/vf_lumakey.c
+++ b/libavfilter/vf_lumakey.c
@@ -182,7 +182,6 @@ static const AVFilterPad lumakey_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad lumakey_outputs[] = {
@@ -190,7 +189,6 @@ static const AVFilterPad lumakey_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(LumakeyContext, x)
@@ -212,7 +210,9 @@ const AVFilter ff_vf_lumakey = {
     .priv_class    = &lumakey_class,
     .query_formats = query_formats,
     .inputs        = lumakey_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(lumakey_inputs),
     .outputs       = lumakey_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(lumakey_outputs),
     .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 47c2416da7..71caec4f7e 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -583,13 +583,11 @@ static const AVFilterPad inputs[] = {
       .filter_frame = filter_frame,
       .config_props = config_props,
     },
-    { NULL }
 };
 static const AVFilterPad outputs[] = {
     { .name = "default",
       .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define DEFINE_LUT_FILTER(name_, description_)                          \
@@ -602,7 +600,9 @@ static const AVFilterPad outputs[] = {
         .uninit        = uninit,                                        \
         .query_formats = query_formats,                                 \
         .inputs        = inputs,                                        \
+        .nb_inputs       = FF_ARRAY_ELEMS(inputs),                        \
         .outputs       = outputs,                                       \
+        .nb_outputs      = FF_ARRAY_ELEMS(outputs),                       \
         .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 658a0bfa56..de98334f83 100644
--- a/libavfilter/vf_lut2.c
+++ b/libavfilter/vf_lut2.c
@@ -533,7 +533,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_inputy,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -542,7 +541,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = lut2_config_output,
     },
-    { NULL }
 };
 
 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
@@ -570,7 +568,9 @@ const AVFilter ff_vf_lut2 = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -640,7 +640,6 @@ static const AVFilterPad tlut2_inputs[] = {
         .filter_frame  = tlut2_filter_frame,
         .config_props  = config_inputx,
     },
-    { NULL }
 };
 
 static const AVFilterPad tlut2_outputs[] = {
@@ -649,7 +648,6 @@ static const AVFilterPad tlut2_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tlut2 = {
@@ -661,7 +659,9 @@ const AVFilter ff_vf_tlut2 = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = tlut2_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(tlut2_inputs),
     .outputs       = tlut2_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(tlut2_outputs),
     .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 c86585cf09..ec238c46d7 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -1342,7 +1342,6 @@ static const AVFilterPad lut3d_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad lut3d_outputs[] = {
@@ -1350,7 +1349,6 @@ static const AVFilterPad lut3d_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_lut3d = {
@@ -1361,7 +1359,9 @@ const AVFilter ff_vf_lut3d = {
     .uninit        = lut3d_uninit,
     .query_formats = query_formats,
     .inputs        = lut3d_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(lut3d_inputs),
     .outputs       = lut3d_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(lut3d_outputs),
     .priv_class    = &lut3d_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -1608,7 +1608,6 @@ static const AVFilterPad haldclut_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_clut,
     },
-    { NULL }
 };
 
 static const AVFilterPad haldclut_outputs[] = {
@@ -1617,7 +1616,6 @@ static const AVFilterPad haldclut_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_haldclut = {
@@ -1630,7 +1628,9 @@ const AVFilter ff_vf_haldclut = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = haldclut_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(haldclut_inputs),
     .outputs       = haldclut_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(haldclut_outputs),
     .priv_class    = &haldclut_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
@@ -2274,7 +2274,6 @@ static const AVFilterPad lut1d_inputs[] = {
         .filter_frame = filter_frame_1d,
         .config_props = config_input_1d,
     },
-    { NULL }
 };
 
 static const AVFilterPad lut1d_outputs[] = {
@@ -2282,7 +2281,6 @@ static const AVFilterPad lut1d_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_lut1d = {
@@ -2292,7 +2290,9 @@ const AVFilter ff_vf_lut1d = {
     .init          = lut1d_init,
     .query_formats = query_formats,
     .inputs        = lut1d_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(lut1d_inputs),
     .outputs       = lut1d_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(lut1d_outputs),
     .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 050e3ae6e4..40430dd12e 100644
--- a/libavfilter/vf_maskedclamp.c
+++ b/libavfilter/vf_maskedclamp.c
@@ -304,7 +304,6 @@ static const AVFilterPad maskedclamp_inputs[] = {
         .name         = "bright",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad maskedclamp_outputs[] = {
@@ -313,7 +312,6 @@ static const AVFilterPad maskedclamp_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_maskedclamp = {
@@ -324,7 +322,9 @@ const AVFilter ff_vf_maskedclamp = {
     .activate      = activate,
     .query_formats = query_formats,
     .inputs        = maskedclamp_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(maskedclamp_inputs),
     .outputs       = maskedclamp_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(maskedclamp_outputs),
     .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 28ac0dd52d..0283b5c094 100644
--- a/libavfilter/vf_maskedmerge.c
+++ b/libavfilter/vf_maskedmerge.c
@@ -305,7 +305,6 @@ static const AVFilterPad maskedmerge_inputs[] = {
         .name         = "mask",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad maskedmerge_outputs[] = {
@@ -314,7 +313,6 @@ static const AVFilterPad maskedmerge_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_maskedmerge = {
@@ -325,7 +323,9 @@ const AVFilter ff_vf_maskedmerge = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = maskedmerge_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(maskedmerge_inputs),
     .outputs       = maskedmerge_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(maskedmerge_outputs),
     .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 0d79fc177f..932cea0d8f 100644
--- a/libavfilter/vf_maskedminmax.c
+++ b/libavfilter/vf_maskedminmax.c
@@ -313,7 +313,6 @@ static const AVFilterPad maskedminmax_inputs[] = {
         .name         = "filter2",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad maskedminmax_outputs[] = {
@@ -322,7 +321,6 @@ static const AVFilterPad maskedminmax_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #define maskedmin_options maskedminmax_options
@@ -338,7 +336,9 @@ const AVFilter ff_vf_maskedmin = {
     .activate      = activate,
     .query_formats = query_formats,
     .inputs        = maskedminmax_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(maskedminmax_inputs),
     .outputs       = maskedminmax_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(maskedminmax_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
@@ -356,7 +356,9 @@ const AVFilter ff_vf_maskedmax = {
     .activate      = activate,
     .query_formats = query_formats,
     .inputs        = maskedminmax_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(maskedminmax_inputs),
     .outputs       = maskedminmax_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(maskedminmax_outputs),
     .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 518ab54546..cf59fede57 100644
--- a/libavfilter/vf_maskedthreshold.c
+++ b/libavfilter/vf_maskedthreshold.c
@@ -270,7 +270,6 @@ static const AVFilterPad maskedthreshold_inputs[] = {
         .name         = "reference",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad maskedthreshold_outputs[] = {
@@ -279,7 +278,6 @@ static const AVFilterPad maskedthreshold_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(maskedthreshold);
@@ -293,7 +291,9 @@ const AVFilter ff_vf_maskedthreshold = {
     .activate      = activate,
     .query_formats = query_formats,
     .inputs        = maskedthreshold_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(maskedthreshold_inputs),
     .outputs       = maskedthreshold_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(maskedthreshold_outputs),
     .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 0f3e3545b3..d23a65c40b 100644
--- a/libavfilter/vf_maskfun.c
+++ b/libavfilter/vf_maskfun.c
@@ -298,7 +298,6 @@ static const AVFilterPad maskfun_inputs[] = {
         .config_props   = config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad maskfun_outputs[] = {
@@ -306,7 +305,6 @@ static const AVFilterPad maskfun_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_maskfun = {
@@ -316,7 +314,9 @@ const AVFilter ff_vf_maskfun = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = maskfun_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(maskfun_inputs),
     .outputs       = maskfun_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(maskfun_outputs),
     .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 1a49829d5b..ad7f38e575 100644
--- a/libavfilter/vf_mcdeint.c
+++ b/libavfilter/vf_mcdeint.c
@@ -293,7 +293,6 @@ static const AVFilterPad mcdeint_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad mcdeint_outputs[] = {
@@ -301,7 +300,6 @@ static const AVFilterPad mcdeint_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_mcdeint = {
@@ -311,6 +309,8 @@ const AVFilter ff_vf_mcdeint = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = mcdeint_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(mcdeint_inputs),
     .outputs       = mcdeint_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(mcdeint_outputs),
     .priv_class    = &mcdeint_class,
 };
diff --git a/libavfilter/vf_median.c b/libavfilter/vf_median.c
index 1e66ab87ff..8189503f20 100644
--- a/libavfilter/vf_median.c
+++ b/libavfilter/vf_median.c
@@ -273,7 +273,6 @@ static const AVFilterPad median_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad median_outputs[] = {
@@ -281,7 +280,6 @@ static const AVFilterPad median_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_median = {
@@ -292,7 +290,9 @@ const AVFilter ff_vf_median = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = median_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(median_inputs),
     .outputs       = median_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(median_outputs),
     .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 30888f62af..6803d57feb 100644
--- a/libavfilter/vf_mergeplanes.c
+++ b/libavfilter/vf_mergeplanes.c
@@ -293,7 +293,6 @@ static const AVFilterPad mergeplanes_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_mergeplanes = {
@@ -307,5 +306,6 @@ const AVFilter ff_vf_mergeplanes = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = mergeplanes_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(mergeplanes_outputs),
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_mestimate.c b/libavfilter/vf_mestimate.c
index f57f2578ec..af094b0ac1 100644
--- a/libavfilter/vf_mestimate.c
+++ b/libavfilter/vf_mestimate.c
@@ -356,7 +356,6 @@ static const AVFilterPad mestimate_inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad mestimate_outputs[] = {
@@ -364,7 +363,6 @@ static const AVFilterPad mestimate_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_mestimate = {
@@ -375,5 +373,7 @@ const AVFilter ff_vf_mestimate = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = mestimate_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(mestimate_inputs),
     .outputs       = mestimate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(mestimate_outputs),
 };
diff --git a/libavfilter/vf_midequalizer.c b/libavfilter/vf_midequalizer.c
index ba50fa0a82..c727b828e9 100644
--- a/libavfilter/vf_midequalizer.c
+++ b/libavfilter/vf_midequalizer.c
@@ -363,7 +363,6 @@ static const AVFilterPad midequalizer_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input1,
     },
-    { NULL }
 };
 
 static const AVFilterPad midequalizer_outputs[] = {
@@ -372,7 +371,6 @@ static const AVFilterPad midequalizer_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_midequalizer = {
@@ -383,7 +381,9 @@ const AVFilter ff_vf_midequalizer = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = midequalizer_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(midequalizer_inputs),
     .outputs       = midequalizer_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(midequalizer_outputs),
     .priv_class    = &midequalizer_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c
index c6aed7755f..a96f50db36 100644
--- a/libavfilter/vf_minterpolate.c
+++ b/libavfilter/vf_minterpolate.c
@@ -1245,7 +1245,6 @@ static const AVFilterPad minterpolate_inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad minterpolate_outputs[] = {
@@ -1254,7 +1253,6 @@ static const AVFilterPad minterpolate_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_minterpolate = {
@@ -1265,5 +1263,7 @@ const AVFilter ff_vf_minterpolate = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = minterpolate_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(minterpolate_inputs),
     .outputs       = minterpolate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(minterpolate_outputs),
 };
diff --git a/libavfilter/vf_misc_vaapi.c b/libavfilter/vf_misc_vaapi.c
index ca0d46ff19..9b6452595a 100644
--- a/libavfilter/vf_misc_vaapi.c
+++ b/libavfilter/vf_misc_vaapi.c
@@ -222,7 +222,6 @@ static const AVFilterPad misc_vaapi_inputs[] = {
         .filter_frame = &misc_vaapi_filter_frame,
         .config_props = &ff_vaapi_vpp_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad misc_vaapi_outputs[] = {
@@ -231,7 +230,6 @@ static const AVFilterPad misc_vaapi_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_vaapi_vpp_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_denoise_vaapi = {
@@ -242,7 +240,9 @@ const AVFilter ff_vf_denoise_vaapi = {
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
     .query_formats = &ff_vaapi_vpp_query_formats,
     .inputs        = misc_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(misc_vaapi_inputs),
     .outputs       = misc_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(misc_vaapi_outputs),
     .priv_class    = &denoise_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
@@ -255,7 +255,9 @@ const AVFilter ff_vf_sharpness_vaapi = {
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
     .query_formats = &ff_vaapi_vpp_query_formats,
     .inputs        = misc_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(misc_vaapi_inputs),
     .outputs       = misc_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(misc_vaapi_outputs),
     .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 0ca60d5522..9992cdf9f0 100644
--- a/libavfilter/vf_mix.c
+++ b/libavfilter/vf_mix.c
@@ -352,7 +352,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #if CONFIG_MIX_FILTER
@@ -365,6 +364,7 @@ const AVFilter ff_vf_mix = {
     .priv_class    = &mix_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
@@ -430,7 +430,6 @@ static const AVFilterPad inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = tmix_filter_frame,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(tmix);
@@ -442,7 +441,9 @@ const AVFilter ff_vf_tmix = {
     .priv_class    = &tmix_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .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 29e70f8c25..f393ca764b 100644
--- a/libavfilter/vf_monochrome.c
+++ b/libavfilter/vf_monochrome.c
@@ -277,7 +277,6 @@ static const AVFilterPad monochrome_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad monochrome_outputs[] = {
@@ -285,7 +284,6 @@ static const AVFilterPad monochrome_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(MonochromeContext, x)
@@ -308,7 +306,9 @@ const AVFilter ff_vf_monochrome = {
     .priv_class    = &monochrome_class,
     .query_formats = query_formats,
     .inputs        = monochrome_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(monochrome_inputs),
     .outputs       = monochrome_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(monochrome_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c
index 53f5a56ef4..558087317b 100644
--- a/libavfilter/vf_mpdecimate.c
+++ b/libavfilter/vf_mpdecimate.c
@@ -231,7 +231,6 @@ static const AVFilterPad mpdecimate_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad mpdecimate_outputs[] = {
@@ -239,7 +238,6 @@ static const AVFilterPad mpdecimate_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_mpdecimate = {
@@ -251,5 +249,7 @@ const AVFilter ff_vf_mpdecimate = {
     .priv_class    = &mpdecimate_class,
     .query_formats = query_formats,
     .inputs        = mpdecimate_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(mpdecimate_inputs),
     .outputs       = mpdecimate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(mpdecimate_outputs),
 };
diff --git a/libavfilter/vf_neighbor.c b/libavfilter/vf_neighbor.c
index a2e9a51165..ffc9a9842c 100644
--- a/libavfilter/vf_neighbor.c
+++ b/libavfilter/vf_neighbor.c
@@ -341,7 +341,6 @@ static const AVFilterPad neighbor_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad neighbor_outputs[] = {
@@ -349,7 +348,6 @@ static const AVFilterPad neighbor_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(NContext, x)
@@ -365,7 +363,9 @@ const AVFilter ff_vf_##name_ = {                                   \
     .priv_class    = &name_##_class,                         \
     .query_formats = query_formats,                          \
     .inputs        = neighbor_inputs,                        \
+    .nb_inputs     = FF_ARRAY_ELEMS(neighbor_inputs),        \
     .outputs       = neighbor_outputs,                       \
+    .nb_outputs    = FF_ARRAY_ELEMS(neighbor_outputs),       \
     .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 e00245089d..bf46cf6a62 100644
--- a/libavfilter/vf_neighbor_opencl.c
+++ b/libavfilter/vf_neighbor_opencl.c
@@ -245,7 +245,6 @@ static const AVFilterPad neighbor_opencl_inputs[] = {
         .filter_frame = &neighbor_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad neighbor_opencl_outputs[] = {
@@ -254,7 +253,6 @@ static const AVFilterPad neighbor_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(NeighborOpenCLContext, x)
@@ -282,7 +280,9 @@ const AVFilter ff_vf_erosion_opencl = {
     .uninit         = &neighbor_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = neighbor_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(neighbor_opencl_inputs),
     .outputs        = neighbor_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(neighbor_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -310,7 +310,9 @@ const AVFilter ff_vf_dilation_opencl = {
     .uninit         = &neighbor_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = neighbor_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(neighbor_opencl_inputs),
     .outputs        = neighbor_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(neighbor_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_nlmeans.c b/libavfilter/vf_nlmeans.c
index 7451bec4ae..4ef172be21 100644
--- a/libavfilter/vf_nlmeans.c
+++ b/libavfilter/vf_nlmeans.c
@@ -566,7 +566,6 @@ static const AVFilterPad nlmeans_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad nlmeans_outputs[] = {
@@ -574,7 +573,6 @@ static const AVFilterPad nlmeans_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_nlmeans = {
@@ -585,7 +583,9 @@ const AVFilter ff_vf_nlmeans = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = nlmeans_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(nlmeans_inputs),
     .outputs       = nlmeans_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(nlmeans_outputs),
     .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 0f16b2fe49..174314f885 100644
--- a/libavfilter/vf_nlmeans_opencl.c
+++ b/libavfilter/vf_nlmeans_opencl.c
@@ -417,7 +417,6 @@ static const AVFilterPad nlmeans_opencl_inputs[] = {
         .filter_frame = &nlmeans_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad nlmeans_opencl_outputs[] = {
@@ -426,7 +425,6 @@ static const AVFilterPad nlmeans_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_nlmeans_opencl = {
@@ -438,6 +436,8 @@ const AVFilter ff_vf_nlmeans_opencl = {
     .uninit         = &nlmeans_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = nlmeans_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(nlmeans_opencl_inputs),
     .outputs        = nlmeans_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(nlmeans_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_nnedi.c b/libavfilter/vf_nnedi.c
index b802ca5433..9b79b50a35 100644
--- a/libavfilter/vf_nnedi.c
+++ b/libavfilter/vf_nnedi.c
@@ -1143,7 +1143,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1153,7 +1152,6 @@ static const AVFilterPad outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_nnedi = {
@@ -1165,7 +1163,9 @@ const AVFilter ff_vf_nnedi = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(outputs),
     .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 73e88063e9..3deacd2f51 100644
--- a/libavfilter/vf_noise.c
+++ b/libavfilter/vf_noise.c
@@ -326,7 +326,6 @@ static const AVFilterPad noise_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad noise_outputs[] = {
@@ -334,7 +333,6 @@ static const AVFilterPad noise_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_noise = {
@@ -345,7 +343,9 @@ const AVFilter ff_vf_noise = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = noise_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(noise_inputs),
     .outputs       = noise_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(noise_outputs),
     .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 3a2127ade3..c6a42c9862 100644
--- a/libavfilter/vf_normalize.c
+++ b/libavfilter/vf_normalize.c
@@ -519,7 +519,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -527,7 +526,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_normalize = {
@@ -538,7 +536,9 @@ const AVFilter ff_vf_normalize = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
     .process_command = ff_filter_process_command,
 };
diff --git a/libavfilter/vf_null.c b/libavfilter/vf_null.c
index 1f0e85e900..422152a4ed 100644
--- a/libavfilter/vf_null.c
+++ b/libavfilter/vf_null.c
@@ -31,7 +31,6 @@ static const AVFilterPad avfilter_vf_null_inputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_null_outputs[] = {
@@ -39,12 +38,13 @@ static const AVFilterPad avfilter_vf_null_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_null = {
     .name        = "null",
     .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
     .inputs      = avfilter_vf_null_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_null_inputs),
     .outputs     = avfilter_vf_null_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_null_outputs),
 };
diff --git a/libavfilter/vf_ocr.c b/libavfilter/vf_ocr.c
index 6de474025a..46042bc460 100644
--- a/libavfilter/vf_ocr.c
+++ b/libavfilter/vf_ocr.c
@@ -135,7 +135,6 @@ static const AVFilterPad ocr_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad ocr_outputs[] = {
@@ -143,7 +142,6 @@ static const AVFilterPad ocr_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_ocr = {
@@ -155,5 +153,7 @@ const AVFilter ff_vf_ocr = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = ocr_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ocr_inputs),
     .outputs       = ocr_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(ocr_outputs),
 };
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 9155de3736..d31d4575d6 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -1094,7 +1094,6 @@ static const AVFilterPad avfilter_vf_overlay_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_overlay,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_overlay_outputs[] = {
@@ -1103,7 +1102,6 @@ static const AVFilterPad avfilter_vf_overlay_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_overlay = {
@@ -1118,7 +1116,9 @@ const AVFilter ff_vf_overlay = {
     .activate      = activate,
     .process_command = process_command,
     .inputs        = avfilter_vf_overlay_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_overlay_inputs),
     .outputs       = avfilter_vf_overlay_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_overlay_outputs),
     .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 37af4e2fa0..d952e72834 100644
--- a/libavfilter/vf_overlay_cuda.c
+++ b/libavfilter/vf_overlay_cuda.c
@@ -567,7 +567,6 @@ static const AVFilterPad overlay_cuda_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_overlay,
     },
-    { NULL }
 };
 
 static const AVFilterPad overlay_cuda_outputs[] = {
@@ -576,7 +575,6 @@ static const AVFilterPad overlay_cuda_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = &overlay_cuda_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_overlay_cuda = {
@@ -589,7 +587,9 @@ const AVFilter ff_vf_overlay_cuda = {
     .activate        = &overlay_cuda_activate,
     .query_formats   = &overlay_cuda_query_formats,
     .inputs          = overlay_cuda_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(overlay_cuda_inputs),
     .outputs         = overlay_cuda_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(overlay_cuda_outputs),
     .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 6ba622baaa..430a0871cd 100644
--- a/libavfilter/vf_overlay_opencl.c
+++ b/libavfilter/vf_overlay_opencl.c
@@ -300,7 +300,6 @@ static const AVFilterPad overlay_opencl_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad overlay_opencl_outputs[] = {
@@ -309,7 +308,6 @@ static const AVFilterPad overlay_opencl_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = &overlay_opencl_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_overlay_opencl = {
@@ -322,6 +320,8 @@ const AVFilter ff_vf_overlay_opencl = {
     .query_formats   = &ff_opencl_filter_query_formats,
     .activate        = &overlay_opencl_activate,
     .inputs          = overlay_opencl_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(overlay_opencl_inputs),
     .outputs         = overlay_opencl_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(overlay_opencl_outputs),
     .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 14c4c37a3c..eb2f2660a4 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -403,7 +403,6 @@ static const AVFilterPad overlay_qsv_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_overlay_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad overlay_qsv_outputs[] = {
@@ -412,7 +411,6 @@ static const AVFilterPad overlay_qsv_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_overlay_qsv = {
@@ -425,7 +423,9 @@ const AVFilter ff_vf_overlay_qsv = {
     .uninit         = overlay_qsv_uninit,
     .activate       = activate,
     .inputs         = overlay_qsv_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(overlay_qsv_inputs),
     .outputs        = overlay_qsv_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(overlay_qsv_outputs),
     .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 8dd3bd2092..a1ebea8c13 100644
--- a/libavfilter/vf_overlay_vulkan.c
+++ b/libavfilter/vf_overlay_vulkan.c
@@ -463,7 +463,6 @@ static const AVFilterPad overlay_vulkan_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_vk_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad overlay_vulkan_outputs[] = {
@@ -472,7 +471,6 @@ static const AVFilterPad overlay_vulkan_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &overlay_vulkan_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_overlay_vulkan = {
@@ -484,7 +482,9 @@ const AVFilter ff_vf_overlay_vulkan = {
     .query_formats  = &ff_vk_filter_query_formats,
     .activate       = &overlay_vulkan_activate,
     .inputs         = overlay_vulkan_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(overlay_vulkan_inputs),
     .outputs        = overlay_vulkan_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(overlay_vulkan_outputs),
     .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 f16a06e3b8..20d0d2d443 100644
--- a/libavfilter/vf_owdenoise.c
+++ b/libavfilter/vf_owdenoise.c
@@ -354,7 +354,6 @@ static const AVFilterPad owdenoise_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad owdenoise_outputs[] = {
@@ -362,7 +361,6 @@ static const AVFilterPad owdenoise_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_owdenoise = {
@@ -372,7 +370,9 @@ const AVFilter ff_vf_owdenoise = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = owdenoise_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(owdenoise_inputs),
     .outputs       = owdenoise_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(owdenoise_outputs),
     .priv_class    = &owdenoise_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index 871f2930af..dc78593289 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -441,7 +441,6 @@ static const AVFilterPad avfilter_vf_pad_inputs[] = {
         .get_video_buffer = get_video_buffer,
         .filter_frame     = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_pad_outputs[] = {
@@ -450,7 +449,6 @@ static const AVFilterPad avfilter_vf_pad_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_pad = {
@@ -460,5 +458,7 @@ const AVFilter ff_vf_pad = {
     .priv_class    = &pad_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_pad_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_pad_inputs),
     .outputs       = avfilter_vf_pad_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_pad_outputs),
 };
diff --git a/libavfilter/vf_pad_opencl.c b/libavfilter/vf_pad_opencl.c
index 8155a96e03..cf2e95f314 100644
--- a/libavfilter/vf_pad_opencl.c
+++ b/libavfilter/vf_pad_opencl.c
@@ -354,7 +354,6 @@ static const AVFilterPad pad_opencl_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad pad_opencl_outputs[] = {
@@ -363,7 +362,6 @@ static const AVFilterPad pad_opencl_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &pad_opencl_config_output,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(PadOpenCLContext, x)
@@ -392,6 +390,8 @@ const AVFilter ff_vf_pad_opencl = {
     .uninit         = &pad_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = pad_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(pad_opencl_inputs),
     .outputs        = pad_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(pad_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE
 };
diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index ef8bc181c5..bfd462f9ae 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -557,7 +557,6 @@ static const AVFilterPad palettegen_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad palettegen_outputs[] = {
@@ -567,7 +566,6 @@ static const AVFilterPad palettegen_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_palettegen = {
@@ -577,6 +575,8 @@ const AVFilter ff_vf_palettegen = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = palettegen_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(palettegen_inputs),
     .outputs       = palettegen_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(palettegen_outputs),
     .priv_class    = &palettegen_class,
 };
diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index f07ef5d760..01e35aede7 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -1122,7 +1122,6 @@ static const AVFilterPad paletteuse_inputs[] = {
         .type           = AVMEDIA_TYPE_VIDEO,
         .config_props   = config_input_palette,
     },
-    { NULL }
 };
 
 static const AVFilterPad paletteuse_outputs[] = {
@@ -1131,7 +1130,6 @@ static const AVFilterPad paletteuse_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_paletteuse = {
@@ -1143,6 +1141,8 @@ const AVFilter ff_vf_paletteuse = {
     .uninit        = uninit,
     .activate      = activate,
     .inputs        = paletteuse_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(paletteuse_inputs),
     .outputs       = paletteuse_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(paletteuse_outputs),
     .priv_class    = &paletteuse_class,
 };
diff --git a/libavfilter/vf_perspective.c b/libavfilter/vf_perspective.c
index a3fa080f21..461acace74 100644
--- a/libavfilter/vf_perspective.c
+++ b/libavfilter/vf_perspective.c
@@ -500,7 +500,6 @@ static const AVFilterPad perspective_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad perspective_outputs[] = {
@@ -508,7 +507,6 @@ static const AVFilterPad perspective_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_perspective = {
@@ -519,7 +517,9 @@ const AVFilter ff_vf_perspective = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = perspective_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(perspective_inputs),
     .outputs       = perspective_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(perspective_outputs),
     .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 556620d36c..40f15accd5 100644
--- a/libavfilter/vf_phase.c
+++ b/libavfilter/vf_phase.c
@@ -224,7 +224,6 @@ static const AVFilterPad phase_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad phase_outputs[] = {
@@ -232,7 +231,6 @@ static const AVFilterPad phase_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_phase = {
@@ -243,7 +241,9 @@ const AVFilter ff_vf_phase = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = phase_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(phase_inputs),
     .outputs       = phase_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(phase_outputs),
     .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 dd3d957bfa..f95324fed4 100644
--- a/libavfilter/vf_photosensitivity.c
+++ b/libavfilter/vf_photosensitivity.c
@@ -318,7 +318,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -326,7 +325,6 @@ static const AVFilterPad outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_photosensitivity = {
@@ -337,5 +335,7 @@ const AVFilter ff_vf_photosensitivity = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index b56839d994..f8adee65e3 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -113,7 +113,6 @@ static const AVFilterPad avfilter_vf_pixdesctest_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_pixdesctest_outputs[] = {
@@ -121,7 +120,6 @@ static const AVFilterPad avfilter_vf_pixdesctest_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_pixdesctest = {
@@ -130,5 +128,7 @@ const AVFilter ff_vf_pixdesctest = {
     .priv_size   = sizeof(PixdescTestContext),
     .uninit      = uninit,
     .inputs      = avfilter_vf_pixdesctest_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_pixdesctest_inputs),
     .outputs     = avfilter_vf_pixdesctest_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_pixdesctest_outputs),
 };
diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c
index 5cd89932f8..e125289663 100644
--- a/libavfilter/vf_pp.c
+++ b/libavfilter/vf_pp.c
@@ -180,7 +180,6 @@ static const AVFilterPad pp_inputs[] = {
         .config_props = pp_config_props,
         .filter_frame = pp_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad pp_outputs[] = {
@@ -188,7 +187,6 @@ static const AVFilterPad pp_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_pp = {
@@ -199,7 +197,9 @@ const AVFilter ff_vf_pp = {
     .uninit          = pp_uninit,
     .query_formats   = pp_query_formats,
     .inputs          = pp_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(pp_inputs),
     .outputs         = pp_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(pp_outputs),
     .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 a9a2fa3d19..1c080c870e 100644
--- a/libavfilter/vf_pp7.c
+++ b/libavfilter/vf_pp7.c
@@ -390,7 +390,6 @@ static const AVFilterPad pp7_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad pp7_outputs[] = {
@@ -398,7 +397,6 @@ static const AVFilterPad pp7_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_pp7 = {
@@ -408,7 +406,9 @@ const AVFilter ff_vf_pp7 = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = pp7_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(pp7_inputs),
     .outputs         = pp7_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(pp7_outputs),
     .priv_class      = &pp7_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c
index b5d0ca6d67..8670fcf88b 100644
--- a/libavfilter/vf_premultiply.c
+++ b/libavfilter/vf_premultiply.c
@@ -819,7 +819,6 @@ static const AVFilterPad premultiply_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #if CONFIG_PREMULTIPLY_FILTER
@@ -834,6 +833,7 @@ const AVFilter ff_vf_premultiply = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = premultiply_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(premultiply_outputs),
     .priv_class    = &premultiply_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_DYNAMIC_INPUTS |
@@ -857,6 +857,7 @@ const AVFilter ff_vf_unpremultiply = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = premultiply_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(premultiply_outputs),
     .priv_class    = &unpremultiply_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
                      AVFILTER_FLAG_DYNAMIC_INPUTS |
diff --git a/libavfilter/vf_procamp_vaapi.c b/libavfilter/vf_procamp_vaapi.c
index 5527556d09..5327fcfd35 100644
--- a/libavfilter/vf_procamp_vaapi.c
+++ b/libavfilter/vf_procamp_vaapi.c
@@ -219,7 +219,6 @@ static const AVFilterPad procamp_vaapi_inputs[] = {
         .filter_frame = &procamp_vaapi_filter_frame,
         .config_props = &ff_vaapi_vpp_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad procamp_vaapi_outputs[] = {
@@ -228,7 +227,6 @@ static const AVFilterPad procamp_vaapi_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_vaapi_vpp_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_procamp_vaapi = {
@@ -239,7 +237,9 @@ const AVFilter ff_vf_procamp_vaapi = {
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
     .query_formats = &ff_vaapi_vpp_query_formats,
     .inputs        = procamp_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(procamp_vaapi_inputs),
     .outputs       = procamp_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(procamp_vaapi_outputs),
     .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 4b38baeb3c..b76c589258 100644
--- a/libavfilter/vf_program_opencl.c
+++ b/libavfilter/vf_program_opencl.c
@@ -359,7 +359,6 @@ static const AVFilterPad program_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &program_opencl_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_program_opencl = {
@@ -374,6 +373,7 @@ const AVFilter ff_vf_program_opencl = {
     .activate       = &program_opencl_activate,
     .inputs         = NULL,
     .outputs        = program_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(program_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
@@ -412,7 +412,6 @@ static const AVFilterPad openclsrc_outputs[] = {
         .config_props  = &program_opencl_config_output,
         .request_frame = &program_opencl_request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_openclsrc = {
@@ -425,6 +424,7 @@ const AVFilter ff_vsrc_openclsrc = {
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = NULL,
     .outputs        = openclsrc_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(openclsrc_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
 
diff --git a/libavfilter/vf_pseudocolor.c b/libavfilter/vf_pseudocolor.c
index ec14a0c363..eb0f956182 100644
--- a/libavfilter/vf_pseudocolor.c
+++ b/libavfilter/vf_pseudocolor.c
@@ -896,7 +896,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -904,7 +903,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static av_cold void uninit(AVFilterContext *ctx)
@@ -928,7 +926,9 @@ const AVFilter ff_vf_pseudocolor = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .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 e5459d3f34..3d470c058c 100644
--- a/libavfilter/vf_psnr.c
+++ b/libavfilter/vf_psnr.c
@@ -455,7 +455,6 @@ static const AVFilterPad psnr_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad psnr_outputs[] = {
@@ -464,7 +463,6 @@ static const AVFilterPad psnr_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_psnr = {
@@ -478,6 +476,8 @@ const AVFilter ff_vf_psnr = {
     .priv_size     = sizeof(PSNRContext),
     .priv_class    = &psnr_class,
     .inputs        = psnr_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(psnr_inputs),
     .outputs       = psnr_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(psnr_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c
index 00d3a8dc51..57e1b81aed 100644
--- a/libavfilter/vf_pullup.c
+++ b/libavfilter/vf_pullup.c
@@ -753,7 +753,6 @@ static const AVFilterPad pullup_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad pullup_outputs[] = {
@@ -761,7 +760,6 @@ static const AVFilterPad pullup_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_pullup = {
@@ -772,5 +770,7 @@ const AVFilter ff_vf_pullup = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = pullup_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(pullup_inputs),
     .outputs       = pullup_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(pullup_outputs),
 };
diff --git a/libavfilter/vf_qp.c b/libavfilter/vf_qp.c
index c932d45a76..761f3447e7 100644
--- a/libavfilter/vf_qp.c
+++ b/libavfilter/vf_qp.c
@@ -182,7 +182,6 @@ static const AVFilterPad qp_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad qp_outputs[] = {
@@ -190,7 +189,6 @@ static const AVFilterPad qp_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_qp = {
@@ -198,7 +196,9 @@ const AVFilter ff_vf_qp = {
     .description   = NULL_IF_CONFIG_SMALL("Change video quantization parameters."),
     .priv_size     = sizeof(QPContext),
     .inputs        = qp_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(qp_inputs),
     .outputs       = qp_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(qp_outputs),
     .priv_class    = &qp_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_random.c b/libavfilter/vf_random.c
index 5e4c30a3b5..ffe1bb2b17 100644
--- a/libavfilter/vf_random.c
+++ b/libavfilter/vf_random.c
@@ -127,7 +127,6 @@ static const AVFilterPad random_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad random_outputs[] = {
@@ -136,7 +135,6 @@ static const AVFilterPad random_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_random = {
@@ -147,5 +145,7 @@ const AVFilter ff_vf_random = {
     .init        = init,
     .uninit      = uninit,
     .inputs      = random_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(random_inputs),
     .outputs     = random_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(random_outputs),
 };
diff --git a/libavfilter/vf_readeia608.c b/libavfilter/vf_readeia608.c
index 9558e938ab..0852946e7a 100644
--- a/libavfilter/vf_readeia608.c
+++ b/libavfilter/vf_readeia608.c
@@ -545,7 +545,6 @@ static const AVFilterPad readeia608_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad readeia608_outputs[] = {
@@ -553,7 +552,6 @@ static const AVFilterPad readeia608_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_readeia608 = {
@@ -563,7 +561,9 @@ const AVFilter ff_vf_readeia608 = {
     .priv_class    = &readeia608_class,
     .query_formats = query_formats,
     .inputs        = readeia608_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(readeia608_inputs),
     .outputs       = readeia608_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(readeia608_outputs),
     .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 25cfa5f32d..82b764a2a9 100644
--- a/libavfilter/vf_readvitc.c
+++ b/libavfilter/vf_readvitc.c
@@ -235,7 +235,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -243,7 +242,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_readvitc = {
@@ -252,7 +250,9 @@ const AVFilter ff_vf_readvitc = {
     .priv_size     = sizeof(ReadVitcContext),
     .priv_class    = &readvitc_class,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .init          = init,
     .query_formats = query_formats,
 };
diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c
index 5ab6199d71..9d05434599 100644
--- a/libavfilter/vf_remap.c
+++ b/libavfilter/vf_remap.c
@@ -386,7 +386,6 @@ static const AVFilterPad remap_inputs[] = {
         .name         = "ymap",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad remap_outputs[] = {
@@ -395,7 +394,6 @@ static const AVFilterPad remap_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_remap = {
@@ -406,7 +404,9 @@ const AVFilter ff_vf_remap = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = remap_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(remap_inputs),
     .outputs       = remap_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(remap_outputs),
     .priv_class    = &remap_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_removegrain.c b/libavfilter/vf_removegrain.c
index 75b3ec35bb..532b8a5d39 100644
--- a/libavfilter/vf_removegrain.c
+++ b/libavfilter/vf_removegrain.c
@@ -637,7 +637,6 @@ static const AVFilterPad removegrain_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad removegrain_outputs[] = {
@@ -645,7 +644,6 @@ static const AVFilterPad removegrain_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_removegrain = {
@@ -654,7 +652,9 @@ const AVFilter ff_vf_removegrain = {
     .priv_size     = sizeof(RemoveGrainContext),
     .query_formats = query_formats,
     .inputs        = removegrain_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(removegrain_inputs),
     .outputs       = removegrain_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(removegrain_outputs),
     .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 4bb81a8a5b..c7425fd628 100644
--- a/libavfilter/vf_removelogo.c
+++ b/libavfilter/vf_removelogo.c
@@ -562,7 +562,6 @@ static const AVFilterPad removelogo_inputs[] = {
         .config_props = config_props_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad removelogo_outputs[] = {
@@ -570,7 +569,6 @@ static const AVFilterPad removelogo_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_removelogo = {
@@ -581,7 +579,9 @@ const AVFilter ff_vf_removelogo = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = removelogo_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(removelogo_inputs),
     .outputs       = removelogo_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(removelogo_outputs),
     .priv_class    = &removelogo_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_repeatfields.c b/libavfilter/vf_repeatfields.c
index 1e2abd3a82..741f9de492 100644
--- a/libavfilter/vf_repeatfields.c
+++ b/libavfilter/vf_repeatfields.c
@@ -170,7 +170,6 @@ static const AVFilterPad repeatfields_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad repeatfields_outputs[] = {
@@ -178,7 +177,6 @@ static const AVFilterPad repeatfields_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_repeatfields = {
@@ -187,6 +185,8 @@ const AVFilter ff_vf_repeatfields = {
     .priv_size     = sizeof(RepeatFieldsContext),
     .uninit        = uninit,
     .inputs        = repeatfields_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(repeatfields_inputs),
     .outputs       = repeatfields_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(repeatfields_outputs),
     .query_formats = query_formats,
 };
diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c
index f16207cbff..f8da37e538 100644
--- a/libavfilter/vf_rotate.c
+++ b/libavfilter/vf_rotate.c
@@ -588,7 +588,6 @@ static const AVFilterPad rotate_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad rotate_outputs[] = {
@@ -597,7 +596,6 @@ static const AVFilterPad rotate_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_rotate = {
@@ -609,7 +607,9 @@ const AVFilter ff_vf_rotate = {
     .query_formats = query_formats,
     .process_command = process_command,
     .inputs        = rotate_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(rotate_inputs),
     .outputs       = rotate_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(rotate_outputs),
     .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 12fbe40655..405dbbafec 100644
--- a/libavfilter/vf_sab.c
+++ b/libavfilter/vf_sab.c
@@ -312,7 +312,6 @@ static const AVFilterPad sab_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad sab_outputs[] = {
@@ -320,7 +319,6 @@ static const AVFilterPad sab_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_sab = {
@@ -331,7 +329,9 @@ const AVFilter ff_vf_sab = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = sab_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(sab_inputs),
     .outputs       = sab_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(sab_outputs),
     .priv_class    = &sab_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 160ad8b584..0f074595c4 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -957,7 +957,6 @@ static const AVFilterPad avfilter_vf_scale_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_scale_outputs[] = {
@@ -966,7 +965,6 @@ static const AVFilterPad avfilter_vf_scale_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale = {
@@ -978,7 +976,9 @@ const AVFilter ff_vf_scale = {
     .priv_size       = sizeof(ScaleContext),
     .priv_class      = &scale_class,
     .inputs          = avfilter_vf_scale_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_scale_inputs),
     .outputs         = avfilter_vf_scale_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_scale_outputs),
     .process_command = process_command,
 };
 
@@ -1002,7 +1002,6 @@ static const AVFilterPad avfilter_vf_scale2ref_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_scale2ref_outputs[] = {
@@ -1018,7 +1017,6 @@ static const AVFilterPad avfilter_vf_scale2ref_outputs[] = {
         .config_props = config_props_ref,
         .request_frame= request_frame_ref,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale2ref = {
@@ -1030,6 +1028,8 @@ const AVFilter ff_vf_scale2ref = {
     .priv_size       = sizeof(ScaleContext),
     .priv_class      = &scale2ref_class,
     .inputs          = avfilter_vf_scale2ref_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_scale2ref_inputs),
     .outputs         = avfilter_vf_scale2ref_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_scale2ref_outputs),
     .process_command = process_command,
 };
diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c
index f3ea01634b..1d2415f618 100644
--- a/libavfilter/vf_scale_cuda.c
+++ b/libavfilter/vf_scale_cuda.c
@@ -628,7 +628,6 @@ static const AVFilterPad cudascale_inputs[] = {
         .filter_frame = cudascale_filter_frame,
         .get_video_buffer = cudascale_get_video_buffer,
     },
-    { NULL }
 };
 
 static const AVFilterPad cudascale_outputs[] = {
@@ -637,7 +636,6 @@ static const AVFilterPad cudascale_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = cudascale_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale_cuda = {
@@ -652,7 +650,9 @@ const AVFilter ff_vf_scale_cuda = {
     .priv_class = &cudascale_class,
 
     .inputs    = cudascale_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(cudascale_inputs),
     .outputs   = cudascale_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(cudascale_outputs),
 
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c
index 8d2ad3aab7..75a2a23c66 100644
--- a/libavfilter/vf_scale_npp.c
+++ b/libavfilter/vf_scale_npp.c
@@ -579,7 +579,6 @@ static const AVFilterPad nppscale_inputs[] = {
         .type        = AVMEDIA_TYPE_VIDEO,
         .filter_frame = nppscale_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad nppscale_outputs[] = {
@@ -588,7 +587,6 @@ static const AVFilterPad nppscale_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = nppscale_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale_npp = {
@@ -604,7 +602,9 @@ const AVFilter ff_vf_scale_npp = {
     .priv_class = &nppscale_class,
 
     .inputs    = nppscale_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(nppscale_inputs),
     .outputs   = nppscale_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(nppscale_outputs),
 
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c
index 189223a58a..126412fc68 100644
--- a/libavfilter/vf_scale_qsv.c
+++ b/libavfilter/vf_scale_qsv.c
@@ -655,7 +655,6 @@ static const AVFilterPad qsvscale_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = qsvscale_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad qsvscale_outputs[] = {
@@ -664,7 +663,6 @@ static const AVFilterPad qsvscale_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = qsvscale_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale_qsv = {
@@ -679,7 +677,9 @@ const AVFilter ff_vf_scale_qsv = {
     .priv_class = &qsvscale_class,
 
     .inputs    = qsvscale_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(qsvscale_inputs),
     .outputs   = qsvscale_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(qsvscale_outputs),
 
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c
index 41ff93156d..91650456ac 100644
--- a/libavfilter/vf_scale_vaapi.c
+++ b/libavfilter/vf_scale_vaapi.c
@@ -269,7 +269,6 @@ static const AVFilterPad scale_vaapi_inputs[] = {
         .filter_frame = &scale_vaapi_filter_frame,
         .config_props = &ff_vaapi_vpp_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad scale_vaapi_outputs[] = {
@@ -278,7 +277,6 @@ static const AVFilterPad scale_vaapi_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &scale_vaapi_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale_vaapi = {
@@ -289,7 +287,9 @@ const AVFilter ff_vf_scale_vaapi = {
     .uninit        = &ff_vaapi_vpp_ctx_uninit,
     .query_formats = &ff_vaapi_vpp_query_formats,
     .inputs        = scale_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(scale_vaapi_inputs),
     .outputs       = scale_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(scale_vaapi_outputs),
     .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 95503480ef..9f541015dc 100644
--- a/libavfilter/vf_scale_vulkan.c
+++ b/libavfilter/vf_scale_vulkan.c
@@ -512,7 +512,6 @@ static const AVFilterPad scale_vulkan_inputs[] = {
         .filter_frame = &scale_vulkan_filter_frame,
         .config_props = &ff_vk_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad scale_vulkan_outputs[] = {
@@ -521,7 +520,6 @@ static const AVFilterPad scale_vulkan_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &scale_vulkan_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scale_vulkan = {
@@ -532,7 +530,9 @@ const AVFilter ff_vf_scale_vulkan = {
     .uninit         = &scale_vulkan_uninit,
     .query_formats  = &ff_vk_filter_query_formats,
     .inputs         = scale_vulkan_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(scale_vulkan_inputs),
     .outputs        = scale_vulkan_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(scale_vulkan_outputs),
     .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 ff8bf21a9c..a65e7b6ebc 100644
--- a/libavfilter/vf_scdet.c
+++ b/libavfilter/vf_scdet.c
@@ -199,7 +199,6 @@ static const AVFilterPad scdet_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad scdet_outputs[] = {
@@ -207,7 +206,6 @@ static const AVFilterPad scdet_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scdet = {
@@ -218,6 +216,8 @@ const AVFilter ff_vf_scdet = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = scdet_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(scdet_inputs),
     .outputs       = scdet_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(scdet_outputs),
     .activate      = activate,
 };
diff --git a/libavfilter/vf_scroll.c b/libavfilter/vf_scroll.c
index 4b7b45f52a..b8a6308fe9 100644
--- a/libavfilter/vf_scroll.c
+++ b/libavfilter/vf_scroll.c
@@ -200,7 +200,6 @@ static const AVFilterPad scroll_inputs[] = {
         .config_props   = config_input,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad scroll_outputs[] = {
@@ -208,7 +207,6 @@ static const AVFilterPad scroll_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_scroll = {
@@ -218,7 +216,9 @@ const AVFilter ff_vf_scroll = {
     .priv_class    = &scroll_class,
     .query_formats = query_formats,
     .inputs        = scroll_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(scroll_inputs),
     .outputs       = scroll_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(scroll_outputs),
     .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 4733cc48f2..25b44607a0 100644
--- a/libavfilter/vf_selectivecolor.c
+++ b/libavfilter/vf_selectivecolor.c
@@ -459,7 +459,6 @@ static const AVFilterPad selectivecolor_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad selectivecolor_outputs[] = {
@@ -467,7 +466,6 @@ static const AVFilterPad selectivecolor_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_selectivecolor = {
@@ -476,7 +474,9 @@ const AVFilter ff_vf_selectivecolor = {
     .priv_size     = sizeof(SelectiveColorContext),
     .query_formats = query_formats,
     .inputs        = selectivecolor_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(selectivecolor_inputs),
     .outputs       = selectivecolor_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(selectivecolor_outputs),
     .priv_class    = &selectivecolor_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c
index c2c7352ad1..7b6e324f1f 100644
--- a/libavfilter/vf_separatefields.c
+++ b/libavfilter/vf_separatefields.c
@@ -161,7 +161,6 @@ static const AVFilterPad separatefields_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad separatefields_outputs[] = {
@@ -170,7 +169,6 @@ static const AVFilterPad separatefields_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_separatefields = {
@@ -180,5 +178,7 @@ const AVFilter ff_vf_separatefields = {
     .activate    = activate,
     .uninit      = uninit,
     .inputs      = separatefields_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(separatefields_inputs),
     .outputs     = separatefields_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(separatefields_outputs),
 };
diff --git a/libavfilter/vf_setparams.c b/libavfilter/vf_setparams.c
index 0cb3af33ed..e049c64126 100644
--- a/libavfilter/vf_setparams.c
+++ b/libavfilter/vf_setparams.c
@@ -151,7 +151,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -159,7 +158,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_setparams = {
@@ -168,7 +166,9 @@ const AVFilter ff_vf_setparams = {
     .priv_size   = sizeof(SetParamsContext),
     .priv_class  = &setparams_class,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
 };
 
 #if CONFIG_SETRANGE_FILTER
@@ -207,7 +207,9 @@ const AVFilter ff_vf_setrange = {
     .init        = init_setrange,
     .priv_class  = &setrange_class,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
 };
 #endif /* CONFIG_SETRANGE_FILTER */
 
@@ -241,6 +243,8 @@ const AVFilter ff_vf_setfield = {
     .init        = init_setfield,
     .priv_class  = &setfield_class,
     .inputs      = inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(inputs),
     .outputs     = outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(outputs),
 };
 #endif /* CONFIG_SETFIELD_FILTER */
diff --git a/libavfilter/vf_shear.c b/libavfilter/vf_shear.c
index 6b9db161d9..b09f2684ac 100644
--- a/libavfilter/vf_shear.c
+++ b/libavfilter/vf_shear.c
@@ -304,7 +304,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -313,7 +312,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_shear = {
@@ -323,7 +321,9 @@ const AVFilter ff_vf_shear = {
     .init            = init,
     .query_formats   = query_formats,
     .inputs          = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs         = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .priv_class      = &shear_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index dfb7f86359..f51e4c7ca6 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -661,7 +661,6 @@ static const AVFilterPad avfilter_vf_showinfo_inputs[] = {
         .filter_frame     = filter_frame,
         .config_props     = config_props_in,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_showinfo_outputs[] = {
@@ -670,14 +669,15 @@ static const AVFilterPad avfilter_vf_showinfo_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props_out,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_showinfo = {
     .name        = "showinfo",
     .description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."),
     .inputs      = avfilter_vf_showinfo_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_showinfo_inputs),
     .outputs     = avfilter_vf_showinfo_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_showinfo_outputs),
     .priv_size   = sizeof(ShowInfoContext),
     .priv_class  = &showinfo_class,
 };
diff --git a/libavfilter/vf_showpalette.c b/libavfilter/vf_showpalette.c
index 2455af687c..24de335929 100644
--- a/libavfilter/vf_showpalette.c
+++ b/libavfilter/vf_showpalette.c
@@ -100,7 +100,6 @@ static const AVFilterPad showpalette_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad showpalette_outputs[] = {
@@ -109,7 +108,6 @@ static const AVFilterPad showpalette_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_showpalette = {
@@ -118,6 +116,8 @@ const AVFilter ff_vf_showpalette = {
     .priv_size     = sizeof(ShowPaletteContext),
     .query_formats = query_formats,
     .inputs        = showpalette_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(showpalette_inputs),
     .outputs       = showpalette_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(showpalette_outputs),
     .priv_class    = &showpalette_class,
 };
diff --git a/libavfilter/vf_shuffleframes.c b/libavfilter/vf_shuffleframes.c
index cdc70f552e..4b935732a8 100644
--- a/libavfilter/vf_shuffleframes.c
+++ b/libavfilter/vf_shuffleframes.c
@@ -144,7 +144,6 @@ static const AVFilterPad shuffleframes_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL },
 };
 
 static const AVFilterPad shuffleframes_outputs[] = {
@@ -152,7 +151,6 @@ static const AVFilterPad shuffleframes_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL },
 };
 
 const AVFilter ff_vf_shuffleframes = {
@@ -163,6 +161,8 @@ const AVFilter ff_vf_shuffleframes = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = shuffleframes_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(shuffleframes_inputs),
     .outputs       = shuffleframes_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(shuffleframes_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_shufflepixels.c b/libavfilter/vf_shufflepixels.c
index b5e757c929..0776d308ae 100644
--- a/libavfilter/vf_shufflepixels.c
+++ b/libavfilter/vf_shufflepixels.c
@@ -436,7 +436,6 @@ static const AVFilterPad shufflepixels_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL },
 };
 
 static const AVFilterPad shufflepixels_outputs[] = {
@@ -445,7 +444,6 @@ static const AVFilterPad shufflepixels_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL },
 };
 
 const AVFilter ff_vf_shufflepixels = {
@@ -456,6 +454,8 @@ const AVFilter ff_vf_shufflepixels = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = shufflepixels_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(shufflepixels_inputs),
     .outputs       = shufflepixels_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(shufflepixels_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_shuffleplanes.c b/libavfilter/vf_shuffleplanes.c
index d1e1d11074..2f916c92cf 100644
--- a/libavfilter/vf_shuffleplanes.c
+++ b/libavfilter/vf_shuffleplanes.c
@@ -151,7 +151,6 @@ static const AVFilterPad shuffleplanes_inputs[] = {
         .config_props     = shuffleplanes_config_input,
         .filter_frame     = shuffleplanes_filter_frame,
     },
-    { NULL },
 };
 
 static const AVFilterPad shuffleplanes_outputs[] = {
@@ -159,7 +158,6 @@ static const AVFilterPad shuffleplanes_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL },
 };
 
 const AVFilter ff_vf_shuffleplanes = {
@@ -169,6 +167,8 @@ const AVFilter ff_vf_shuffleplanes = {
     .priv_class   = &shuffleplanes_class,
     .query_formats = query_formats,
     .inputs       = shuffleplanes_inputs,
+    .nb_inputs    = FF_ARRAY_ELEMS(shuffleplanes_inputs),
     .outputs      = shuffleplanes_outputs,
+    .nb_outputs   = FF_ARRAY_ELEMS(shuffleplanes_outputs),
     .flags        = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_signalstats.c b/libavfilter/vf_signalstats.c
index 6f0ff53029..5c0f2d667c 100644
--- a/libavfilter/vf_signalstats.c
+++ b/libavfilter/vf_signalstats.c
@@ -1000,7 +1000,6 @@ static const AVFilterPad signalstats_inputs[] = {
         .type           = AVMEDIA_TYPE_VIDEO,
         .filter_frame   = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad signalstats_outputs[] = {
@@ -1009,7 +1008,6 @@ static const AVFilterPad signalstats_outputs[] = {
         .config_props   = config_output,
         .type           = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_signalstats = {
@@ -1020,7 +1018,9 @@ const AVFilter ff_vf_signalstats = {
     .query_formats = query_formats,
     .priv_size     = sizeof(SignalstatsContext),
     .inputs        = signalstats_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(signalstats_inputs),
     .outputs       = signalstats_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(signalstats_outputs),
     .priv_class    = &signalstats_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_signature.c b/libavfilter/vf_signature.c
index a345ad6ebd..8adc69477a 100644
--- a/libavfilter/vf_signature.c
+++ b/libavfilter/vf_signature.c
@@ -755,7 +755,6 @@ static const AVFilterPad signature_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_signature = {
@@ -767,6 +766,7 @@ const AVFilter ff_vf_signature = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .outputs       = signature_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(signature_outputs),
     .inputs        = NULL,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
index 36ed72a12c..a346170635 100644
--- a/libavfilter/vf_smartblur.c
+++ b/libavfilter/vf_smartblur.c
@@ -280,7 +280,6 @@ static const AVFilterPad smartblur_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad smartblur_outputs[] = {
@@ -288,7 +287,6 @@ static const AVFilterPad smartblur_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_smartblur = {
@@ -299,7 +297,9 @@ const AVFilter ff_vf_smartblur = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = smartblur_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(smartblur_inputs),
     .outputs       = smartblur_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(smartblur_outputs),
     .priv_class    = &smartblur_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_spp.c b/libavfilter/vf_spp.c
index cfa1cb77c4..a4aa7ba65a 100644
--- a/libavfilter/vf_spp.c
+++ b/libavfilter/vf_spp.c
@@ -498,7 +498,6 @@ static const AVFilterPad spp_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad spp_outputs[] = {
@@ -506,7 +505,6 @@ static const AVFilterPad spp_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_spp = {
@@ -517,7 +515,9 @@ const AVFilter ff_vf_spp = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = spp_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(spp_inputs),
     .outputs         = spp_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(spp_outputs),
     .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 f930b38748..42785bcab1 100644
--- a/libavfilter/vf_sr.c
+++ b/libavfilter/vf_sr.c
@@ -181,7 +181,6 @@ static const AVFilterPad sr_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad sr_outputs[] = {
@@ -190,7 +189,6 @@ static const AVFilterPad sr_outputs[] = {
         .config_props = config_output,
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_sr = {
@@ -201,6 +199,8 @@ const AVFilter ff_vf_sr = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = sr_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(sr_inputs),
     .outputs       = sr_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(sr_outputs),
     .priv_class    = &sr_class,
 };
diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c
index c6e4fe286a..81b26a9848 100644
--- a/libavfilter/vf_ssim.c
+++ b/libavfilter/vf_ssim.c
@@ -581,7 +581,6 @@ static const AVFilterPad ssim_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad ssim_outputs[] = {
@@ -590,7 +589,6 @@ static const AVFilterPad ssim_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_ssim = {
@@ -604,6 +602,8 @@ const AVFilter ff_vf_ssim = {
     .priv_size     = sizeof(SSIMContext),
     .priv_class    = &ssim_class,
     .inputs        = ssim_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ssim_inputs),
     .outputs       = ssim_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(ssim_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
index 3368e25c9c..a99496ca52 100644
--- a/libavfilter/vf_stack.c
+++ b/libavfilter/vf_stack.c
@@ -401,7 +401,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #if CONFIG_HSTACK_FILTER
@@ -416,6 +415,7 @@ const AVFilter ff_vf_hstack = {
     .priv_class    = &hstack_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
@@ -436,6 +436,7 @@ const AVFilter ff_vf_vstack = {
     .priv_class    = &vstack_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
@@ -463,6 +464,7 @@ const AVFilter ff_vf_xstack = {
     .priv_class    = &xstack_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .init          = init,
     .uninit        = uninit,
     .activate      = activate,
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index ec7d410f76..b99a4e43a0 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -1100,7 +1100,6 @@ static const AVFilterPad stereo3d_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad stereo3d_outputs[] = {
@@ -1109,7 +1108,6 @@ static const AVFilterPad stereo3d_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_stereo3d = {
@@ -1119,7 +1117,9 @@ const AVFilter ff_vf_stereo3d = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = stereo3d_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(stereo3d_inputs),
     .outputs       = stereo3d_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(stereo3d_outputs),
     .priv_class    = &stereo3d_class,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index ab32e1b7f3..07fef01da3 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -202,7 +202,6 @@ static const AVFilterPad ass_inputs[] = {
         .config_props     = config_input,
         .needs_writable   = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad ass_outputs[] = {
@@ -210,7 +209,6 @@ static const AVFilterPad ass_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #if CONFIG_ASS_FILTER
@@ -255,7 +253,9 @@ const AVFilter ff_vf_ass = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = ass_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ass_inputs),
     .outputs       = ass_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(ass_outputs),
     .priv_class    = &ass_class,
 };
 #endif
@@ -489,7 +489,9 @@ const AVFilter ff_vf_subtitles = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = ass_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(ass_inputs),
     .outputs       = ass_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(ass_outputs),
     .priv_class    = &subtitles_class,
 };
 #endif
diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c
index 00e88eafe3..c24b5e02a1 100644
--- a/libavfilter/vf_super2xsai.c
+++ b/libavfilter/vf_super2xsai.c
@@ -347,7 +347,6 @@ static const AVFilterPad super2xsai_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad super2xsai_outputs[] = {
@@ -356,7 +355,6 @@ static const AVFilterPad super2xsai_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_super2xsai = {
@@ -365,6 +363,8 @@ const AVFilter ff_vf_super2xsai = {
     .priv_size     = sizeof(Super2xSaIContext),
     .query_formats = query_formats,
     .inputs        = super2xsai_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(super2xsai_inputs),
     .outputs       = super2xsai_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(super2xsai_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_swaprect.c b/libavfilter/vf_swaprect.c
index 3b96790798..a29849ff79 100644
--- a/libavfilter/vf_swaprect.c
+++ b/libavfilter/vf_swaprect.c
@@ -232,7 +232,6 @@ static const AVFilterPad inputs[] = {
         .config_props   = config_input,
         .needs_writable = 1,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -240,7 +239,6 @@ static const AVFilterPad outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_swaprect = {
@@ -251,7 +249,9 @@ const AVFilter ff_vf_swaprect = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 34868eb0c9..b00e7ec790 100644
--- a/libavfilter/vf_swapuv.c
+++ b/libavfilter/vf_swapuv.c
@@ -100,7 +100,6 @@ static const AVFilterPad swapuv_inputs[] = {
         .get_video_buffer = get_video_buffer,
         .filter_frame     = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad swapuv_outputs[] = {
@@ -108,7 +107,6 @@ static const AVFilterPad swapuv_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_swapuv = {
@@ -118,6 +116,8 @@ const AVFilter ff_vf_swapuv = {
     .priv_size     = sizeof(SwapUVContext),
     .priv_class    = &swapuv_class,
     .inputs        = swapuv_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(swapuv_inputs),
     .outputs       = swapuv_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(swapuv_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c
index 52a3f2f353..3aee0fcd9f 100644
--- a/libavfilter/vf_telecine.c
+++ b/libavfilter/vf_telecine.c
@@ -275,7 +275,6 @@ static const AVFilterPad telecine_inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad telecine_outputs[] = {
@@ -284,7 +283,6 @@ static const AVFilterPad telecine_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_telecine = {
@@ -296,5 +294,7 @@ const AVFilter ff_vf_telecine = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = telecine_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(telecine_inputs),
     .outputs       = telecine_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(telecine_outputs),
 };
diff --git a/libavfilter/vf_threshold.c b/libavfilter/vf_threshold.c
index 0c8787e331..d5d43e38d5 100644
--- a/libavfilter/vf_threshold.c
+++ b/libavfilter/vf_threshold.c
@@ -342,7 +342,6 @@ static const AVFilterPad inputs[] = {
         .name         = "max",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -351,7 +350,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_threshold = {
@@ -363,7 +361,9 @@ const AVFilter ff_vf_threshold = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(outputs),
     .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 825e536e67..c22f697183 100644
--- a/libavfilter/vf_thumbnail.c
+++ b/libavfilter/vf_thumbnail.c
@@ -275,7 +275,6 @@ static const AVFilterPad thumbnail_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad thumbnail_outputs[] = {
@@ -284,7 +283,6 @@ static const AVFilterPad thumbnail_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_thumbnail = {
@@ -295,7 +293,9 @@ const AVFilter ff_vf_thumbnail = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = thumbnail_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(thumbnail_inputs),
     .outputs       = thumbnail_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(thumbnail_outputs),
     .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 ceac10f72f..09ef551d03 100644
--- a/libavfilter/vf_thumbnail_cuda.c
+++ b/libavfilter/vf_thumbnail_cuda.c
@@ -431,7 +431,6 @@ static const AVFilterPad thumbnail_cuda_inputs[] = {
         .config_props = config_props,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad thumbnail_cuda_outputs[] = {
@@ -440,7 +439,6 @@ static const AVFilterPad thumbnail_cuda_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_thumbnail_cuda = {
@@ -451,7 +449,9 @@ const AVFilter ff_vf_thumbnail_cuda = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = thumbnail_cuda_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(thumbnail_cuda_inputs),
     .outputs       = thumbnail_cuda_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(thumbnail_cuda_outputs),
     .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 11392169e4..ff500aa11b 100644
--- a/libavfilter/vf_tile.c
+++ b/libavfilter/vf_tile.c
@@ -272,7 +272,6 @@ static const AVFilterPad tile_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad tile_outputs[] = {
@@ -282,7 +281,6 @@ static const AVFilterPad tile_outputs[] = {
         .config_props  = config_props,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tile = {
@@ -293,6 +291,8 @@ const AVFilter ff_vf_tile = {
     .query_formats = query_formats,
     .priv_size     = sizeof(TileContext),
     .inputs        = tile_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(tile_inputs),
     .outputs       = tile_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(tile_outputs),
     .priv_class    = &tile_class,
 };
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 40d8879871..9311590af8 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -543,7 +543,6 @@ static const AVFilterPad tinterlace_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad tinterlace_outputs[] = {
@@ -552,7 +551,6 @@ static const AVFilterPad tinterlace_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_out_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tinterlace = {
@@ -562,7 +560,9 @@ const AVFilter ff_vf_tinterlace = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = tinterlace_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(tinterlace_inputs),
     .outputs       = tinterlace_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(tinterlace_outputs),
     .priv_class    = &tinterlace_class,
 };
 
@@ -575,6 +575,8 @@ const AVFilter ff_vf_interlace = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = tinterlace_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(tinterlace_inputs),
     .outputs       = tinterlace_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(tinterlace_outputs),
     .priv_class    = &interlace_class,
 };
diff --git a/libavfilter/vf_tmidequalizer.c b/libavfilter/vf_tmidequalizer.c
index 24e1d557e2..680776192f 100644
--- a/libavfilter/vf_tmidequalizer.c
+++ b/libavfilter/vf_tmidequalizer.c
@@ -415,7 +415,6 @@ static const AVFilterPad tmidequalizer_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad tmidequalizer_outputs[] = {
@@ -424,7 +423,6 @@ static const AVFilterPad tmidequalizer_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tmidequalizer = {
@@ -434,7 +432,9 @@ const AVFilter ff_vf_tmidequalizer = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = tmidequalizer_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(tmidequalizer_inputs),
     .outputs       = tmidequalizer_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(tmidequalizer_outputs),
     .priv_class    = &tmidequalizer_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_tonemap.c b/libavfilter/vf_tonemap.c
index 4d04118eac..fe4da6e438 100644
--- a/libavfilter/vf_tonemap.c
+++ b/libavfilter/vf_tonemap.c
@@ -323,7 +323,6 @@ static const AVFilterPad tonemap_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad tonemap_outputs[] = {
@@ -331,7 +330,6 @@ static const AVFilterPad tonemap_outputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tonemap = {
@@ -342,6 +340,8 @@ const AVFilter ff_vf_tonemap = {
     .priv_size       = sizeof(TonemapContext),
     .priv_class      = &tonemap_class,
     .inputs          = tonemap_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(tonemap_inputs),
     .outputs         = tonemap_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(tonemap_outputs),
     .flags           = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_tonemap_opencl.c b/libavfilter/vf_tonemap_opencl.c
index 8cf7c099ee..5533a5bf8a 100644
--- a/libavfilter/vf_tonemap_opencl.c
+++ b/libavfilter/vf_tonemap_opencl.c
@@ -527,7 +527,6 @@ static const AVFilterPad tonemap_opencl_inputs[] = {
         .filter_frame = &tonemap_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad tonemap_opencl_outputs[] = {
@@ -536,7 +535,6 @@ static const AVFilterPad tonemap_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &tonemap_opencl_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tonemap_opencl = {
@@ -548,6 +546,8 @@ const AVFilter ff_vf_tonemap_opencl = {
     .uninit         = &tonemap_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = tonemap_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(tonemap_opencl_inputs),
     .outputs        = tonemap_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(tonemap_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_tonemap_vaapi.c b/libavfilter/vf_tonemap_vaapi.c
index d33c4f8f6d..401b541cef 100644
--- a/libavfilter/vf_tonemap_vaapi.c
+++ b/libavfilter/vf_tonemap_vaapi.c
@@ -391,7 +391,6 @@ static const AVFilterPad tonemap_vaapi_inputs[] = {
         .filter_frame = &tonemap_vaapi_filter_frame,
         .config_props = &ff_vaapi_vpp_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad tonemap_vaapi_outputs[] = {
@@ -400,7 +399,6 @@ static const AVFilterPad tonemap_vaapi_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_vaapi_vpp_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tonemap_vaapi = {
@@ -411,7 +409,9 @@ const AVFilter ff_vf_tonemap_vaapi = {
     .uninit         = &ff_vaapi_vpp_ctx_uninit,
     .query_formats  = &ff_vaapi_vpp_query_formats,
     .inputs         = tonemap_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(tonemap_vaapi_inputs),
     .outputs        = tonemap_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(tonemap_vaapi_outputs),
     .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 d23869f3e2..c88da1cd40 100644
--- a/libavfilter/vf_tpad.c
+++ b/libavfilter/vf_tpad.c
@@ -193,7 +193,6 @@ static const AVFilterPad tpad_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad tpad_outputs[] = {
@@ -201,7 +200,6 @@ static const AVFilterPad tpad_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_tpad = {
@@ -213,5 +211,7 @@ const AVFilter ff_vf_tpad = {
     .activate      = activate,
     .uninit        = uninit,
     .inputs        = tpad_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(tpad_inputs),
     .outputs       = tpad_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(tpad_outputs),
 };
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 6affbed0a6..e8a976dbaf 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -385,7 +385,6 @@ static const AVFilterPad avfilter_vf_transpose_inputs[] = {
         .get_video_buffer = get_video_buffer,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_transpose_outputs[] = {
@@ -394,7 +393,6 @@ static const AVFilterPad avfilter_vf_transpose_outputs[] = {
         .config_props = config_props_output,
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_transpose = {
@@ -404,6 +402,8 @@ const AVFilter ff_vf_transpose = {
     .priv_class    = &transpose_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_transpose_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_transpose_inputs),
     .outputs       = avfilter_vf_transpose_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_transpose_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_transpose_npp.c b/libavfilter/vf_transpose_npp.c
index 2a68a832ff..bddca86fb4 100644
--- a/libavfilter/vf_transpose_npp.c
+++ b/libavfilter/vf_transpose_npp.c
@@ -461,7 +461,6 @@ static const AVFilterPad npptranspose_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = npptranspose_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad npptranspose_outputs[] = {
@@ -470,7 +469,6 @@ static const AVFilterPad npptranspose_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = npptranspose_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_transpose_npp = {
@@ -482,6 +480,8 @@ const AVFilter ff_vf_transpose_npp = {
     .priv_size      = sizeof(NPPTransposeContext),
     .priv_class     = &npptranspose_class,
     .inputs         = npptranspose_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(npptranspose_inputs),
     .outputs        = npptranspose_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(npptranspose_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_transpose_opencl.c b/libavfilter/vf_transpose_opencl.c
index 2877d3c826..5203c09b5c 100644
--- a/libavfilter/vf_transpose_opencl.c
+++ b/libavfilter/vf_transpose_opencl.c
@@ -260,7 +260,6 @@ static const AVFilterPad transpose_opencl_inputs[] = {
         .filter_frame = &transpose_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad transpose_opencl_outputs[] = {
@@ -269,7 +268,6 @@ static const AVFilterPad transpose_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &transpose_opencl_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_transpose_opencl = {
@@ -281,6 +279,8 @@ const AVFilter ff_vf_transpose_opencl = {
     .uninit         = &transpose_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = transpose_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(transpose_opencl_inputs),
     .outputs        = transpose_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(transpose_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_transpose_vaapi.c b/libavfilter/vf_transpose_vaapi.c
index 79413e0eeb..b95db576d6 100644
--- a/libavfilter/vf_transpose_vaapi.c
+++ b/libavfilter/vf_transpose_vaapi.c
@@ -260,7 +260,6 @@ static const AVFilterPad transpose_vaapi_inputs[] = {
         .get_video_buffer = get_video_buffer,
         .config_props = &ff_vaapi_vpp_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad transpose_vaapi_outputs[] = {
@@ -269,7 +268,6 @@ static const AVFilterPad transpose_vaapi_outputs[] = {
         .type = AVMEDIA_TYPE_VIDEO,
         .config_props = &transpose_vaapi_vpp_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_transpose_vaapi = {
@@ -280,7 +278,9 @@ const AVFilter ff_vf_transpose_vaapi = {
     .uninit         = &ff_vaapi_vpp_ctx_uninit,
     .query_formats  = &ff_vaapi_vpp_query_formats,
     .inputs         = transpose_vaapi_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(transpose_vaapi_inputs),
     .outputs        = transpose_vaapi_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(transpose_vaapi_outputs),
     .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 0bf72169a9..7143068991 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -345,7 +345,6 @@ static const AVFilterPad avfilter_vf_unsharp_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_unsharp_outputs[] = {
@@ -353,7 +352,6 @@ static const AVFilterPad avfilter_vf_unsharp_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_unsharp = {
@@ -365,6 +363,8 @@ const AVFilter ff_vf_unsharp = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_unsharp_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_unsharp_inputs),
     .outputs       = avfilter_vf_unsharp_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_unsharp_outputs),
     .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 200350de9f..a580487412 100644
--- a/libavfilter/vf_unsharp_opencl.c
+++ b/libavfilter/vf_unsharp_opencl.c
@@ -386,7 +386,6 @@ static const AVFilterPad unsharp_opencl_inputs[] = {
         .filter_frame = &unsharp_opencl_filter_frame,
         .config_props = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad unsharp_opencl_outputs[] = {
@@ -395,7 +394,6 @@ static const AVFilterPad unsharp_opencl_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = &ff_opencl_filter_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_unsharp_opencl = {
@@ -407,6 +405,8 @@ const AVFilter ff_vf_unsharp_opencl = {
     .uninit         = &unsharp_opencl_uninit,
     .query_formats  = &ff_opencl_filter_query_formats,
     .inputs         = unsharp_opencl_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(unsharp_opencl_inputs),
     .outputs        = unsharp_opencl_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(unsharp_opencl_outputs),
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_untile.c b/libavfilter/vf_untile.c
index 9035e819d4..9e872bffa7 100644
--- a/libavfilter/vf_untile.c
+++ b/libavfilter/vf_untile.c
@@ -172,7 +172,6 @@ static const AVFilterPad untile_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad untile_outputs[] = {
@@ -181,7 +180,6 @@ static const AVFilterPad untile_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_untile = {
@@ -193,6 +191,8 @@ const AVFilter ff_vf_untile = {
     .activate      = activate,
     .priv_size     = sizeof(UntileContext),
     .inputs        = untile_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(untile_inputs),
     .outputs       = untile_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(untile_outputs),
     .priv_class    = &untile_class,
 };
diff --git a/libavfilter/vf_uspp.c b/libavfilter/vf_uspp.c
index 7029963e29..fe0fb43dc6 100644
--- a/libavfilter/vf_uspp.c
+++ b/libavfilter/vf_uspp.c
@@ -483,7 +483,6 @@ static const AVFilterPad uspp_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad uspp_outputs[] = {
@@ -491,7 +490,6 @@ static const AVFilterPad uspp_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_uspp = {
@@ -501,7 +499,9 @@ const AVFilter ff_vf_uspp = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = uspp_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(uspp_inputs),
     .outputs         = uspp_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(uspp_outputs),
     .priv_class      = &uspp_class,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c
index 692fa43c4d..b79773ac0e 100644
--- a/libavfilter/vf_v360.c
+++ b/libavfilter/vf_v360.c
@@ -4969,7 +4969,6 @@ static const AVFilterPad inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -4978,7 +4977,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_v360 = {
@@ -4989,7 +4987,9 @@ const AVFilter ff_vf_v360 = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .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 481fc774e5..69daee0d7b 100644
--- a/libavfilter/vf_vaguedenoiser.c
+++ b/libavfilter/vf_vaguedenoiser.c
@@ -598,7 +598,6 @@ static const AVFilterPad vaguedenoiser_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 
@@ -607,7 +606,6 @@ static const AVFilterPad vaguedenoiser_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vaguedenoiser = {
@@ -619,6 +617,8 @@ const AVFilter ff_vf_vaguedenoiser = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = vaguedenoiser_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(vaguedenoiser_inputs),
     .outputs       = vaguedenoiser_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(vaguedenoiser_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_vectorscope.c b/libavfilter/vf_vectorscope.c
index 0669230890..75eeb91e9d 100644
--- a/libavfilter/vf_vectorscope.c
+++ b/libavfilter/vf_vectorscope.c
@@ -1575,7 +1575,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -1584,7 +1583,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vectorscope = {
@@ -1595,5 +1593,7 @@ const AVFilter ff_vf_vectorscope = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index 95a693a7e1..53fc3e1df2 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -133,7 +133,6 @@ static const AVFilterPad avfilter_vf_vflip_inputs[] = {
         .filter_frame     = filter_frame,
         .config_props     = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_vflip_outputs[] = {
@@ -141,7 +140,6 @@ static const AVFilterPad avfilter_vf_vflip_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vflip = {
@@ -150,6 +148,8 @@ const AVFilter ff_vf_vflip = {
     .priv_size   = sizeof(FlipContext),
     .priv_class  = &vflip_class,
     .inputs      = avfilter_vf_vflip_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vf_vflip_inputs),
     .outputs     = avfilter_vf_vflip_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(avfilter_vf_vflip_outputs),
     .flags       = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_vfrdet.c b/libavfilter/vf_vfrdet.c
index 7e37036aef..7f551cb687 100644
--- a/libavfilter/vf_vfrdet.c
+++ b/libavfilter/vf_vfrdet.c
@@ -93,7 +93,6 @@ static const AVFilterPad vfrdet_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad vfrdet_outputs[] = {
@@ -101,7 +100,6 @@ static const AVFilterPad vfrdet_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vfrdet = {
@@ -111,5 +109,7 @@ const AVFilter ff_vf_vfrdet = {
     .init        = init,
     .uninit      = uninit,
     .inputs      = vfrdet_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(vfrdet_inputs),
     .outputs     = vfrdet_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(vfrdet_outputs),
 };
diff --git a/libavfilter/vf_vibrance.c b/libavfilter/vf_vibrance.c
index cca677ee78..1340069100 100644
--- a/libavfilter/vf_vibrance.c
+++ b/libavfilter/vf_vibrance.c
@@ -350,7 +350,6 @@ static const AVFilterPad vibrance_inputs[] = {
         .filter_frame   = filter_frame,
         .config_props   = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad vibrance_outputs[] = {
@@ -358,7 +357,6 @@ static const AVFilterPad vibrance_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(VibranceContext, x)
@@ -385,7 +383,9 @@ const AVFilter ff_vf_vibrance = {
     .priv_class    = &vibrance_class,
     .query_formats = query_formats,
     .inputs        = vibrance_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(vibrance_inputs),
     .outputs       = vibrance_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(vibrance_outputs),
     .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 475d0381bc..2dbd009a5e 100644
--- a/libavfilter/vf_vidstabdetect.c
+++ b/libavfilter/vf_vidstabdetect.c
@@ -196,7 +196,6 @@ static const AVFilterPad avfilter_vf_vidstabdetect_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_vidstabdetect_outputs[] = {
@@ -204,7 +203,6 @@ static const AVFilterPad avfilter_vf_vidstabdetect_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vidstabdetect = {
@@ -217,6 +215,8 @@ const AVFilter ff_vf_vidstabdetect = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_vidstabdetect_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_vidstabdetect_inputs),
     .outputs       = avfilter_vf_vidstabdetect_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_vidstabdetect_outputs),
     .priv_class    = &vidstabdetect_class,
 };
diff --git a/libavfilter/vf_vidstabtransform.c b/libavfilter/vf_vidstabtransform.c
index 79e62c1f58..02c2a64cca 100644
--- a/libavfilter/vf_vidstabtransform.c
+++ b/libavfilter/vf_vidstabtransform.c
@@ -297,7 +297,6 @@ static const AVFilterPad avfilter_vf_vidstabtransform_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_vidstabtransform_outputs[] = {
@@ -305,7 +304,6 @@ static const AVFilterPad avfilter_vf_vidstabtransform_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vidstabtransform = {
@@ -318,6 +316,8 @@ const AVFilter ff_vf_vidstabtransform = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_vidstabtransform_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_vidstabtransform_inputs),
     .outputs       = avfilter_vf_vidstabtransform_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_vidstabtransform_outputs),
     .priv_class    = &vidstabtransform_class,
 };
diff --git a/libavfilter/vf_vif.c b/libavfilter/vf_vif.c
index c21bd40f44..471a054156 100644
--- a/libavfilter/vf_vif.c
+++ b/libavfilter/vf_vif.c
@@ -630,7 +630,6 @@ static const AVFilterPad vif_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad vif_outputs[] = {
@@ -639,7 +638,6 @@ static const AVFilterPad vif_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vif = {
@@ -651,6 +649,8 @@ const AVFilter ff_vf_vif = {
     .priv_class    = &vif_class,
     .activate      = activate,
     .inputs        = vif_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(vif_inputs),
     .outputs       = vif_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(vif_outputs),
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_vignette.c b/libavfilter/vf_vignette.c
index 91754306ae..efb657f818 100644
--- a/libavfilter/vf_vignette.c
+++ b/libavfilter/vf_vignette.c
@@ -330,7 +330,6 @@ static const AVFilterPad vignette_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 static const AVFilterPad vignette_outputs[] = {
@@ -338,7 +337,6 @@ static const AVFilterPad vignette_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vignette = {
@@ -349,7 +347,9 @@ const AVFilter ff_vf_vignette = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = vignette_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(vignette_inputs),
     .outputs       = vignette_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(vignette_outputs),
     .priv_class    = &vignette_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 };
diff --git a/libavfilter/vf_vmafmotion.c b/libavfilter/vf_vmafmotion.c
index 454ebb8afa..feb063ef21 100644
--- a/libavfilter/vf_vmafmotion.c
+++ b/libavfilter/vf_vmafmotion.c
@@ -347,7 +347,6 @@ static const AVFilterPad vmafmotion_inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input_ref,
     },
-    { NULL }
 };
 
 static const AVFilterPad vmafmotion_outputs[] = {
@@ -355,7 +354,6 @@ static const AVFilterPad vmafmotion_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vmafmotion = {
@@ -367,5 +365,7 @@ const AVFilter ff_vf_vmafmotion = {
     .priv_size     = sizeof(VMAFMotionContext),
     .priv_class    = &vmafmotion_class,
     .inputs        = vmafmotion_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(vmafmotion_inputs),
     .outputs       = vmafmotion_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(vmafmotion_outputs),
 };
diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index ee9317a49e..8ebefcaef0 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -600,7 +600,6 @@ static const AVFilterPad vpp_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad vpp_outputs[] = {
@@ -609,7 +608,6 @@ static const AVFilterPad vpp_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_vpp_qsv = {
@@ -620,7 +618,9 @@ const AVFilter ff_vf_vpp_qsv = {
     .init          = vpp_init,
     .uninit        = vpp_uninit,
     .inputs        = vpp_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(vpp_inputs),
     .outputs       = vpp_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(vpp_outputs),
     .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 5edb826f0a..f0fe0985ed 100644
--- a/libavfilter/vf_w3fdif.c
+++ b/libavfilter/vf_w3fdif.c
@@ -600,7 +600,6 @@ static const AVFilterPad w3fdif_inputs[] = {
         .filter_frame  = filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad w3fdif_outputs[] = {
@@ -610,7 +609,6 @@ static const AVFilterPad w3fdif_outputs[] = {
         .config_props  = config_output,
         .request_frame = request_frame,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_w3fdif = {
@@ -621,7 +619,9 @@ const AVFilter ff_vf_w3fdif = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = w3fdif_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(w3fdif_inputs),
     .outputs       = w3fdif_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(w3fdif_outputs),
     .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 977ebad9ce..7bf997f2f2 100644
--- a/libavfilter/vf_waveform.c
+++ b/libavfilter/vf_waveform.c
@@ -3477,7 +3477,6 @@ static const AVFilterPad inputs[] = {
         .filter_frame = filter_frame,
         .config_props = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -3486,7 +3485,6 @@ static const AVFilterPad outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_waveform = {
@@ -3497,6 +3495,8 @@ const AVFilter ff_vf_waveform = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c
index 98b8d0bd06..54b19b1e86 100644
--- a/libavfilter/vf_weave.c
+++ b/libavfilter/vf_weave.c
@@ -178,7 +178,6 @@ static const AVFilterPad weave_inputs[] = {
         .type             = AVMEDIA_TYPE_VIDEO,
         .filter_frame     = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad weave_outputs[] = {
@@ -187,7 +186,6 @@ static const AVFilterPad weave_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_weave = {
@@ -198,7 +196,9 @@ const AVFilter ff_vf_weave = {
     .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = weave_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(weave_inputs),
     .outputs       = weave_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(weave_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
 
@@ -224,6 +224,8 @@ const AVFilter ff_vf_doubleweave = {
     .init          = init,
     .uninit        = uninit,
     .inputs        = weave_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(weave_inputs),
     .outputs       = weave_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(weave_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_xbr.c b/libavfilter/vf_xbr.c
index 1300693bac..36288b970f 100644
--- a/libavfilter/vf_xbr.c
+++ b/libavfilter/vf_xbr.c
@@ -412,7 +412,6 @@ static const AVFilterPad xbr_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad xbr_outputs[] = {
@@ -421,14 +420,15 @@ static const AVFilterPad xbr_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_xbr = {
     .name          = "xbr",
     .description   = NULL_IF_CONFIG_SMALL("Scale the input using xBR algorithm."),
     .inputs        = xbr_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(xbr_inputs),
     .outputs       = xbr_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(xbr_outputs),
     .query_formats = query_formats,
     .priv_size     = sizeof(XBRContext),
     .priv_class    = &xbr_class,
diff --git a/libavfilter/vf_xfade.c b/libavfilter/vf_xfade.c
index 2e075cfb9a..1564db4530 100644
--- a/libavfilter/vf_xfade.c
+++ b/libavfilter/vf_xfade.c
@@ -1944,7 +1944,6 @@ static const AVFilterPad xfade_inputs[] = {
         .name          = "xfade",
         .type          = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad xfade_outputs[] = {
@@ -1953,7 +1952,6 @@ static const AVFilterPad xfade_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_xfade = {
@@ -1965,6 +1963,8 @@ const AVFilter ff_vf_xfade = {
     .activate      = xfade_activate,
     .uninit        = uninit,
     .inputs        = xfade_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(xfade_inputs),
     .outputs       = xfade_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(xfade_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_xfade_opencl.c b/libavfilter/vf_xfade_opencl.c
index 5b64ea2f08..e00c1ed40e 100644
--- a/libavfilter/vf_xfade_opencl.c
+++ b/libavfilter/vf_xfade_opencl.c
@@ -411,7 +411,6 @@ static const AVFilterPad xfade_opencl_inputs[] = {
         .get_video_buffer = get_video_buffer,
         .config_props     = &ff_opencl_filter_config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad xfade_opencl_outputs[] = {
@@ -420,7 +419,6 @@ static const AVFilterPad xfade_opencl_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = &xfade_opencl_config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_xfade_opencl = {
@@ -433,6 +431,8 @@ const AVFilter ff_vf_xfade_opencl = {
     .query_formats   = &ff_opencl_filter_query_formats,
     .activate        = &xfade_opencl_activate,
     .inputs          = xfade_opencl_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(xfade_opencl_inputs),
     .outputs         = xfade_opencl_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(xfade_opencl_outputs),
     .flags_internal  = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
diff --git a/libavfilter/vf_xmedian.c b/libavfilter/vf_xmedian.c
index 168a5944db..ed83b37f39 100644
--- a/libavfilter/vf_xmedian.c
+++ b/libavfilter/vf_xmedian.c
@@ -385,7 +385,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 #if CONFIG_XMEDIAN_FILTER
@@ -398,6 +397,7 @@ const AVFilter ff_vf_xmedian = {
     .priv_class    = &xmedian_class,
     .query_formats = query_formats,
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
     .preinit       = xmedian_framesync_preinit,
     .init          = init,
     .uninit        = uninit,
@@ -461,7 +461,6 @@ static const AVFilterPad tmedian_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = tmedian_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad tmedian_outputs[] = {
@@ -470,7 +469,6 @@ static const AVFilterPad tmedian_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(tmedian);
@@ -482,7 +480,9 @@ const AVFilter ff_vf_tmedian = {
     .priv_class    = &tmedian_class,
     .query_formats = query_formats,
     .inputs        = tmedian_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(tmedian_inputs),
     .outputs       = tmedian_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(tmedian_outputs),
     .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 17269d6b96..3800179b43 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -339,7 +339,6 @@ static const AVFilterPad avfilter_vf_yadif_inputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .filter_frame  = ff_yadif_filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_yadif_outputs[] = {
@@ -349,7 +348,6 @@ static const AVFilterPad avfilter_vf_yadif_outputs[] = {
         .request_frame = ff_yadif_request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_yadif = {
@@ -360,6 +358,8 @@ const AVFilter ff_vf_yadif = {
     .uninit        = uninit,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_yadif_inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(avfilter_vf_yadif_inputs),
     .outputs       = avfilter_vf_yadif_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vf_yadif_outputs),
     .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 95267d6a1c..fd29defa20 100644
--- a/libavfilter/vf_yadif_cuda.c
+++ b/libavfilter/vf_yadif_cuda.c
@@ -363,7 +363,6 @@ static const AVFilterPad deint_cuda_inputs[] = {
         .filter_frame  = ff_yadif_filter_frame,
         .config_props  = config_input,
     },
-    { NULL }
 };
 
 static const AVFilterPad deint_cuda_outputs[] = {
@@ -373,7 +372,6 @@ static const AVFilterPad deint_cuda_outputs[] = {
         .request_frame = ff_yadif_request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_yadif_cuda = {
@@ -384,7 +382,9 @@ const AVFilter ff_vf_yadif_cuda = {
     .uninit         = deint_cuda_uninit,
     .query_formats  = deint_cuda_query_formats,
     .inputs         = deint_cuda_inputs,
+    .nb_inputs      = FF_ARRAY_ELEMS(deint_cuda_inputs),
     .outputs        = deint_cuda_outputs,
+    .nb_outputs     = FF_ARRAY_ELEMS(deint_cuda_outputs),
     .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 3380f7112a..5ae43fc36f 100644
--- a/libavfilter/vf_yaepblur.c
+++ b/libavfilter/vf_yaepblur.c
@@ -309,7 +309,6 @@ static const AVFilterPad yaep_inputs[] = {
         .config_props = config_input,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad yaep_outputs[] = {
@@ -317,7 +316,6 @@ static const AVFilterPad yaep_outputs[] = {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 #define OFFSET(x) offsetof(YAEPContext, x)
@@ -343,7 +341,9 @@ const AVFilter ff_vf_yaepblur = {
     .uninit          = uninit,
     .query_formats   = query_formats,
     .inputs          = yaep_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(yaep_inputs),
     .outputs         = yaep_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(yaep_outputs),
     .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 9115c23dc4..8bc56ced91 100644
--- a/libavfilter/vf_zoompan.c
+++ b/libavfilter/vf_zoompan.c
@@ -364,7 +364,6 @@ static const AVFilterPad inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
     },
-    { NULL }
 };
 
 static const AVFilterPad outputs[] = {
@@ -373,7 +372,6 @@ static const AVFilterPad outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_zoompan = {
@@ -386,5 +384,7 @@ const AVFilter ff_vf_zoompan = {
     .query_formats = query_formats,
     .activate      = activate,
     .inputs        = inputs,
+    .nb_inputs     = FF_ARRAY_ELEMS(inputs),
     .outputs       = outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(outputs),
 };
diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c
index d21de8d9db..a8469ddc15 100644
--- a/libavfilter/vf_zscale.c
+++ b/libavfilter/vf_zscale.c
@@ -914,7 +914,6 @@ static const AVFilterPad avfilter_vf_zscale_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL }
 };
 
 static const AVFilterPad avfilter_vf_zscale_outputs[] = {
@@ -923,7 +922,6 @@ static const AVFilterPad avfilter_vf_zscale_outputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vf_zscale = {
@@ -935,6 +933,8 @@ const AVFilter ff_vf_zscale = {
     .priv_class      = &zscale_class,
     .uninit          = uninit,
     .inputs          = avfilter_vf_zscale_inputs,
+    .nb_inputs       = FF_ARRAY_ELEMS(avfilter_vf_zscale_inputs),
     .outputs         = avfilter_vf_zscale_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(avfilter_vf_zscale_outputs),
     .process_command = process_command,
 };
diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c
index 1c796b7cb8..db30834af0 100644
--- a/libavfilter/vsink_nullsink.c
+++ b/libavfilter/vsink_nullsink.c
@@ -32,7 +32,6 @@ static const AVFilterPad avfilter_vsink_nullsink_inputs[] = {
         .type        = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
     },
-    { NULL },
 };
 
 const AVFilter ff_vsink_nullsink = {
@@ -40,5 +39,6 @@ const AVFilter ff_vsink_nullsink = {
     .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input video."),
     .priv_size   = 0,
     .inputs      = avfilter_vsink_nullsink_inputs,
+    .nb_inputs   = FF_ARRAY_ELEMS(avfilter_vsink_nullsink_inputs),
     .outputs     = NULL,
 };
diff --git a/libavfilter/vsrc_cellauto.c b/libavfilter/vsrc_cellauto.c
index 250c88c8da..e9dfa7aff5 100644
--- a/libavfilter/vsrc_cellauto.c
+++ b/libavfilter/vsrc_cellauto.c
@@ -324,7 +324,6 @@ static const AVFilterPad cellauto_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_cellauto = {
@@ -337,4 +336,5 @@ const AVFilter ff_vsrc_cellauto = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = cellauto_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(cellauto_outputs),
 };
diff --git a/libavfilter/vsrc_gradients.c b/libavfilter/vsrc_gradients.c
index 904baf1360..c378283a74 100644
--- a/libavfilter/vsrc_gradients.c
+++ b/libavfilter/vsrc_gradients.c
@@ -295,7 +295,6 @@ static const AVFilterPad gradients_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_gradients = {
@@ -306,6 +305,7 @@ const AVFilter ff_vsrc_gradients = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = gradients_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(gradients_outputs),
     .activate      = activate,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vsrc_life.c b/libavfilter/vsrc_life.c
index ca12f294b8..ea5f63fdb8 100644
--- a/libavfilter/vsrc_life.c
+++ b/libavfilter/vsrc_life.c
@@ -438,7 +438,6 @@ static const AVFilterPad life_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL}
 };
 
 const AVFilter ff_vsrc_life = {
@@ -451,4 +450,5 @@ const AVFilter ff_vsrc_life = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = life_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(life_outputs),
 };
diff --git a/libavfilter/vsrc_mandelbrot.c b/libavfilter/vsrc_mandelbrot.c
index 88c14f0d48..ee96cea82e 100644
--- a/libavfilter/vsrc_mandelbrot.c
+++ b/libavfilter/vsrc_mandelbrot.c
@@ -416,7 +416,6 @@ static const AVFilterPad mandelbrot_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_mandelbrot = {
@@ -429,4 +428,5 @@ const AVFilter ff_vsrc_mandelbrot = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = mandelbrot_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(mandelbrot_outputs),
 };
diff --git a/libavfilter/vsrc_mptestsrc.c b/libavfilter/vsrc_mptestsrc.c
index 8aa75a24ac..ae2f11fac1 100644
--- a/libavfilter/vsrc_mptestsrc.c
+++ b/libavfilter/vsrc_mptestsrc.c
@@ -354,7 +354,6 @@ static const AVFilterPad mptestsrc_outputs[] = {
         .request_frame = request_frame,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_mptestsrc = {
@@ -366,4 +365,5 @@ const AVFilter ff_vsrc_mptestsrc = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = mptestsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(mptestsrc_outputs),
 };
diff --git a/libavfilter/vsrc_sierpinski.c b/libavfilter/vsrc_sierpinski.c
index 7db4852892..a3cd4f05c9 100644
--- a/libavfilter/vsrc_sierpinski.c
+++ b/libavfilter/vsrc_sierpinski.c
@@ -220,7 +220,6 @@ static const AVFilterPad sierpinski_outputs[] = {
         .request_frame = sierpinski_request_frame,
         .config_props  = config_output,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_sierpinski = {
@@ -231,5 +230,6 @@ const AVFilter ff_vsrc_sierpinski = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = sierpinski_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(sierpinski_outputs),
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 08686938db..82b01640ce 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -263,7 +263,6 @@ static const AVFilterPad color_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = color_config_props,
     },
-    {  NULL }
 };
 
 const AVFilter ff_vsrc_color = {
@@ -277,6 +276,7 @@ const AVFilter ff_vsrc_color = {
     .query_formats   = color_query_formats,
     .inputs          = NULL,
     .outputs         = color_outputs,
+    .nb_outputs      = FF_ARRAY_ELEMS(color_outputs),
     .process_command = color_process_command,
 };
 
@@ -397,7 +397,6 @@ static const AVFilterPad haldclutsrc_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = haldclutsrc_config_props,
     },
-    {  NULL }
 };
 
 const AVFilter ff_vsrc_haldclutsrc = {
@@ -411,6 +410,7 @@ const AVFilter ff_vsrc_haldclutsrc = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = haldclutsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(haldclutsrc_outputs),
 };
 #endif /* CONFIG_HALDCLUTSRC_FILTER */
 
@@ -435,7 +435,6 @@ static const AVFilterPad nullsrc_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props,
     },
-    { NULL },
 };
 
 const AVFilter ff_vsrc_nullsrc = {
@@ -448,6 +447,7 @@ const AVFilter ff_vsrc_nullsrc = {
     .priv_class  = &nullsrc_class,
     .inputs      = NULL,
     .outputs     = nullsrc_outputs,
+    .nb_outputs  = FF_ARRAY_ELEMS(nullsrc_outputs),
 };
 
 #endif /* CONFIG_NULLSRC_FILTER */
@@ -671,7 +671,6 @@ static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_testsrc = {
@@ -685,6 +684,7 @@ const AVFilter ff_vsrc_testsrc = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_testsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_testsrc_outputs),
 };
 
 #endif /* CONFIG_TESTSRC_FILTER */
@@ -944,7 +944,6 @@ static const AVFilterPad avfilter_vsrc_testsrc2_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = test2_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_testsrc2 = {
@@ -958,6 +957,7 @@ const AVFilter ff_vsrc_testsrc2 = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_testsrc2_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_testsrc2_outputs),
 };
 
 #endif /* CONFIG_TESTSRC2_FILTER */
@@ -1119,7 +1119,6 @@ static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = rgbtest_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_rgbtestsrc = {
@@ -1133,6 +1132,7 @@ const AVFilter ff_vsrc_rgbtestsrc = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_rgbtestsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_rgbtestsrc_outputs),
 };
 
 #endif /* CONFIG_RGBTESTSRC_FILTER */
@@ -1295,7 +1295,6 @@ static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = yuvtest_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_yuvtestsrc = {
@@ -1309,6 +1308,7 @@ const AVFilter ff_vsrc_yuvtestsrc = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_yuvtestsrc_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_yuvtestsrc_outputs),
 };
 
 #endif /* CONFIG_YUVTESTSRC_FILTER */
@@ -1438,7 +1438,6 @@ static const AVFilterPad smptebars_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 #if CONFIG_PAL75BARS_FILTER
@@ -1486,6 +1485,7 @@ const AVFilter ff_vsrc_pal75bars = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = smptebars_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(smptebars_outputs),
 };
 
 #endif  /* CONFIG_PAL75BARS_FILTER */
@@ -1533,6 +1533,7 @@ const AVFilter ff_vsrc_pal100bars = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = smptebars_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(smptebars_outputs),
 };
 
 #endif  /* CONFIG_PAL100BARS_FILTER */
@@ -1601,6 +1602,7 @@ const AVFilter ff_vsrc_smptebars = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = smptebars_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(smptebars_outputs),
 };
 
 #endif  /* CONFIG_SMPTEBARS_FILTER */
@@ -1707,6 +1709,7 @@ const AVFilter ff_vsrc_smptehdbars = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = smptebars_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(smptebars_outputs),
 };
 
 #endif  /* CONFIG_SMPTEHDBARS_FILTER */
@@ -1771,7 +1774,6 @@ static const AVFilterPad avfilter_vsrc_allyuv_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_allyuv = {
@@ -1785,6 +1787,7 @@ const AVFilter ff_vsrc_allyuv = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_allyuv_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_allyuv_outputs),
 };
 
 #endif /* CONFIG_ALLYUV_FILTER */
@@ -1848,7 +1851,6 @@ static const AVFilterPad avfilter_vsrc_allrgb_outputs[] = {
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = allrgb_config_props,
     },
-    { NULL }
 };
 
 const AVFilter ff_vsrc_allrgb = {
@@ -1862,6 +1864,7 @@ const AVFilter ff_vsrc_allrgb = {
     .activate      = activate,
     .inputs        = NULL,
     .outputs       = avfilter_vsrc_allrgb_outputs,
+    .nb_outputs    = FF_ARRAY_ELEMS(avfilter_vsrc_allrgb_outputs),
 };
 
 #endif /* CONFIG_ALLRGB_FILTER */
