struct _PendingXmpTag
{
- const gchar *gst_tag;
XmpTag *xmp_tag;
gchar *str;
};
/* parsing */
static void
-read_one_tag (GstTagList * list, const gchar * tag, XmpTag * xmptag,
+read_one_tag (GstTagList * list, XmpTag * xmptag,
const gchar * v, GSList ** pending_tags)
{
GType tag_type;
GstTagMergeMode merge_mode;
+ const gchar *tag = xmptag->gst_tag;
+
+ g_return_if_fail (tag != NULL);
if (xmptag && xmptag->deserialize) {
xmptag->deserialize (xmptag, list, tag, xmptag->tag_name, v, pending_tags);
gboolean in_tag;
gchar *part, *pp;
guint i;
- const gchar *last_tag = NULL;
XmpTag *last_xmp_tag = NULL;
GSList *pending_tags = NULL;
+ /* Used for strucuture xmp tags */
+ XmpTag *context_tag = NULL;
+
GstXmpNamespaceMap ns_map[] = {
{"dc", NULL},
{"exif", NULL},
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
g_return_val_if_fail (GST_BUFFER_SIZE (buffer) > 0, NULL);
+ GST_LOG ("Starting xmp parsing");
+
xps = (const gchar *) GST_BUFFER_DATA (buffer);
len = GST_BUFFER_SIZE (buffer);
xpe = &xps[len + 1];
}
}
} else {
- const gchar *gst_tag;
XmpTag *xmp_tag = NULL;
/* FIXME: eventualy rewrite ns
* find ':'
* check if ns before ':' is in ns_map and ns_map[i].gstreamer_ns!=NULL
* do 2 stage filter in tag_matches
*/
- gst_tag = _gst_xmp_tag_get_mapping_reverse (as, &xmp_tag);
- if (gst_tag) {
+ if (context_tag) {
+ GSList *iter;
+
+ for (iter = context_tag->children; iter;
+ iter = g_slist_next (iter)) {
+ XmpTag *child = iter->data;
+
+ GST_DEBUG ("Looking at child tag %s : %s", child->tag_name,
+ as);
+ if (strcmp (child->tag_name, as) == 0) {
+ xmp_tag = child;
+ break;
+ }
+ }
+
+ } else {
+ GST_LOG ("Looking for tag: %s", as);
+ _gst_xmp_tag_get_mapping_reverse (as, &xmp_tag);
+ }
+ if (xmp_tag) {
PendingXmpTag *ptag;
+ GST_DEBUG ("Found xmp tag: %s -> %s", xmp_tag->tag_name,
+ xmp_tag->gst_tag);
+
+ /* we shouldn't find a xmp structure here */
+ g_assert (xmp_tag->gst_tag != NULL);
+
ptag = g_slice_new (PendingXmpTag);
- ptag->gst_tag = gst_tag;
ptag->xmp_tag = xmp_tag;
ptag->str = g_strdup (v);
/* skip rdf tags for now */
if (strncmp (part, "rdf:", 4)) {
- const gchar *parttag;
+ /* if we're inside some struct, we look only on its children */
+ if (context_tag) {
+ GSList *iter;
+
+ /* check if this is the closing of the context */
+ if (part[0] == '/'
+ && strcmp (part + 1, context_tag->tag_name) == 0) {
+ GST_DEBUG ("Closing context tag %s", part);
+ context_tag = NULL;
+ } else {
+
+ for (iter = context_tag->children; iter;
+ iter = g_slist_next (iter)) {
+ XmpTag *child = iter->data;
- parttag = _gst_xmp_tag_get_mapping_reverse (part, &last_xmp_tag);
- if (parttag) {
- last_tag = parttag;
+ GST_DEBUG ("Looking at child tag %s : %s", child->tag_name,
+ part);
+ if (strcmp (child->tag_name, part) == 0) {
+ last_xmp_tag = child;
+ break;
+ }
+ }
+ }
+
+ } else {
+ GST_LOG ("Looking for tag: %s", part);
+ _gst_xmp_tag_get_mapping_reverse (part, &last_xmp_tag);
+ if (last_xmp_tag && last_xmp_tag->type == GstXmpTagTypeStruct) {
+ context_tag = last_xmp_tag;
+ last_xmp_tag = NULL;
+ }
}
}
}
}
+ GST_LOG ("Next cycle");
/* next cycle */
ne++;
if (ne < xp2) {
if (ns[0] != '\n' && &ns[1] <= ne) {
/* only log non-newline nodes, we still have to parse them */
GST_INFO ("txt: %s", part);
- if (last_tag) {
+ if (last_xmp_tag) {
PendingXmpTag *ptag;
- ptag = g_slice_new (PendingXmpTag);
- ptag->gst_tag = last_tag;
- ptag->xmp_tag = last_xmp_tag;
- ptag->str = g_strdup (part);
+ GST_DEBUG ("Found tag %s -> %s", last_xmp_tag->tag_name,
+ last_xmp_tag->gst_tag);
+
+ if (last_xmp_tag->type == GstXmpTagTypeStruct) {
+ g_assert (context_tag == NULL); /* we can't handle struct nesting currently */
- pending_tags = g_slist_append (pending_tags, ptag);
+ context_tag = last_xmp_tag;
+ } else {
+ ptag = g_slice_new (PendingXmpTag);
+ ptag->xmp_tag = last_xmp_tag;
+ ptag->str = g_strdup (part);
+
+ pending_tags = g_slist_append (pending_tags, ptag);
+ }
}
}
/* next cycle */
pending_tags = g_slist_delete_link (pending_tags, pending_tags);
- read_one_tag (list, ptag->gst_tag, ptag->xmp_tag, ptag->str, &pending_tags);
+ read_one_tag (list, ptag->xmp_tag, ptag->str, &pending_tags);
g_free (ptag->str);
g_slice_free (PendingXmpTag, ptag);