From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 523804405F for ; Thu, 25 Aug 2022 00:27:53 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4437A68B8F3; Thu, 25 Aug 2022 03:27:38 +0300 (EEST) Received: from mail-qt1-f175.google.com (mail-qt1-f175.google.com [209.85.160.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 21A9968B937 for ; Thu, 25 Aug 2022 03:27:31 +0300 (EEST) Received: by mail-qt1-f175.google.com with SMTP id a4so14085384qto.10 for ; Wed, 24 Aug 2022 17:27:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rcombs.me; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc; bh=kSRRoBFkBOWQ1BGEXZopxUfT2hRwJvMLYOw8EvMyDFI=; b=r67IuHoZybrRfJo6wcVj6f2SW64Ul8ZLSCvJwTkbbMuJL0Drh6MzuBHkr42WNxXz2x vMhMsPihnsI1bBANEOgCw+DVU/6UbsZTIWEZztbCwyCYXOvCHbFlkmQFylrPwYCX+Agd Dc7ML0SmqibvrJ+Wf3AK3qV16ZEsy4VFWa3pAUBhcCtVxyEyiLegnUydspck/PTL/bRn fjssBD28Hgxb+2ETsKvw1awzRzHGmM07CGkZkk95SCkyxiiryFKJ1GEiqVNL5Xn3+qKD wZ3+D+ZnOCXMTOZuHzF09do/J8XWvADIpYRrO5iI4U77mpTc+SglS55swlKQpVUM2G1w rvxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc; bh=kSRRoBFkBOWQ1BGEXZopxUfT2hRwJvMLYOw8EvMyDFI=; b=004XwcFDhlp/kxcsc1UxiHbG8IxPN9JeZIKAt4OEaZFl0LRtakfjihjAuwlC6+a4kP U+h5hM67wzozCvhABp3oHZVnmM9c5RHSHbPfx6x25qve90hiKKS4ryX+LKGVfXjKNFUi HrBNafq0si6u1T2lmlpQwYv9YusNlYNVxmvXN+lOULSqtNr2zEC+l9QsOZaQsOufsmgD PXFCpLEVNyE7zcI237h7cBlDZNU17eoJayY3Q+Rc5wpkCOtLjKSh17MGnu7SnKBHlmE+ XBebruzSgVRrl3O90ePJX7RvYR+8tZqhxgtb3pgoB1agWEg3A9BPQ9RhKW6novR7uSuT dNyw== X-Gm-Message-State: ACgBeo19Fxv+9qkto96q3l6BoV0Z/mA23VA7UqG40/LtLsBHc+gCmu2w Zp7eFTh1Zrdqlh/F36m8no0Xk8VXGl/H X-Google-Smtp-Source: AA6agR6vAGlimx8ShX6okoZ6X+ZelsVtt7LUC2Axm8ozucfKq+Gdi0CO43mgSVfuY0GKj6sZuITINw== X-Received: by 2002:ac8:5cc2:0:b0:344:50c9:5308 with SMTP id s2-20020ac85cc2000000b0034450c95308mr1683021qta.602.1661387249728; Wed, 24 Aug 2022 17:27:29 -0700 (PDT) Received: from localhost.localdomain ([192.210.24.132]) by smtp.gmail.com with ESMTPSA id i22-20020a05620a405600b006bba9575621sm16521091qko.68.2022.08.24.17.27.29 for (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 24 Aug 2022 17:27:29 -0700 (PDT) From: rcombs To: ffmpeg-devel@ffmpeg.org Date: Wed, 24 Aug 2022 19:27:22 -0500 Message-Id: <20220825002722.79902-3-rcombs@rcombs.me> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220825002722.79902-1-rcombs@rcombs.me> References: <20220825002722.79902-1-rcombs@rcombs.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/3] lavf/id3v2dec: support multiple values and TIPL frames X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Fixes https://trac.ffmpeg.org/ticket/6949 Ordinary text frames in ID3v2 are allowed to have multiple (null-separated) values. This technically isn't allowed in TXXX, but it's used in practice by Picard, and supporting it is harmless. TIPL/IPL (Involved People List) and TMCL (Musician Credits List) work similarly to TXXX, but alternate key-value-key-value. --- libavformat/id3v2.c | 49 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 191a305ffb..335a1436b2 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -321,8 +321,12 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, AVDictionary **metadata, const char *key) { uint8_t *dst; - int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL; + uint8_t *dst_key = NULL; + int encoding, dict_flags = AV_DICT_MULTIKEY | AV_DICT_DONT_STRDUP_VAL | AV_DICT_DEDUP; unsigned genre; + int count = 0; + int is_tipl = !(strcmp(key, "TIPL") && strcmp(key, "TMCL") && + strcmp(key, "IPL")); if (taglen < 1) return; @@ -330,30 +334,33 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, encoding = avio_r8(pb); taglen--; /* account for encoding type byte */ - if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { - av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); - return; - } - - if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && - (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) && - genre <= ID3v1_GENRE_MAX) { - av_freep(&dst); - dst = av_strdup(ff_id3v1_genre_str[genre]); - } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { - /* dst now contains the key, need to get value */ - key = dst; + while (taglen > 1) { if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); - av_freep(&key); return; } - dict_flags |= AV_DICT_DONT_STRDUP_KEY; - } else if (!*dst) - av_freep(&dst); - if (dst) - av_dict_set(metadata, key, dst, dict_flags); + count++; + + if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && + (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) && + genre <= ID3v1_GENRE_MAX) { + av_freep(&dst); + dst = av_strdup(ff_id3v1_genre_str[genre]); + } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX")) || + (is_tipl && (count & 1))) { + /* dst now contains the key, need to get value */ + av_free(dst_key); + key = dst_key = dst; + continue; + } else if (!*dst) + av_freep(&dst); + + if (dst) + av_dict_set(metadata, key, dst, dict_flags); + } + + av_free(dst_key); } static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, @@ -1039,7 +1046,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, pbx = &pb_local.pub; // read from sync buffer } #endif - if (tag[0] == 'T') + if (tag[0] == 'T' || !strcmp(tag, "IPL")) /* parse text tag */ read_ttag(s, pbx, tlen, metadata, tag); else if (!memcmp(tag, "USLT", 4)) -- 2.37.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".