From 8ffc1761b31c7a6c425853e16d87a907d9a4e6c7 Mon Sep 17 00:00:00 2001 From: Tim-Philipp Müller Date: Tue, 6 Mar 2007 18:16:49 +0000 Subject: 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. --- gst/id3demux/id3tags.c | 16 ++++++++++++++-- gst/id3demux/id3tags.h | 4 ++++ gst/id3demux/id3v2frames.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 6 deletions(-) (limited to 'gst/id3demux') diff --git a/gst/id3demux/id3tags.c b/gst/id3demux/id3tags.c index 7e354f2a..249acd0a 100644 --- a/gst/id3demux/id3tags.c +++ b/gst/id3demux/id3tags.c @@ -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; } diff --git a/gst/id3demux/id3tags.h b/gst/id3demux/id3tags.h index c87c8710..85a17cd4 100644 --- a/gst/id3demux/id3tags.h +++ b/gst/id3demux/id3tags.h @@ -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 { diff --git a/gst/id3demux/id3v2frames.c b/gst/id3demux/id3v2frames.c index 459a1ff3..f02f1241 100644 --- a/gst/id3demux/id3v2frames.c +++ b/gst/id3demux/id3v2frames.c @@ -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) -- cgit