This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit b0c702aec28b00aa08cce05c6066e535a5c210a5
Author:     Romain Beauxis <[email protected]>
AuthorDate: Wed Mar 11 19:14:47 2026 -0500
Commit:     Romain Beauxis <[email protected]>
CommitDate: Sat Jul 18 09:59:57 2026 -0500

    libavformat/id3v2: deprecate legacy COMM descriptor-as-key behavior
---
 doc/APIchanges                        |  6 ++++
 libavformat/avformat.h                | 16 +++++++++++
 libavformat/id3v2.c                   | 53 ++++++++++++++++++-----------------
 libavformat/version.h                 |  2 +-
 libavformat/version_major.h           |  2 ++
 tests/ref/fate/id3v2-reenc-remux-keep |  7 +++--
 tests/ref/fate/id3v2-wma-comm         |  5 ++++
 tests/ref/fate/id3v2-wma-comm-asf_o   |  5 ++++
 8 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index a3a978c43b..2b0f3ab87e 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,12 @@ The last version increases of all libraries were on 2026-06-23.
 
 API changes, most recent first:
 
+2026-07-xx - xxxxxxxxxx - lavf 63.5.101 - version_major.h
+  Deprecate using descriptor for metadata tag name in id3v2 COMM tags.
+  COMM Tags are duplicated, exporting deprecated named tag along with
+  new <tag>-<description>-<lang> tag until the next libavformat major
+  version bumped.
+
 2026-07-14 - xxxxxxxxxx - lavu 61.5.100 - hwcontext_cuda.h
   Add AVCUDAFramesContext and AVCUDAArrayFrameDescriptor.
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 2ebe889b54..e5a6481aa8 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -357,6 +357,15 @@ struct AVFrame;
  * -  Several modifiers can be applied to the tag name. This is done by
  *    appending a dash character ('-') and the modifier name in the order
  *    they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng.
+ *    -  descriptor -- some formats (e.g. ID3v2 COMM and USLT frames) attach
+ *       a free-form descriptor to a tag to distinguish multiple instances.
+ *       The full key format is "<tag>-<descriptor>-<lang>", but either
+ *       component may be absent. When writing, the last dash-separated suffix
+ *       is interpreted as a language code if it is a valid ISO 639-2/B code;
+ *       otherwise the entire portion after the first dash is treated as a
+ *       descriptor. Examples: "comment-eng" (lang only),
+ *       "comment-MusicMatch_Bio-eng" (descriptor + lang),
+ *       "comment-foobar" (descriptor only, foobar is not a valid lang code).
  *    -  language -- a tag whose value is localized for a particular language
  *       is appended with the ISO 639-2/B 3-letter language code.
  *       For example: Author-ger=Michael, Author-eng=Mike
@@ -381,6 +390,9 @@ struct AVFrame;
                  e.g. "Various Artists" for compilation albums.
  artist       -- main creator of the work
  comment      -- any additional description of the file.
+                 ID3v2 COMM frames: bare "comment" has no lang or descriptor;
+                 "comment-<lang>" for lang only; "comment-<descriptor>-<lang>"
+                 for both (see descriptor modifier above).
  composer     -- who composed the work, if different from artist.
  copyright    -- name of copyright holder.
  creation_time-- date when the file was created, preferably in ISO 8601.
@@ -394,6 +406,10 @@ struct AVFrame;
  language     -- main language in which the work is performed, preferably
                  in ISO 639-2 format. Multiple languages can be specified by
                  separating them with commas.
+ lyrics       -- lyrics for the work.
+                 ID3v2 USLT frames: bare "lyrics" has no lang or descriptor;
+                 "lyrics-<lang>" for lang only; "lyrics-<descriptor>-<lang>"
+                 for both (see descriptor modifier above).
  performer    -- artist who performed the work, if different from artist.
                  E.g for "Also sprach Zarathustra", artist would be "Richard
                  Strauss" and performer "London Philharmonic Orchestra".
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 3e931d2bd2..1b4d4e65ef 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -39,7 +39,6 @@
 #include "libavutil/dict.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
-#include "libavutil/opt.h"
 #include "libavcodec/png.h"
 #include "avio_internal.h"
 #include "avlanguage.h"
