Commit 5664e9e97f for ffmpeg

commit 5664e9e97f47951bf5286bd3a8f3547f30b811b5
Author: Romain Beauxis <romain.beauxis@gmail.com>
Date:   Thu Oct 15 15:31:57 2026 +0200

    tests/fate: check that every packet side data type has a handle

    Walk all the side data types: each one has to have a handle, which has to
    find the type again and not be shared. The handles are compared with the
    reference, so that a new type fails the test until it gets one and a
    released handle cannot change unnoticed.

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3d0be56320..53c638c878 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1390,6 +1390,7 @@ TESTPROGS = avcodec                                                     \
             htmlsubtitles                                               \
             jpeg2000dwt                                                 \
             mathops                                                    \
+            packet_side_data_handle                                     \

 TESTPROGS-$(CONFIG_AC3DSP)                += ac3
 TESTPROGS-$(CONFIG_APV_DECODER)           += apv
diff --git a/libavcodec/tests/.gitignore b/libavcodec/tests/.gitignore
index 8e4f26c2ad..3e986b00dd 100644
--- a/libavcodec/tests/.gitignore
+++ b/libavcodec/tests/.gitignore
@@ -19,5 +19,6 @@
 /mjpegenc_huffman
 /mpeg12framerate
 /mpegaudiodecheader
+/packet_side_data_handle
 /rangecoder
 /snowenc
diff --git a/libavcodec/tests/packet_side_data_handle.c b/libavcodec/tests/packet_side_data_handle.c
new file mode 100644
index 0000000000..df1da8b73d
--- /dev/null
+++ b/libavcodec/tests/packet_side_data_handle.c
@@ -0,0 +1,65 @@
+/*
+ * 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 <string.h>
+
+#include "libavcodec/packet.h"
+#include "libavcodec/packet_internal.h"
+
+#define HANDLE_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_"
+
+#define SET_HANDLE(type, handle)                                          \
+    if (handles[AV_PKT_DATA_ ## type]) {                                  \
+        printf("%s: second handle %s\n", #type, handle);                  \
+        ret = 1;                                                          \
+    }                                                                     \
+    handles[AV_PKT_DATA_ ## type] = handle;
+
+/*
+ * Every side data type needs exactly one handle, and no two types may share
+ * one. A handle is typed in options, where '+' and '-' have a meaning, so it
+ * is made of [a-z0-9_] only. The handles are printed and compared with the
+ * reference, since a released handle must not change.
+ */
+int main(void)
+{
+    const char *handles[AV_PKT_DATA_NB] = { NULL };
+    int ret = 0;
+
+    FF_PACKET_SIDE_DATA_HANDLES(SET_HANDLE)
+
+    for (int type = 0; type < AV_PKT_DATA_NB; type++) {
+        printf("%2d: %s\n", type, handles[type] ? handles[type] : "(none)");
+        if (!handles[type])
+            ret = 1;
+        else if (strspn(handles[type], HANDLE_CHARS) != strlen(handles[type])) {
+            printf("%2d: character outside of [a-z0-9_]\n", type);
+            ret = 1;
+        }
+
+        for (int other = 0; handles[type] && other < type; other++) {
+            if (handles[other] && !strcmp(handles[type], handles[other])) {
+                printf("%2d: handle of type %d\n", type, other);
+                ret = 1;
+            }
+        }
+    }
+
+    return ret;
+}
diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak
index 3cde003212..713b1feb36 100644
--- a/tests/fate/libavcodec.mak
+++ b/tests/fate/libavcodec.mak
@@ -17,6 +17,10 @@ fate-avpacket: libavcodec/tests/avpacket$(EXESUF)
 fate-avpacket: CMD = run libavcodec/tests/avpacket$(EXESUF)
 fate-avpacket: CMP = null

+FATE_LIBAVCODEC-yes += fate-packet-side-data-handle
+fate-packet-side-data-handle: libavcodec/tests/packet_side_data_handle$(EXESUF)
+fate-packet-side-data-handle: CMD = run libavcodec/tests/packet_side_data_handle$(EXESUF)
+
 FATE_LIBAVCODEC-yes += fate-bitstream-be
 fate-bitstream-be: libavcodec/tests/bitstream_be$(EXESUF)
 fate-bitstream-be: CMD = run libavcodec/tests/bitstream_be$(EXESUF)
diff --git a/tests/ref/fate/packet-side-data-handle b/tests/ref/fate/packet-side-data-handle
new file mode 100644
index 0000000000..126936a739
--- /dev/null
+++ b/tests/ref/fate/packet-side-data-handle
@@ -0,0 +1,44 @@
+ 0: palette
+ 1: new_extradata
+ 2: param_change
+ 3: h263_mb_info
+ 4: replaygain
+ 5: displaymatrix
+ 6: stereo3d
+ 7: audio_service_type
+ 8: quality_stats
+ 9: fallback_track
+10: cpb_properties
+11: skip_samples
+12: jp_dualmono
+13: strings_metadata
+14: subtitle_position
+15: matroska_blockadditional
+16: webvtt_identifier
+17: webvtt_settings
+18: metadata_update
+19: mpegts_stream_id
+20: mastering_display_metadata
+21: spherical
+22: content_light_level
+23: a53_cc
+24: encryption_init_info
+25: encryption_info
+26: afd
+27: prft
+28: icc_profile
+29: dovi_conf
+30: s12m_timecode
+31: hdr10_plus
+32: iamf_mix_gain_param
+33: iamf_demixing_info_param
+34: iamf_recon_gain_info_param
+35: ambient_viewing_environment
+36: frame_cropping
+37: lcevc
+38: 3d_reference_displays
+39: rtcp_sr
+40: exif
+41: hdr_smpte_2094_app5
+42: hevc_conf
+43: gain_map_params