Skip to content

Commit

Permalink
[scan] Fix issue where albums get split
Browse files Browse the repository at this point in the history
Regression from PR #1655. This reverts the metadata search to the method used
before the PR, so that search is done in the order set by the metadata maps.

This means the songalbumid is set by the tag with the highest precedence, not
just the first one found.

Closes #1696
  • Loading branch information
ejurgensen committed Dec 15, 2023
1 parent 2d33dea commit f657780
Showing 1 changed file with 36 additions and 46 deletions.
82 changes: 36 additions & 46 deletions src/library/filescanner_ffmpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct metadata_map {
int as_int;
size_t offset;
int (*handler_function)(struct media_file_info *, const char *);
int flags;
};

// Used for passing errors to DPRINTF (can't count on av_err2str being present)
Expand Down Expand Up @@ -196,7 +197,7 @@ static const struct metadata_map md_map_generic[] =
{ "artist-sort", 0, mfi_offsetof(artist_sort), NULL },
{ "album-sort", 0, mfi_offsetof(album_sort), NULL },
{ "compilation", 1, mfi_offsetof(compilation), NULL },
{ "lyrics", 0, mfi_offsetof(lyrics), NULL },
{ "lyrics", 0, mfi_offsetof(lyrics), NULL, AV_DICT_IGNORE_SUFFIX },

// ALAC sort tags
{ "sort_name", 0, mfi_offsetof(title_sort), NULL },
Expand Down Expand Up @@ -288,65 +289,56 @@ static const struct metadata_map md_map_id3[] =
{ NULL, 0, 0, NULL }
};


static int
extract_metadata_from_kv(struct media_file_info *mfi, const char *key, const char *value, const struct metadata_map *md_map)
extract_metadata_from_dict(struct media_file_info *mfi, AVDictionary *md, const struct metadata_map *md_map)
{
AVDictionaryEntry *mdt;
char **strval;
uint32_t *intval;
int mdcount = 0;
int i;

if ((value == NULL) || (strlen(value) == 0))
return 0;

if (strncasecmp(key, "lyrics-", sizeof("lyrics-") - 1) == 0)
key = "lyrics";

for (i = 0; md_map[i].key != NULL; i++)
#if 0
/* Dump all the metadata reported by ffmpeg */
while ((mdt = av_dict_iterate(md, mdt)))
{
if (strcasecmp(key, md_map[i].key) == 0)
break;
DPRINTF(E_DBG, L_SCAN, " -> %s = %s\n", mdt->key, mdt->value);
}
#endif

if (md_map[i].key == NULL)
return 0; // Not found in map

if (md_map[i].handler_function)
return md_map[i].handler_function(mfi, value);

if (!md_map[i].as_int)
for (i = 0; md_map[i].key != NULL; i++)
{
strval = (char **) ((char *) mfi + md_map[i].offset);
mdt = av_dict_get(md, md_map[i].key, NULL, md_map[i].flags);
if (!mdt || !mdt->value || strlen(mdt->value) == 0)
continue;

if (*strval != NULL)
return 0;
if (md_map[i].handler_function)
{
mdcount += md_map[i].handler_function(mfi, mdt->value);
continue;
}

*strval = strdup(value);
}
else
{
intval = (uint32_t *) ((char *) mfi + md_map[i].offset);
if (!md_map[i].as_int)
{
strval = (char **) ((char *) mfi + md_map[i].offset);

if (*intval != 0)
return 0;
if (*strval != NULL)
continue;

if (safe_atou32(value, intval) < 0)
return 0;
}
*strval = strdup(mdt->value);
}
else
{
intval = (uint32_t *) ((char *) mfi + md_map[i].offset);

return 1;
}
if (*intval != 0)
continue;

static int
extract_metadata_from_dict(struct media_file_info *mfi, AVDictionary *md, const struct metadata_map *md_map)
{
const AVDictionaryEntry *mdt = NULL;
int mdcount = 0;
if (safe_atou32(mdt->value, intval) < 0)
continue;
}

while ((mdt = av_dict_iterate(md, mdt)))
{
// DPRINTF(E_DBG, L_SCAN, " -> %s = %s\n", mdt->key, mdt->value);
mdcount += extract_metadata_from_kv(mfi, mdt->key, mdt->value, md_map);
mdcount++;
}

return mdcount;
Expand All @@ -355,11 +347,9 @@ extract_metadata_from_dict(struct media_file_info *mfi, AVDictionary *md, const
static int
extract_metadata(struct media_file_info *mfi, AVFormatContext *ctx, AVStream *audio_stream, AVStream *video_stream, const struct metadata_map *md_map)
{
int mdcount;
int mdcount = 0;
int ret;

mdcount = 0;

if (ctx->metadata)
{
ret = extract_metadata_from_dict(mfi, ctx->metadata, md_map);
Expand Down

0 comments on commit f657780

Please sign in to comment.