From: softworkz <softwo...@hotmail.com> Fixes Trac ticket https://trac.ffmpeg.org/ticket/6949
Signed-off-by: softworkz <softwo...@hotmail.com> --- avformat/id3v2: Support null-separated multi-value properties Fixes Trac ticket https://trac.ffmpeg.org/ticket/6949 Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-54%2Fsoftworkz%2Fsubmit_id3v2-v1 Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-54/softworkz/submit_id3v2-v1 Pull-Request: https://github.com/ffstaging/FFmpeg/pull/54 libavformat/id3v2.c | 65 ++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 29ee59e1f4..cebb4acd75 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -327,39 +327,55 @@ 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; + int encoding, nb_values = 0; unsigned genre; + AVDictionaryEntry *tag = NULL; if (taglen < 1) return; + tag = av_dict_get(*metadata, key, NULL, 0); + if (tag) + return; + 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; - } + /* Read all null-terminated values */ + while (taglen > 0) { + int n = 0, dict_flags = AV_DICT_APPEND | AV_DICT_DONT_STRDUP_VAL; - 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); - if (dst) - av_dict_set(metadata, key, dst, dict_flags); + if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && + (sscanf(dst, "(%d)", &genre) == 1 || (sscanf(dst, "%d%n", &genre, &n) == 1 && n == strlen(dst))) && + 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; + } + } else if (!*dst) { + av_freep(&dst); + return; + } + + if (dst) { + if (nb_values > 0) + av_dict_set(metadata, key, ";", dict_flags & ~AV_DICT_DONT_STRDUP_VAL); + + av_dict_set(metadata, key, dst, dict_flags); + nb_values++; + } + } } static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, @@ -372,7 +388,7 @@ static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, int encoding; int ok = 0; - if (taglen < 4) + if (taglen < 1) goto error; encoding = avio_r8(pb); @@ -383,10 +399,10 @@ static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, lang[3] = '\0'; taglen -= 3; - if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0 || taglen < 0) + if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0) goto error; - if (decode_str(s, pb, encoding, &text, &taglen) < 0 || taglen < 0) + if (decode_str(s, pb, encoding, &text, &taglen) < 0) goto error; // FFmpeg does not support hierarchical metadata, so concatenate the keys. @@ -1003,7 +1019,8 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, t++; } - ffio_init_read_context(&pb_local, buffer, b - buffer); + ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL, + NULL); tlen = b - buffer; pbx = &pb_local.pub; // read from sync buffer } @@ -1039,7 +1056,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err); goto seek; } - ffio_init_read_context(&pb_local, uncompressed_buffer, dlen); + ffio_init_context(&pb_local, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL); tlen = dlen; pbx = &pb_local.pub; // read from sync buffer } base-commit: 0e7c2a6287f977c30e08e2a211385c6a80614fe8 -- ffmpeg-codebot _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".