1 From 6e0213e903e1afe4fc65add8f5e1595057e646a7 Mon Sep 17 00:00:00 2001
2 From: Thiago Santos <thiago.sousa.santos@collabora.co.uk>
3 Date: Tue, 19 Apr 2011 11:00:24 -0300
4 Subject: [PATCH] tag: xmp: Add support for reading struct tags
6 Adds a context variable that controls if the parsing is on
7 'top level' tags or inside a struct tag.
9 gst-libs/gst/tag/gstxmptag.c | 99 ++++++++++++++++++++++++++++++++++--------
10 1 files changed, 81 insertions(+), 18 deletions(-)
12 diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c
13 index 1a6e3c1..296804a 100644
14 --- a/gst-libs/gst/tag/gstxmptag.c
15 +++ b/gst-libs/gst/tag/gstxmptag.c
16 @@ -170,7 +170,6 @@ xmp_tag_get_type_name (XmpTag * xmptag)
20 - const gchar *gst_tag;
24 @@ -1045,11 +1044,14 @@ struct _GstXmpNamespaceMap
28 -read_one_tag (GstTagList * list, const gchar * tag, XmpTag * xmptag,
29 +read_one_tag (GstTagList * list, XmpTag * xmptag,
30 const gchar * v, GSList ** pending_tags)
33 GstTagMergeMode merge_mode;
34 + const gchar *tag = xmptag->gst_tag;
36 + g_return_if_fail (tag != NULL);
38 if (xmptag && xmptag->deserialize) {
39 xmptag->deserialize (xmptag, list, tag, xmptag->tag_name, v, pending_tags);
40 @@ -1236,10 +1238,12 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
44 - const gchar *last_tag = NULL;
45 XmpTag *last_xmp_tag = NULL;
46 GSList *pending_tags = NULL;
48 + /* Used for strucuture xmp tags */
49 + XmpTag *context_tag = NULL;
51 GstXmpNamespaceMap ns_map[] = {
54 @@ -1255,6 +1259,8 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
55 g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
56 g_return_val_if_fail (GST_BUFFER_SIZE (buffer) > 0, NULL);
58 + GST_LOG ("Starting xmp parsing");
60 xps = (const gchar *) GST_BUFFER_DATA (buffer);
61 len = GST_BUFFER_SIZE (buffer);
63 @@ -1354,19 +1360,41 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
67 - const gchar *gst_tag;
68 XmpTag *xmp_tag = NULL;
69 /* FIXME: eventualy rewrite ns
71 * check if ns before ':' is in ns_map and ns_map[i].gstreamer_ns!=NULL
72 * do 2 stage filter in tag_matches
74 - gst_tag = _gst_xmp_tag_get_mapping_reverse (as, &xmp_tag);
79 + for (iter = context_tag->children; iter;
80 + iter = g_slist_next (iter)) {
81 + XmpTag *child = iter->data;
83 + GST_DEBUG ("Looking at child tag %s : %s", child->tag_name,
85 + if (strcmp (child->tag_name, as) == 0) {
92 + GST_LOG ("Looking for tag: %s", as);
93 + _gst_xmp_tag_get_mapping_reverse (as, &xmp_tag);
98 + GST_DEBUG ("Found xmp tag: %s -> %s", xmp_tag->tag_name,
101 + /* we shouldn't find a xmp structure here */
102 + g_assert (xmp_tag->gst_tag != NULL);
104 ptag = g_slice_new (PendingXmpTag);
105 - ptag->gst_tag = gst_tag;
106 ptag->xmp_tag = xmp_tag;
107 ptag->str = g_strdup (v);
109 @@ -1393,15 +1421,42 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
111 /* skip rdf tags for now */
112 if (strncmp (part, "rdf:", 4)) {
113 - const gchar *parttag;
114 + /* if we're inside some struct, we look only on its children */
118 + /* check if this is the closing of the context */
120 + && strcmp (part + 1, context_tag->tag_name) == 0) {
121 + GST_DEBUG ("Closing context tag %s", part);
122 + context_tag = NULL;
125 + for (iter = context_tag->children; iter;
126 + iter = g_slist_next (iter)) {
127 + XmpTag *child = iter->data;
129 - parttag = _gst_xmp_tag_get_mapping_reverse (part, &last_xmp_tag);
131 - last_tag = parttag;
132 + GST_DEBUG ("Looking at child tag %s : %s", child->tag_name,
134 + if (strcmp (child->tag_name, part) == 0) {
135 + last_xmp_tag = child;
142 + GST_LOG ("Looking for tag: %s", part);
143 + _gst_xmp_tag_get_mapping_reverse (part, &last_xmp_tag);
144 + if (last_xmp_tag && last_xmp_tag->type == GstXmpTagTypeStruct) {
145 + context_tag = last_xmp_tag;
146 + last_xmp_tag = NULL;
152 + GST_LOG ("Next cycle");
156 @@ -1421,15 +1476,23 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
157 if (ns[0] != '\n' && &ns[1] <= ne) {
158 /* only log non-newline nodes, we still have to parse them */
159 GST_INFO ("txt: %s", part);
161 + if (last_xmp_tag) {
164 - ptag = g_slice_new (PendingXmpTag);
165 - ptag->gst_tag = last_tag;
166 - ptag->xmp_tag = last_xmp_tag;
167 - ptag->str = g_strdup (part);
168 + GST_DEBUG ("Found tag %s -> %s", last_xmp_tag->tag_name,
169 + last_xmp_tag->gst_tag);
171 + if (last_xmp_tag->type == GstXmpTagTypeStruct) {
172 + g_assert (context_tag == NULL); /* we can't handle struct nesting currently */
174 - pending_tags = g_slist_append (pending_tags, ptag);
175 + context_tag = last_xmp_tag;
177 + ptag = g_slice_new (PendingXmpTag);
178 + ptag->xmp_tag = last_xmp_tag;
179 + ptag->str = g_strdup (part);
181 + pending_tags = g_slist_append (pending_tags, ptag);
186 @@ -1444,7 +1507,7 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
188 pending_tags = g_slist_delete_link (pending_tags, pending_tags);
190 - read_one_tag (list, ptag->gst_tag, ptag->xmp_tag, ptag->str, &pending_tags);
191 + read_one_tag (list, ptag->xmp_tag, ptag->str, &pending_tags);
194 g_slice_free (PendingXmpTag, ptag);