Commit ca85613d10 for ffmpeg
commit ca85613d10cd523dd05780f48dc6ecac142bd560
Author: Martin Mirchev <mmirchev@comp.nus.edu.sg>
Date: Wed Oct 21 19:04:05 2026 +0800
tests/fate/libavutil: add a test for the IAMF AVClass hierarchy
Print the child class tree of the IAMF AVClasses as returned by
av_opt_child_class_iterate() and look up options of the child classes
with av_opt_find2() and AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ.
Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 6e6246cb97..737d98e56f 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -292,6 +292,7 @@ TESTPROGS = adler32 \
hdr_dynamic_vivid_metadata \
hmac \
hwdevice \
+ iamf \
integer \
imgutils \
lfg \
diff --git a/libavutil/tests/iamf.c b/libavutil/tests/iamf.c
new file mode 100644
index 0000000000..9795948621
--- /dev/null
+++ b/libavutil/tests/iamf.c
@@ -0,0 +1,68 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "libavutil/iamf.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
+static void print_class_tree(const AVClass *class, int depth)
+{
+ const AVClass *child;
+ void *iter = NULL;
+
+ printf("%*s%s\n", depth * 2, "", class->class_name);
+ if (depth >= 8)
+ return;
+ while ((child = av_opt_child_class_iterate(class, &iter)))
+ print_class_tree(child, depth + 1);
+}
+
+static void find_option(const AVClass *class, const char *name)
+{
+ const AVOption *o = av_opt_find2(&class, name, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ,
+ NULL);
+ printf("%s: %s %s\n", class->class_name, name, o ? "found" : "not found");
+}
+
+int main(void)
+{
+ const AVClass *audio_element = av_iamf_audio_element_get_class();
+ const AVClass *mix_presentation = av_iamf_mix_presentation_get_class();
+ const AVClass *param_definition = av_iamf_param_definition_get_class();
+
+ printf("Testing av_opt_child_class_iterate()\n");
+ print_class_tree(audio_element, 0);
+ print_class_tree(mix_presentation, 0);
+ print_class_tree(param_definition, 0);
+
+ printf("\nTesting av_opt_find2() with AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ\n");
+ find_option(audio_element, "default_w");
+ find_option(audio_element, "ch_layout");
+ find_option(mix_presentation, "annotations");
+ find_option(mix_presentation, "default_mix_gain");
+ find_option(mix_presentation, "headphones_rendering_mode");
+ find_option(mix_presentation, "sound_system");
+ find_option(mix_presentation, "parameter_rate");
+ find_option(param_definition, "parameter_rate");
+ find_option(param_definition, "subblock_duration");
+
+ return 0;
+}
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index d45c7f5d89..fa55ebdbe3 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -139,6 +139,10 @@ FATE_LIBAVUTIL += fate-hmac
fate-hmac: libavutil/tests/hmac$(EXESUF)
fate-hmac: CMD = run libavutil/tests/hmac$(EXESUF)
+FATE_LIBAVUTIL += fate-iamf-class
+fate-iamf-class: libavutil/tests/iamf$(EXESUF)
+fate-iamf-class: CMD = run libavutil/tests/iamf$(EXESUF)
+
FATE_LIBAVUTIL += fate-imgutils
fate-imgutils: libavutil/tests/imgutils$(EXESUF)
fate-imgutils: CMD = run libavutil/tests/imgutils$(EXESUF)
diff --git a/tests/ref/fate/iamf-class b/tests/ref/fate/iamf-class
new file mode 100644
index 0000000000..518835a202
--- /dev/null
+++ b/tests/ref/fate/iamf-class
@@ -0,0 +1,30 @@
+Testing av_opt_child_class_iterate()
+AVIAMFAudioElement
+ AVIAMFLayer
+AVIAMFMixPresentation
+ AVIAMFSubmix
+ AVIAMFSubmixElement
+ AVIAMFParamDefinition
+ AVIAMFMixGain
+ AVIAMFDemixingInfo
+ AVIAMFReconGain
+ AVIAMFSubmixLayout
+ AVIAMFParamDefinition
+ AVIAMFMixGain
+ AVIAMFDemixingInfo
+ AVIAMFReconGain
+AVIAMFParamDefinition
+ AVIAMFMixGain
+ AVIAMFDemixingInfo
+ AVIAMFReconGain
+
+Testing av_opt_find2() with AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ
+AVIAMFAudioElement: default_w found
+AVIAMFAudioElement: ch_layout found
+AVIAMFMixPresentation: annotations found
+AVIAMFMixPresentation: default_mix_gain found
+AVIAMFMixPresentation: headphones_rendering_mode found
+AVIAMFMixPresentation: sound_system found
+AVIAMFMixPresentation: parameter_rate found
+AVIAMFParamDefinition: parameter_rate found
+AVIAMFParamDefinition: subblock_duration found