@@ -379,9 +378,7 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, 
int taglen,
 /**
  * Parse a lang descr tag such as COMM and USLT.
  *
- * COMM with a non-empty descriptor: the descriptor becomes the bare key
- * (e.g. "MusicMatch_Bio").  USLT and all other cases produce
- * "<base>-<descriptor>-<lang>".
+ * A non-empty descriptor produces "<base>-<descriptor>-<lang>" keys.
  */
 static void read_lang_descr_tag(AVFormatContext *s, AVIOContext *pb,
                                 const char *key, int taglen,
@@ -424,29 +421,35 @@ static void read_lang_descr_tag(AVFormatContext *s, 
AVIOContext *pb,
     }
 
     if (descriptor && *descriptor) {
+#if FF_API_OLD_ID3V2_COMMENT
         if (!strcmp(key, "comment")) {
-            /* legacy COMM: non-empty descriptor becomes the metadata key */
-            flags |= AV_DICT_DONT_STRDUP_KEY;
-            key = (char *)descriptor;
-            descriptor = NULL;
-        } else {
-            /* USLT: <tag>-<descriptor>-<lang> */
-            if (av_strnlen(language, 3) > 0)
-                full_key = av_asprintf("%s-%s-%s", key, descriptor, language);
-            else if (strlen((char *)descriptor) == 3 &&
-                     ff_convert_lang_to((char *)descriptor, 
AV_LANG_ISO639_2_BIBL))
-                /* Descriptor looks like a lang code: add trailing lang to
-                 * keep the key unambiguous on the write side. */
-                full_key = av_asprintf("%s-%s-und", key, descriptor);
-            else
-                full_key = av_asprintf("%s-%s", key, descriptor);
-            if (!full_key) {
-                av_freep(&descriptor);
-                av_freep(&dst);
-                return;
-            }
-            key = full_key;
+            av_log(s, AV_LOG_WARNING,
+                   "Deprecated: COMM descriptor '%s' used as metadata key. "
+                   "This will change in a future version.\n", descriptor);
+            av_dict_set(metadata, (const char *)descriptor, (const char *)dst,
+                        AV_DICT_DONT_OVERWRITE);
+        }
+#endif
+        int descr_len = strlen((char *)descriptor);
+        if (av_strnlen(language, 3) > 0)
+            full_key = av_asprintf("%s-%s-%s", key, descriptor, language);
+                 // descr = "eng"
+        else if ((descr_len == 3 &&
+                 ff_convert_lang_to((char *)descriptor, 
AV_LANG_ISO639_2_BIBL)) ||
+                 // descr = Foo-eng
+                 (descr_len > 4 && descriptor[descr_len-4] == '-' &&
+                 ff_convert_lang_to((char *)descriptor+descr_len-3, 
AV_LANG_ISO639_2_BIBL))) {
+            /* Descriptor looks like a lang code: add trailing lang to
+             * keep the key unambiguous on the write side. */
+            full_key = av_asprintf("%s-%s-und", key, descriptor);
+        } else
+            full_key = av_asprintf("%s-%s", key, descriptor);
+        if (!full_key) {
+            av_freep(&descriptor);
+            av_freep(&dst);
+            return;
         }
+        key = full_key;
     } else if (av_strnlen(language, 3) == 3) {
         full_key = av_asprintf("%s-%s", key, language);
         if (!full_key) {
diff --git a/libavformat/version.h b/libavformat/version.h
index e2634b85ae..384cbd49cc 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
 #include "version_major.h"
 
 #define LIBAVFORMAT_VERSION_MINOR   5
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MICRO 101
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
diff --git a/libavformat/version_major.h b/libavformat/version_major.h
index 1e43129016..f0eaa170b4 100644
--- a/libavformat/version_major.h
+++ b/libavformat/version_major.h
@@ -47,6 +47,8 @@
 
 #define FF_API_LCEVC_STRUCT             (LIBAVFORMAT_VERSION_MAJOR < 64)
 
+#define FF_API_OLD_ID3V2_COMMENT        (LIBAVFORMAT_VERSION_MAJOR < 64)
+
 #define FF_API_R_FRAME_RATE            1
 
 #endif /* AVFORMAT_VERSION_MAJOR_H */
diff --git a/tests/ref/fate/id3v2-reenc-remux-keep 
b/tests/ref/fate/id3v2-reenc-remux-keep
index e685b11291..7bf43f0612 100644
--- a/tests/ref/fate/id3v2-reenc-remux-keep
+++ b/tests/ref/fate/id3v2-reenc-remux-keep
@@ -1,9 +1,12 @@
-263462774b77f2b20a9cb5cbe492f910 *tests/data/fate/id3v2-reenc-remux-keep.mp3
-192072 tests/data/fate/id3v2-reenc-remux-keep.mp3
+f68df33ad53e6175269f7ea876b492e3 *tests/data/fate/id3v2-reenc-remux-keep.mp3
+192378 tests/data/fate/id3v2-reenc-remux-keep.mp3
 [FORMAT]
 TAG:title=7rk
 TAG:iTunPGAP=0
+TAG:comment-iTunPGAP-eng=0
 TAG:encoded_by=iTunes 12.7.0.166
 TAG:iTunNORM= 00000362 000004C0 0000308F 00003CC5 00000DAC 00000DAC 00007D14 
00007AC9 000007C1 0000175E
+TAG:comment-iTunNORM-eng= 00000362 000004C0 0000308F 00003CC5 00000DAC 
00000DAC 00007D14 00007AC9 000007C1 0000175E
 TAG:iTunSMPB= 00000000 00000210 0000086A 0000000000066486 00000000 0002DA9D 
00000000 00000000 00000000 00000000 00000000 00000000
+TAG:comment-iTunSMPB-eng= 00000000 00000210 0000086A 0000000000066486 00000000 
0002DA9D 00000000 00000000 00000000 00000000 00000000 00000000
 [/FORMAT]
diff --git a/tests/ref/fate/id3v2-wma-comm b/tests/ref/fate/id3v2-wma-comm
index 68d113862c..e2f19f5077 100644
--- a/tests/ref/fate/id3v2-wma-comm
+++ b/tests/ref/fate/id3v2-wma-comm
@@ -11,11 +11,16 @@ TAG:genre=Inconnu
 TAG:comment-eng=
 TAG:lyrics-eng=
 TAG:MusicMatch_Bio=
+TAG:comment-MusicMatch_Bio-eng=
 TAG:TLEN=286000
 TAG:MusicMatch_Tempo=
+TAG:comment-MusicMatch_Tempo-eng=
 TAG:MusicMatch_Mood=
+TAG:comment-MusicMatch_Mood-eng=
 TAG:MusicMatch_Preference=
+TAG:comment-MusicMatch_Preference-eng=
 TAG:MusicMatch_Situation=
+TAG:comment-MusicMatch_Situation-eng=
 TAG:track=5
 TAG:composer=Jacques Higelin
 TAG:WM/EncodingTime=127518048290000000
diff --git a/tests/ref/fate/id3v2-wma-comm-asf_o 
b/tests/ref/fate/id3v2-wma-comm-asf_o
index 639f0a02ce..5d8e02aac6 100644
--- a/tests/ref/fate/id3v2-wma-comm-asf_o
+++ b/tests/ref/fate/id3v2-wma-comm-asf_o
@@ -13,11 +13,16 @@ TAG:genre=Inconnu
 TAG:comment-eng=
 TAG:lyrics-eng=
 TAG:MusicMatch_Bio=
+TAG:comment-MusicMatch_Bio-eng=
 TAG:TLEN=286000
 TAG:MusicMatch_Tempo=
+TAG:comment-MusicMatch_Tempo-eng=
 TAG:MusicMatch_Mood=
+TAG:comment-MusicMatch_Mood-eng=
 TAG:MusicMatch_Preference=
+TAG:comment-MusicMatch_Preference-eng=
 TAG:MusicMatch_Situation=
+TAG:comment-MusicMatch_Situation-eng=
 TAG:WM/TrackNumber=5
 TAG:WM/Composer=Jacques Higelin
 TAG:WM/Genre=Inconnu

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to