From 129c79c841a284165ee05575e43bafeecb71cc84 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 1 May 2004 17:27:23 +0000 Subject: gst/matroska/: Basic tag reading support. Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_parse_metadata): * gst/matroska/matroska-ids.h: Basic tag reading support. --- gst/matroska/matroska-demux.c | 163 +++++++++++++++++++++++++++++++++++++++++- gst/matroska/matroska-ids.h | 23 +++++- 2 files changed, 184 insertions(+), 2 deletions(-) (limited to 'gst') diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 895b8d22..3ca025cc 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -1471,6 +1471,37 @@ gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, gboolean res = TRUE; guint32 id; guint64 length = 0; + struct + { + gchar *matroska_tagname; + gchar *gstreamer_tagname; + } + tag_conv[] = + { + { + GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE} + , { + GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST} + , { + GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM} + , { + GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT} + , { + GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE} + , { + GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER} + , { + GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE} + , { + GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC} + , { + GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT} + , { + NULL, NULL} + }; + gint i; + gboolean have_tags = FALSE; + GstTagList *taglist = gst_tag_list_new (); if (prevent_eos) { length = gst_bytestream_length (ebml->bs); @@ -1492,8 +1523,122 @@ gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, } switch (id) { + case GST_MATROSKA_ID_TAG: + if (!gst_ebml_read_master (ebml, &id)) { + res = FALSE; + break; + } + + while (res) { + /* read all sub-entries */ + if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) { + res = FALSE; + break; + } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) { + res = FALSE; + break; + } else if (demux->level_up) { + demux->level_up--; + break; + } + + switch (id) { + case GST_MATROSKA_ID_SIMPLETAG:{ + gchar *tag = NULL, *value = NULL; + + if (!gst_ebml_read_master (ebml, &id)) { + res = FALSE; + break; + } + + while (res) { + /* read all sub-entries */ + if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) { + res = FALSE; + break; + } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) { + res = FALSE; + break; + } else if (demux->level_up) { + demux->level_up--; + break; + } + + switch (id) { + case GST_MATROSKA_ID_TAGNAME: + g_free (tag); + res = gst_ebml_read_ascii (ebml, &id, &tag); + break; + + case GST_MATROSKA_ID_TAGSTRING: + g_free (value); + res = gst_ebml_read_utf8 (ebml, &id, &value); + break; + + default: + GST_WARNING ("Unknown entry 0x%x in metadata collection", + id); + /* fall-through */ + + case GST_EBML_ID_VOID: + if (!gst_ebml_read_skip (ebml)) + res = FALSE; + break; + } + + if (demux->level_up) { + demux->level_up--; + break; + } + } + + if (tag && value) { + for (i = 0; tag_conv[i].matroska_tagname != NULL; i++) { + if (!strcmp (tag_conv[i].matroska_tagname, tag)) { + GValue src = { 0 } + , dest = + { + 0}; + const gchar *type = tag_conv[i].gstreamer_tagname; + GType dest_type = gst_tag_get_type (type); + + g_value_init (&src, G_TYPE_STRING); + g_value_set_string (&src, value); + g_value_init (&dest, dest_type); + g_value_transform (&src, &dest); + g_value_unset (&src); + gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND, + type, &dest, NULL); + g_value_unset (&dest); + have_tags = TRUE; + break; + } + } + } + g_free (tag); + g_free (value); + break; + } + + default: + GST_WARNING ("Unknown entry 0x%x in metadata collection", id); + /* fall-through */ + + case GST_EBML_ID_VOID: + if (!gst_ebml_read_skip (ebml)) + res = FALSE; + break; + } + + if (demux->level_up) { + demux->level_up--; + break; + } + } + break; + default: - GST_WARNING ("metadata unimplemented"); + GST_WARNING ("Unknown entry 0x%x in metadata header", id); /* fall-through */ case GST_EBML_ID_VOID: @@ -1508,6 +1653,22 @@ gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, } } + if (have_tags) { + const GList *padlist; + + /* let the world know about this wonderful thing */ + for (padlist = gst_element_get_pad_list (GST_ELEMENT (ebml)); + padlist != NULL; padlist = padlist->next) { + if (GST_PAD_IS_SRC (padlist->data) && GST_PAD_IS_USABLE (padlist->data)) { + gst_pad_push (GST_PAD (padlist->data), + GST_DATA (gst_event_new_tag (taglist))); + } + } + gst_element_found_tags (GST_ELEMENT (ebml), taglist); + } else { + gst_tag_list_free (taglist); + } + return res; } diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h index 64f25c0f..16fc475f 100644 --- a/gst/matroska/matroska-ids.h +++ b/gst/matroska/matroska-ids.h @@ -97,7 +97,14 @@ #define GST_MATROSKA_ID_CUECLUSTERPOSITION 0xF1 /* IDs in the tags master */ -/* TODO */ +#define GST_MATROSKA_ID_TAG 0x7373 + +/* in the tag master */ +#define GST_MATROSKA_ID_SIMPLETAG 0x67C8 + +/* in the simpletag master */ +#define GST_MATROSKA_ID_TAGNAME 0x45A3 +#define GST_MATROSKA_ID_TAGSTRING 0x4487 /* IDs in the seekhead master */ #define GST_MATROSKA_ID_SEEKENTRY 0x4DBB @@ -143,6 +150,20 @@ #define GST_MATROSKA_CODEC_ID_AUDIO_MPEG4 "A_AAC/MPEG4/" /* TODO: AC3-9/10 (?), Real, Musepack, Quicktime */ +/* + * Matrodka tags. Strings. + */ + +#define GST_MATROSKA_TAG_ID_TITLE "TITLE" +#define GST_MATROSKA_TAG_ID_AUTHOR "AUTHOR" +#define GST_MATROSKA_TAG_ID_ALBUM "ALBUM" +#define GST_MATROSKA_TAG_ID_COMMENTS "COMMENTS" +#define GST_MATROSKA_TAG_ID_BITSPS "BITSPS" +#define GST_MATROSKA_TAG_ID_ENCODER "ENCODER" +#define GST_MATROSKA_TAG_ID_DATE "DATE" +#define GST_MATROSKA_TAG_ID_ISRC "ISRC" +#define GST_MATROSKA_TAG_ID_COPYRIGHT "COPYRIGHT" + /* * Enumerations for various types (mapping from binary * value to what it actually means). -- cgit