Index: apps/metadata/id3tags.c =================================================================== --- apps/metadata/id3tags.c (revision 29276) +++ apps/metadata/id3tags.c (working copy) @@ -358,8 +358,7 @@ if ((tag - entry->id3v2buf + desc_len + 2) < bufferpos) { /* At least part of the value was read, so we can safely try to - * parse it - */ + * parse it */ value = tag + desc_len + 1; value_len = bufferpos - (tag - entry->id3v2buf); @@ -368,8 +367,7 @@ entry->albumartist = tag; #if CONFIG_CODEC == SWCODEC } else { - value_len = parse_replaygain(tag, value, entry, tag, - value_len); + value_len = parse_replaygain(tag, value, entry, tag, value_len); #endif } } @@ -1040,6 +1038,12 @@ #endif if( tr->ppFunc ) bufferpos = tr->ppFunc(entry, tag, bufferpos); + + /* Trim. Take into account that multiple string contents will + * only be displayed up to their first null termination. All + * content after this null termination is obsolete and can be + * overwritten. */ + bufferpos -= (bytesread - strlen(tag)); /* Seek to the next frame */ if(framelen < totframelen) Index: apps/metadata/mp4.c =================================================================== --- apps/metadata/mp4.c (revision 29276) +++ apps/metadata/mp4.c (working copy) @@ -120,11 +120,17 @@ if (bytes_read) { - (*buffer)[bytes_read] = 0; - *dest = *buffer; - length = strlen(*buffer) + 1; - *buffer_left -= length; - *buffer += length; + /* Do not overwrite already available metadata. Especially when reading + * tags with e.g. multiple genres / artists. This way only the first + * of multiple entries is used, all following are dropped. */ + if (*dest == NULL) + { + (*buffer)[bytes_read] = 0; + *dest = *buffer; + length = strlen(*buffer) + 1; + *buffer_left -= length; + *buffer += length; + } } else { Index: apps/metadata/metadata_common.c =================================================================== --- apps/metadata/metadata_common.c (revision 29276) +++ apps/metadata/metadata_common.c (working copy) @@ -252,19 +252,26 @@ long len = 0; char** p; - if ((((strcasecmp(name, "track") == 0) && (type == TAGTYPE_APE))) - || ((strcasecmp(name, "tracknumber") == 0) && (type == TAGTYPE_VORBIS))) + if ((((strcasecmp(name, "track") == 0) && (type == TAGTYPE_APE )) || + ((strcasecmp(name, "tracknumber") == 0) && (type == TAGTYPE_VORBIS))) && + (id3->track_string == NULL) + ) { id3->tracknum = atoi(value); p = &(id3->track_string); } - else if (strcasecmp(name, "discnumber") == 0 || strcasecmp(name, "disc") == 0) + else if ((strcasecmp(name, "discnumber") == 0 || + strcasecmp(name, "disc") == 0) && + (id3->disc_string == NULL) + ) { id3->discnum = atoi(value); p = &(id3->disc_string); } - else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE)) - || ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS))) + else if ((((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE )) || + ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS))) && + (id3->year_string == NULL) + ) { /* Date's can be in any format in Vorbis. However most of them * are in ISO8601 format so if we try and parse the first part @@ -278,56 +285,58 @@ } p = &(id3->year_string); } - else if (strcasecmp(name, "title") == 0) + else if (strcasecmp(name, "title") == 0 && id3->title == NULL) { p = &(id3->title); } - else if (strcasecmp(name, "artist") == 0) + else if (strcasecmp(name, "artist") == 0 && id3->artist == NULL) { p = &(id3->artist); } - else if (strcasecmp(name, "album") == 0) + else if (strcasecmp(name, "album") == 0 && id3->album == NULL) { p = &(id3->album); } - else if (strcasecmp(name, "genre") == 0) + else if (strcasecmp(name, "genre") == 0 && id3->genre_string == NULL) { p = &(id3->genre_string); } - else if (strcasecmp(name, "composer") == 0) + else if (strcasecmp(name, "composer") == 0 && id3->composer == NULL) { p = &(id3->composer); } - else if (strcasecmp(name, "comment") == 0) + else if (strcasecmp(name, "comment") == 0 && id3->comment == NULL) { p = &(id3->comment); } - else if (strcasecmp(name, "albumartist") == 0) + else if (strcasecmp(name, "albumartist") == 0 && id3->albumartist == NULL) { p = &(id3->albumartist); } - else if (strcasecmp(name, "album artist") == 0) + else if (strcasecmp(name, "album artist") == 0 && id3->albumartist == NULL) { p = &(id3->albumartist); } - else if (strcasecmp(name, "ensemble") == 0) + else if (strcasecmp(name, "ensemble") == 0 && id3->albumartist == NULL) { p = &(id3->albumartist); } - else if (strcasecmp(name, "grouping") == 0) + else if (strcasecmp(name, "grouping") == 0 && id3->grouping == NULL) { p = &(id3->grouping); } - else if (strcasecmp(name, "content group") == 0) + else if (strcasecmp(name, "content group") == 0 && id3->grouping == NULL) { p = &(id3->grouping); } - else if (strcasecmp(name, "contentgroup") == 0) + else if (strcasecmp(name, "contentgroup") == 0 && id3->grouping == NULL) { p = &(id3->grouping); } - else if (strcasecmp(name, "musicbrainz_trackid") == 0 - || strcasecmp(name, "http://musicbrainz.org") == 0 ) + else if ((strcasecmp(name, "musicbrainz_trackid") == 0 || + strcasecmp(name, "http://musicbrainz.org") == 0 ) && + (id3->mb_track_id == NULL) + ) { p = &(id3->mb_track_id); }