diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2025-04-16 03:20:14 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2025-04-16 13:09:05 +0200 |
commit | 058d49b1684de54952f5776bf32779f51c46a39a (patch) | |
tree | e61c1d7d75659329867f93aee2098e257c85656e | |
parent | cf7dfddee4068c65811965dcea42d9a86c104bca (diff) | |
download | ffmpeg-058d49b1684de54952f5776bf32779f51c46a39a.tar.gz |
Revert "lavf/id3v2dec: support multiple values and TIPL frames"
see: Re: [FFmpeg-devel] [PATCH 2/2] avformat/id3v2: Check that decode_str() did advance
but in short, first our API since 16years says we dont have multiple values per key
(which it supports since 9 years only)
and it causes some problems for ffprobe apparently.
I do believe the original patch is the correct direction but it requires
more changes. So revert this until other things are in place and until
we have a consensus.
This reverts commit 80b77e8e8d0630710ad6069133f397459015f139.
-rw-r--r-- | libavformat/id3v2.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 90314583a7..0441824126 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -327,12 +327,8 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, AVDictionary **metadata, const char *key) { uint8_t *dst; - uint8_t *dst_key = NULL; - int encoding, dict_flags = AV_DICT_MULTIKEY | AV_DICT_DONT_STRDUP_VAL | AV_DICT_DEDUP; + int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL; unsigned genre; - int count = 0; - int is_tipl = !(strcmp(key, "TIPL") && strcmp(key, "TMCL") && - strcmp(key, "IPL")); if (taglen < 1) return; @@ -340,33 +336,30 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, encoding = avio_r8(pb); taglen--; /* account for encoding type byte */ - 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); + 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; 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); - 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); + if (dst) + av_dict_set(metadata, key, dst, dict_flags); } static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, @@ -1051,7 +1044,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, pbx = &pb_local.pub; // read from sync buffer } #endif - if (tag[0] == 'T' || !strcmp(tag, "IPL")) + if (tag[0] == 'T') /* parse text tag */ read_ttag(s, pbx, tlen, metadata, tag); else if (!memcmp(tag, "USLT", 4)) |