gst/id3demux/: Do not convert obsolete TDA/TDAT frames to TDRC frames, otherwise the four-digit number will be interp...

Original commit message from CVS:
* gst/id3demux/id3tags.c: (id3demux_id3v2_frames_to_tag_list):
* gst/id3demux/id3tags.h:
* gst/id3demux/id3v2frames.c: (id3demux_id3v2_parse_frame),
(parse_obsolete_tdat_frame):
Do not convert obsolete TDA/TDAT frames to TDRC frames, otherwise
the four-digit number will be interpreted as a year, whereas it is
month and day in DDMM format. Instead, parse TDAT frames and fix up
the date in the GST_TAG_DATE tag later if we also extracted a year.
Fixes #407349.
This commit is contained in:
Tim-Philipp Müller 2007-03-06 18:16:49 +00:00
parent c71db98b91
commit 8ffc1761b3
5 changed files with 57 additions and 7 deletions

View file

@ -1,3 +1,15 @@
2007-03-06 Tim-Philipp Müller <tim at centricular dot net>
* gst/id3demux/id3tags.c: (id3demux_id3v2_frames_to_tag_list):
* gst/id3demux/id3tags.h:
* gst/id3demux/id3v2frames.c: (id3demux_id3v2_parse_frame),
(parse_obsolete_tdat_frame):
Do not convert obsolete TDA/TDAT frames to TDRC frames, otherwise
the four-digit number will be interpreted as a year, whereas it is
month and day in DDMM format. Instead, parse TDAT frames and fix up
the date in the GST_TAG_DATE tag later if we also extracted a year.
Fixes #407349.
2007-03-06 Jan Schmidt <thaytan@mad.scientist.com>
* ext/gconf/gstswitchsink.c: (gst_switch_sink_dispose),

2
common

@ -1 +1 @@
Subproject commit 9a56e28fc15440eb6852411321c46312e1d1bb73
Subproject commit b333511364c0796d395b4235571db2fc9a8c1e4f

View file

@ -242,7 +242,6 @@ const struct ID3v2FrameIDConvert
} frame_id_conversions[] = {
/* 2.3.x frames */
{
"TDAT", "TDRC"}, {
"TORY", "TDOR"}, {
"TYER", "TDRC"},
/* 2.2.x frames */
@ -266,7 +265,7 @@ const struct ID3v2FrameIDConvert
"TCM", "TCOM"}, {
"TCO", "TCON"}, {
"TCR", "TCOP"}, {
"TDA", "TDRC"}, {
"TDA", "TDAT"}, { /* obsolete, but we need to parse it anyway */
"TDY", "TDLY"}, {
"TEN", "TENC"}, {
"TFT", "TFLT"}, {
@ -500,5 +499,18 @@ id3demux_id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size)
return ID3TAGS_BROKEN_TAG;
}
/* Set day/month now if they were in a separate (obsolete) TDAT frame */
if (work->pending_day != 0 && work->pending_month != 0) {
GDate *date = NULL;
if (gst_tag_list_get_date (work->tags, GST_TAG_DATE, &date)) {
g_date_set_day (date, work->pending_day);
g_date_set_month (date, work->pending_month);
gst_tag_list_add (work->tags, GST_TAG_MERGE_REPLACE, GST_TAG_DATE,
date, NULL);
g_date_free (date);
}
}
return ID3TAGS_READ_TAG;
}

View file

@ -78,6 +78,10 @@ typedef struct {
/* Previous genre string, for simple duplicate removal */
gchar *prev_genre;
/* To collect day/month from obsolete TDAT frame if it exists */
guint pending_month;
guint pending_day;
} ID3TagsWorking;
enum {

View file

@ -44,6 +44,7 @@ static gchar *parse_user_text_identification_frame (ID3TagsWorking * work,
static gchar *parse_unique_file_identifier (ID3TagsWorking * work,
const gchar ** tag_name);
static gboolean parse_relative_volume_adjustment_two (ID3TagsWorking * work);
static void parse_obsolete_tdat_frame (ID3TagsWorking * work);
static gboolean id3v2_tag_to_taglist (ID3TagsWorking * work,
const gchar * tag_name, const gchar * tag_str);
/* Parse a single string into an array of gchar* */
@ -100,6 +101,7 @@ id3demux_id3v2_parse_frame (ID3TagsWorking * work)
if (tag_name == NULL &&
strncmp (work->frame_id, "RVA2", 4) != 0 &&
strncmp (work->frame_id, "TXXX", 4) != 0 &&
strncmp (work->frame_id, "TDAT", 4) != 0 &&
strncmp (work->frame_id, "UFID", 4) != 0) {
return FALSE;
}
@ -152,12 +154,15 @@ id3demux_id3v2_parse_frame (ID3TagsWorking * work)
}
if (work->frame_id[0] == 'T') {
if (strcmp (work->frame_id, "TXXX") != 0) {
/* Text identification frame */
tag_fields = parse_text_identification_frame (work);
} else {
if (strcmp (work->frame_id, "TDAT") == 0) {
parse_obsolete_tdat_frame (work);
result = TRUE;
} else if (strcmp (work->frame_id, "TXXX") == 0) {
/* Handle user text frame */
tag_str = parse_user_text_identification_frame (work, &tag_name);
} else {
/* Text identification frame */
tag_fields = parse_text_identification_frame (work);
}
} else if (!strcmp (work->frame_id, "COMM")) {
/* Comment */
@ -635,6 +640,23 @@ parse_relative_volume_adjustment_two (ID3TagsWorking * work)
return (gain_tag_name != NULL || peak_tag_name != NULL);
}
static void
parse_obsolete_tdat_frame (ID3TagsWorking * work)
{
if (work->parse_size >= 5 &&
work->parse_data[0] == ID3V2_ENCODING_ISO8859 &&
g_ascii_isdigit (work->parse_data[1]) &&
g_ascii_isdigit (work->parse_data[2]) &&
g_ascii_isdigit (work->parse_data[3]) &&
g_ascii_isdigit (work->parse_data[4])) {
work->pending_day = (10 * g_ascii_digit_value (work->parse_data[1])) +
g_ascii_digit_value (work->parse_data[2]);
work->pending_month = (10 * g_ascii_digit_value (work->parse_data[3])) +
g_ascii_digit_value (work->parse_data[4]);
GST_LOG ("date (dd/mm) %02u/%02u", work->pending_day, work->pending_month);
}
}
static gboolean
id3v2_tag_to_taglist (ID3TagsWorking * work, const gchar * tag_name,
const gchar * tag_str)