From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id A20844CEAF for ; Tue, 2 Dec 2025 16:48:08 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'1OUnLvXmGmkJ/JvsWdv7YLuet7CiN+yW62joXOTm3HU=', expected b'8ibEFR2cs/8acL9krlM/7gVp2svWz01OhqYD1hJnaKw=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1764694074; h=mime-version : to : date : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=1OUnLvXmGmkJ/JvsWdv7YLuet7CiN+yW62joXOTm3HU=; b=5FZ7ybOKXW8exi38wCiqAz4ueQ3l6z60ka08hbR7V8Dxbqgac9BoSESaTH91+4oBGw6/N C3YKM1qklpYZZHE+yebFBZYc+CbasN3ROFB3H0Lngo/6z+3W390WIEdID16Un/hfq6/eRiP tox1cAyMZ3x3L4++HOtVpE4PS3gNaOJrbIbBoWvX8tRnsdzE3FmQ0dNOZL7cgRE+xJyw0fs QxyLyKzhFvv8TG6nFKqCDF5w7X+uToAUe2bqu8bwg4BWYqqgYEYBATC3CauDxTMjdk6drX/ JUqNazEr3So9vtnIAq+QCXXCmTyR8/fACXv9VKkJP2wA3BHRAusEekworsBw== Received: from [172.19.0.3] (unknown [172.19.0.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 6FF6569047C; Tue, 2 Dec 2025 18:47:54 +0200 (EET) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1764694062; b=M93bengJceQrx/xCKHlIOQTi5rm7suNx+bLhd1zoJMdNuZbLP7B9YAdjP8L7OKDnptJK0 oCFGVdel9yyoF2u7AUSkaV78w8/rycXPm9/7s8EWNosbfrdNr1bV2OksJQ4Bi4iAVCXL1n4 fIjpXMDxCQQqs5RWQ3sKngb2dxKls+0ROtzMS21VEecaoC4yTaMP9tGu3wFSIhh3syg0aPw TC/LOCNF8wF8s6IRrbwgHN55TUZ8CfxcY4lBkWgWBBH+EP8C9WD75mq0yJ7ByxdaY5lrLON nai1hjwxP0aIPnB8JicKfEQCPxX4BkyaiOQnayI/0ptCWHyG9EbVGVG8RWlA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1764694062; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=NmFzlpuE+PGIr2hvKRigbLB2+93r3ecHolABbSpMYJs=; b=qbnUj558dF+jUTEUNxQt20YBJUwe+3HsC8IgultS4G6Zsd7sryCmqL2FV+crlgkeJhdSl LiB/cBdDBxQxyRqh2KgH2HNQG7C293N5mgyhHJcihiRNGgDlGjWdCaY8GfrIOfxWYj1LD4w OET9VkKvlvNQn/hhC/b4csRvbZ650nhWv0FHUfICGOITTjjvfcbPu+ISHp+erD3+qXj4g4Q FOZfVqSwGpPZzXDrmtBl4ThpXQ4ryN2PnO0xYvGMj8Ekte+T6NkRVWYhsXhXmiMPbS79Zf3 0mLcZvN2+HpRoSdkV915a/nVU3ULzn7F3q9H7jemvtWvbY8oB6YE3YpAwc5Q== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=pass header.from=ffmpeg.org policy.dmarc=quarantine Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=pass (Used From Domain Record) header.from=ffmpeg.org policy.dmarc=quarantine DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1764694053; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : date : from; bh=8ibEFR2cs/8acL9krlM/7gVp2svWz01OhqYD1hJnaKw=; b=AI+Z0FUUlL4CxULAzrWs2EPwZXZ2HYZ6InswwoNb3F35loECu7P8XTWkCow7c5qONf9mv SE/Z+c6yAhTMUdyH5eNVu3DVfZsZ4BjvFZMRZrRFrCND7efS4rKLaRmwYIm38P92zw/SnYv hkMw+FNG+fTaxnG2bMPw8X88cb0QSFfmvnGUZmyxOSdfTyiJz93iWvdltLBk+P/9BvZYaS1 yIR/GXTGaFN26hTSpFlYmCG432pq4w2sBQogOntO73Z0dNB8xwLC6mK1ED3xjblpsSbmWTJ TI/8Wy3s2uLzdWaZ0Wl0QZOaoyeZhktONVS0IIICEnXGKzNO/YTqyVHiutfQ== Received: from 55ca25703178 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 1F8A269040F for ; Tue, 2 Dec 2025 18:47:33 +0200 (EET) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Date: Tue, 02 Dec 2025 16:47:32 -0000 Message-ID: <176469405328.39.4170251048618595780@2cb04c0e5124> Message-ID-Hash: F647VUUM35DTZCXX6A4CKBQT6ABQGV62 X-Message-ID-Hash: F647VUUM35DTZCXX6A4CKBQT6ABQGV62 X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] Add support for COMM frames in id3v2 tags. (PR #21079) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: toots via ffmpeg-devel Cc: toots Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #21079 opened by toots URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21079 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21079.patch >>From e87ebff53376354ffc5902c9404e65df534a3041 Mon Sep 17 00:00:00 2001 From: Romain Beauxis Date: Tue, 2 Dec 2025 10:43:46 -0600 Subject: [PATCH] Add support for COMM frames in id3v2 tags. --- libavformat/id3v2.c | 1 + libavformat/id3v2enc.c | 58 +++++++++++++++++++++++++++++++++++++++ tests/fate-run.sh | 13 +++++++++ tests/fate/id3v2.mak | 4 +++ tests/ref/fate/id3v2-comm | 5 ++++ 5 files changed, 81 insertions(+) create mode 100644 tests/ref/fate/id3v2-comm diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 3ce2fadce8..392a7e6730 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -44,6 +44,7 @@ #include "id3v2.h" const AVMetadataConv ff_id3v2_34_metadata_conv[] = { + { "COMM", "comment" }, { "TALB", "album" }, { "TCOM", "composer" }, { "TCON", "genre" }, diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c index ac907c2758..02dc3fc68a 100644 --- a/libavformat/id3v2enc.c +++ b/libavformat/id3v2enc.c @@ -25,6 +25,7 @@ #include "libavutil/dict.h" #include "libavutil/intreadwrite.h" #include "avformat.h" +#include "avlanguage.h" #include "avio.h" #include "avio_internal.h" #include "id3v2.h" @@ -58,6 +59,48 @@ static void id3v2_encode_string(AVIOContext *pb, const uint8_t *str, put(pb, str); } +/** + * Write a comment frame according to encoding (only UTF-8 or UTF-16+BOM + * supported). + * @return number of bytes written or a negative error code. + */ +static int id3v2_put_comm(ID3v2EncContext *id3, AVIOContext *avioc, const char *lang, const char *descr, + const char *comment, enum ID3v2Encoding enc) +{ + int len, ret; + uint8_t *pb; + AVIOContext *dyn_buf; + if ((ret = avio_open_dyn_buf(&dyn_buf)) < 0) + return ret; + + /* check if the strings are ASCII-only and use UTF16 only if + * they're not */ + if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(comment) && + (!descr || string_is_ascii(descr))) + enc = ID3v2_ENCODING_ISO8859; + + avio_w8(dyn_buf, enc); + avio_write(dyn_buf, lang && strlen(lang) == 3 ? lang : "und", 3); + if (descr) + id3v2_encode_string(dyn_buf, descr, enc); + else + avio_w8(dyn_buf, 0); + id3v2_encode_string(dyn_buf, comment, enc); + len = avio_get_dyn_buf(dyn_buf, &pb); + + avio_wb32(avioc, MKBETAG('C', 'O', 'M', 'M')); + /* ID3v2.3 frame size is not sync-safe */ + if (id3->version == 3) + avio_wb32(avioc, len); + else + id3v2_put_size(avioc, len); + avio_wb16(avioc, 0); + avio_write(avioc, pb, len); + + ffio_free_dyn_buf(&dyn_buf); + return len + ID3v2_HEADER_SIZE; +} + /** * Write a text frame with one (normal frames) or two (TXXX frames) strings * according to encoding (only UTF-8 or UTF-16+BOM supported). @@ -221,8 +264,14 @@ static int write_metadata(AVIOContext *pb, AVDictionary **metadata, ID3v2EncContext *id3, int enc) { const AVDictionaryEntry *t = NULL; + const char *lang = NULL; + const AVDictionaryEntry *lang_tag; int ret; + lang_tag = av_dict_get(*metadata, "language", NULL, 0); + if (lang_tag) + lang = ff_convert_lang_to(lang_tag->value, AV_LANG_ISO639_2_BIBL); + ff_metadata_conv(metadata, ff_id3v2_34_metadata_conv, NULL); if (id3->version == 3) id3v2_3_metadata_split_date(metadata); @@ -230,6 +279,15 @@ static int write_metadata(AVIOContext *pb, AVDictionary **metadata, ff_metadata_conv(metadata, ff_id3v2_4_metadata_conv, NULL); while ((t = av_dict_iterate(*metadata, t))) { + if (!strncmp(t->key, "COMM", 4)) { + ret = id3v2_put_comm(id3, pb, lang, NULL, t->value, enc); + if (ret < 0) + return ret; + + id3->len += ret; + continue; + } + if ((ret = id3v2_check_write_tag(id3, pb, t, ff_id3v2_tags, enc)) > 0) { id3->len += ret; continue; diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 6d1fe1185c..fd564ff945 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -94,6 +94,19 @@ runecho(){ $target_exec $target_path/"$@" >&3 } +run_with_temp(){ + tmpfile=`mktemp` + trap 'rm -rf "$tmpfile"' EXIT + create_tmp=$1 + run "$create_tmp $tmpfile" + ret=$? + if [ $ret -ne 0 ]; then + exit $? + fi + process_tmp=$2 + run "$process_tmp $tmpfile" +} + probefmt(){ run ffprobe${PROGSUF}${EXECSUF} -bitexact -threads $threads -show_entries format=format_name -print_format default=nw=1:nk=1 "$@" } diff --git a/tests/fate/id3v2.mak b/tests/fate/id3v2.mak index 7ad4d877a4..0ff8451529 100644 --- a/tests/fate/id3v2.mak +++ b/tests/fate/id3v2.mak @@ -4,6 +4,10 @@ fate-id3v2-priv: CMD = probetags $(TARGET_SAMPLES)/id3v2/id3v2_priv.mp3 FATE_ID3V2_FFMPEG_FFPROBE-$(call REMUX, MP3) += fate-id3v2-priv-remux fate-id3v2-priv-remux: CMD = transcode mp3 $(TARGET_SAMPLES)/id3v2/id3v2_priv.mp3 mp3 "-c copy" "-c copy -t 0.1" "-show_entries format_tags" +FATE_ID3V2_FFMPEG_FFPROBE-$(call REMUX, MP3) += fate-id3v2-comm +fate-id3v2-comm: $(FFMPEG) $(FFPROBE) +fate-id3v2-comm: CMD = run_with_temp "$(FFMPEG) -nostdin -hide_banner -loglevel quiet -f lavfi -i sine=frequency=1000:duration=2 -id3v2_version 3 -metadata \"comment=Testing Comment\" -metadata language=eng -y" "$(FFPROBE) -bitexact -show_entries format_tags" + FATE_ID3V2_FFMPEG_FFPROBE-$(call REMUX, AIFF, WAV_DEMUXER) += fate-id3v2-chapters fate-id3v2-chapters: CMD = transcode wav $(TARGET_SAMPLES)/wav/200828-005.wav aiff "-c copy -metadata:c:0 description=foo -metadata:c:0 date=2021 -metadata:c copyright=none -metadata:c:1 genre=nonsense -write_id3v2 1" "-c copy -t 0.05" "-show_entries format_tags:chapters" diff --git a/tests/ref/fate/id3v2-comm b/tests/ref/fate/id3v2-comm new file mode 100644 index 0000000000..11b48bb831 --- /dev/null +++ b/tests/ref/fate/id3v2-comm @@ -0,0 +1,5 @@ +[FORMAT] +TAG:comment=Testing Comment +TAG:language=eng +TAG:encoder=Lavf62.6.103 +[/FORMAT] -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org