From 1b29009bb3e39097e2f9af5f9e9724d4332bbfdb Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 18 Apr 2011 16:54:54 -0300 Subject: [PATCH] tag: xmp: Add struct xmp tag type support Adds support for writing the xmp struct tag type, it is a compound tag that has inner tags. --- gst-libs/gst/tag/gstxmptag.c | 357 +++++++++++++++++++---------------- 1 file changed, 195 insertions(+), 162 deletions(-) diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c index b9fee8fbd..1a6e3c128 100644 --- a/gst-libs/gst/tag/gstxmptag.c +++ b/gst-libs/gst/tag/gstxmptag.c @@ -112,14 +112,31 @@ xmp_serialization_data_use_schema (XmpSerializationData * serdata, return FALSE; } +typedef enum +{ + GstXmpTagTypeSimple = 0, + GstXmpTagTypeBag, + GstXmpTagTypeSeq, + GstXmpTagTypeStruct, + + /* Not really a xmp type, this is a tag that in gst is represented with + * a single value and on xmp it needs 2 (or more) simple values + * + * e.g. GST_TAG_GEO_LOCATION_ELEVATION needs to be mapped into 2 complementary + * tags in the exif's schema. One of them stores the absolute elevation, + * and the other one stores if it is above of below sea level. + */ + GstXmpTagTypeCompound +} GstXmpTagType; -#define GST_XMP_TAG_TYPE_SIMPLE 0 -#define GST_XMP_TAG_TYPE_BAG 1 -#define GST_XMP_TAG_TYPE_SEQ 2 struct _XmpTag { + const gchar *gst_tag; const gchar *tag_name; - gint type; + GstXmpTagType type; + + /* Used for struct and compound types */ + GSList *children; XmpSerializationFunc serialize; XmpDeserializationFunc deserialize; @@ -129,10 +146,10 @@ static GstTagMergeMode xmp_tag_get_merge_mode (XmpTag * xmptag) { switch (xmptag->type) { - case GST_XMP_TAG_TYPE_BAG: - case GST_XMP_TAG_TYPE_SEQ: + case GstXmpTagTypeBag: + case GstXmpTagTypeSeq: return GST_TAG_MERGE_APPEND; - case GST_XMP_TAG_TYPE_SIMPLE: + case GstXmpTagTypeSimple: default: return GST_TAG_MERGE_KEEP; } @@ -142,11 +159,11 @@ static const gchar * xmp_tag_get_type_name (XmpTag * xmptag) { switch (xmptag->type) { - case GST_XMP_TAG_TYPE_SEQ: + case GstXmpTagTypeSeq: return "rdf:Seq"; default: g_assert_not_reached (); - case GST_XMP_TAG_TYPE_BAG: + case GstXmpTagTypeBag: return "rdf:Bag"; } } @@ -159,14 +176,9 @@ struct _PendingXmpTag }; typedef struct _PendingXmpTag PendingXmpTag; - /* * A schema is a mapping of strings (the tag name in gstreamer) to a list of - * tags in xmp (XmpTag). We need a list because some tags are split into 2 - * when serialized into xmp. - * e.g. GST_TAG_GEO_LOCATION_ELEVATION needs to be mapped into 2 complementary - * tags in the exif's schema. One of them stores the absolute elevation, - * and the other one stores if it is above of below sea level. + * tags in xmp (XmpTag). */ typedef GHashTable GstXmpSchema; #define gst_xmp_schema_lookup g_hash_table_lookup @@ -214,40 +226,70 @@ _gst_xmp_add_schema (const gchar * name, GstXmpSchema * schema) } static void -_gst_xmp_schema_add_mapping (GstXmpSchema * schema, const gchar * gst_tag, - GPtrArray * array) +_gst_xmp_schema_add_mapping (GstXmpSchema * schema, XmpTag * tag) { GQuark key; - key = g_quark_from_string (gst_tag); + key = g_quark_from_string (tag->gst_tag); if (gst_xmp_schema_lookup (schema, GUINT_TO_POINTER (key))) { - GST_WARNING ("Tag %s already present for the schema", gst_tag); + GST_WARNING ("Tag %s already present for the schema", tag->gst_tag); g_assert_not_reached (); return; } - gst_xmp_schema_insert (schema, GUINT_TO_POINTER (key), array); + gst_xmp_schema_insert (schema, GUINT_TO_POINTER (key), tag); } -static void -_gst_xmp_schema_add_simple_mapping (GstXmpSchema * schema, - const gchar * gst_tag, const gchar * xmp_tag, gint xmp_type, - XmpSerializationFunc serialization_func, +static XmpTag * +gst_xmp_tag_create (const gchar * gst_tag, const gchar * xmp_tag, + gint xmp_type, XmpSerializationFunc serialization_func, XmpDeserializationFunc deserialization_func) { XmpTag *xmpinfo; - GPtrArray *array; xmpinfo = g_slice_new (XmpTag); + xmpinfo->gst_tag = gst_tag; xmpinfo->tag_name = xmp_tag; xmpinfo->type = xmp_type; xmpinfo->serialize = serialization_func; xmpinfo->deserialize = deserialization_func; + xmpinfo->children = NULL; - array = g_ptr_array_sized_new (1); - g_ptr_array_add (array, xmpinfo); + return xmpinfo; +} - _gst_xmp_schema_add_mapping (schema, gst_tag, array); +static XmpTag * +gst_xmp_tag_create_compound (const gchar * gst_tag, const gchar * xmp_tag_a, + const gchar * xmp_tag_b, XmpSerializationFunc serialization_func_a, + XmpSerializationFunc serialization_func_b, + XmpDeserializationFunc deserialization_func) +{ + XmpTag *xmptag; + XmpTag *xmptag_a = + gst_xmp_tag_create (gst_tag, xmp_tag_a, GstXmpTagTypeSimple, + serialization_func_a, deserialization_func); + XmpTag *xmptag_b = + gst_xmp_tag_create (gst_tag, xmp_tag_b, GstXmpTagTypeSimple, + serialization_func_b, deserialization_func); + + xmptag = + gst_xmp_tag_create (gst_tag, NULL, GstXmpTagTypeCompound, NULL, NULL); + + xmptag->children = g_slist_prepend (xmptag->children, xmptag_b); + xmptag->children = g_slist_prepend (xmptag->children, xmptag_a); + + return xmptag; +} + +static void +_gst_xmp_schema_add_simple_mapping (GstXmpSchema * schema, + const gchar * gst_tag, const gchar * xmp_tag, gint xmp_type, + XmpSerializationFunc serialization_func, + XmpDeserializationFunc deserialization_func) +{ + _gst_xmp_schema_add_mapping (schema, + gst_xmp_tag_create (gst_tag, xmp_tag, xmp_type, serialization_func, + deserialization_func)); } /* @@ -286,22 +328,30 @@ _gst_xmp_schema_get_mapping_reverse (GstXmpSchema * schema, GHashTableIter iter; gpointer key, value; const gchar *ret = NULL; - gint index; /* Iterate over the hashtable */ g_hash_table_iter_init (&iter, schema); while (!ret && g_hash_table_iter_next (&iter, &key, &value)) { - GPtrArray *array = (GPtrArray *) value; - - /* each mapping might contain complementary tags */ - for (index = 0; index < array->len; index++) { - XmpTag *xmpinfo = (XmpTag *) g_ptr_array_index (array, index); + XmpTag *xmpinfo = (XmpTag *) value; + if (xmpinfo->tag_name) { if (strcmp (xmpinfo->tag_name, xmp_tag) == 0) { *_xmp_tag = xmpinfo; ret = g_quark_to_string (GPOINTER_TO_UINT (key)); goto out; } + } else if (xmpinfo->children) { + GSList *iter; + for (iter = xmpinfo->children; iter; iter = g_slist_next (iter)) { + XmpTag *child = iter->data; + if (strcmp (child->tag_name, xmp_tag) == 0) { + *_xmp_tag = child; + ret = g_quark_to_string (GPOINTER_TO_UINT (key)); + goto out; + } + } + } else { + g_assert_not_reached (); } } @@ -856,7 +906,6 @@ deserialize_tiff_orientation (XmpTag * xmptag, GstTagList * taglist, static gpointer _init_xmp_tag_map (gpointer user_data) { - GPtrArray *array; XmpTag *xmpinfo; GstXmpSchema *schema; @@ -868,136 +917,95 @@ _init_xmp_tag_map (gpointer user_data) */ schema = gst_xmp_schema_new (); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_ARTIST, - "dc:creator", GST_XMP_TAG_TYPE_SEQ, NULL, NULL); + "dc:creator", GstXmpTagTypeSeq, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_COPYRIGHT, - "dc:rights", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "dc:rights", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DATE, "dc:date", - GST_XMP_TAG_TYPE_SEQ, NULL, NULL); + GstXmpTagTypeSeq, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DESCRIPTION, - "dc:description", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "dc:description", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_KEYWORDS, - "dc:subject", GST_XMP_TAG_TYPE_BAG, NULL, NULL); + "dc:subject", GstXmpTagTypeBag, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_TITLE, "dc:title", - GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + GstXmpTagTypeSimple, NULL, NULL); /* FIXME: we probably want GST_TAG_{,AUDIO_,VIDEO_}MIME_TYPE */ _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_VIDEO_CODEC, - "dc:format", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "dc:format", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_add_schema ("dc", schema); /* xap (xmp) schema */ schema = gst_xmp_schema_new (); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_USER_RATING, - "xmp:Rating", GST_XMP_TAG_TYPE_SIMPLE, NULL, deserialize_xmp_rating); + "xmp:Rating", GstXmpTagTypeSimple, NULL, deserialize_xmp_rating); _gst_xmp_add_schema ("xap", schema); /* tiff */ schema = gst_xmp_schema_new (); _gst_xmp_schema_add_simple_mapping (schema, - GST_TAG_DEVICE_MANUFACTURER, "tiff:Make", GST_XMP_TAG_TYPE_SIMPLE, NULL, + GST_TAG_DEVICE_MANUFACTURER, "tiff:Make", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DEVICE_MODEL, - "tiff:Model", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "tiff:Model", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_APPLICATION_NAME, - "tiff:Software", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "tiff:Software", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_IMAGE_ORIENTATION, - "tiff:Orientation", GST_XMP_TAG_TYPE_SIMPLE, serialize_tiff_orientation, + "tiff:Orientation", GstXmpTagTypeSimple, serialize_tiff_orientation, deserialize_tiff_orientation); _gst_xmp_add_schema ("tiff", schema); /* exif schema */ schema = gst_xmp_schema_new (); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DATE_TIME, - "exif:DateTimeOriginal", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "exif:DateTimeOriginal", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_LATITUDE, "exif:GPSLatitude", - GST_XMP_TAG_TYPE_SIMPLE, serialize_exif_latitude, - deserialize_exif_latitude); + GstXmpTagTypeSimple, serialize_exif_latitude, deserialize_exif_latitude); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_LONGITUDE, - "exif:GPSLongitude", GST_XMP_TAG_TYPE_SIMPLE, serialize_exif_longitude, + "exif:GPSLongitude", GstXmpTagTypeSimple, serialize_exif_longitude, deserialize_exif_longitude); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, "exif:ExposureBiasValue", - GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + GstXmpTagTypeSimple, NULL, NULL); /* compound exif tags */ - array = g_ptr_array_sized_new (2); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSAltitude"; - xmpinfo->serialize = serialize_exif_altitude; - xmpinfo->deserialize = deserialize_exif_altitude; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSAltitudeRef"; - xmpinfo->serialize = serialize_exif_altituderef; - xmpinfo->deserialize = deserialize_exif_altitude; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - _gst_xmp_schema_add_mapping (schema, GST_TAG_GEO_LOCATION_ELEVATION, array); - - array = g_ptr_array_sized_new (2); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSSpeed"; - xmpinfo->serialize = serialize_exif_gps_speed; - xmpinfo->deserialize = deserialize_exif_gps_speed; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSSpeedRef"; - xmpinfo->serialize = serialize_exif_gps_speedref; - xmpinfo->deserialize = deserialize_exif_gps_speed; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - _gst_xmp_schema_add_mapping (schema, - GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, array); - - array = g_ptr_array_sized_new (2); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSTrack"; - xmpinfo->serialize = serialize_exif_gps_direction; - xmpinfo->deserialize = deserialize_exif_gps_track; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSTrackRef"; - xmpinfo->serialize = serialize_exif_gps_directionref; - xmpinfo->deserialize = deserialize_exif_gps_track; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - _gst_xmp_schema_add_mapping (schema, - GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, array); + xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_ELEVATION, + "exif:GPSAltitude", "exif:GPSAltitudeRef", serialize_exif_altitude, + serialize_exif_altituderef, deserialize_exif_altitude); + _gst_xmp_schema_add_mapping (schema, xmpinfo); + + xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, + "exif:GPSSpeed", "exif:GPSSpeedRef", serialize_exif_gps_speed, + serialize_exif_gps_speedref, deserialize_exif_gps_speed); + _gst_xmp_schema_add_mapping (schema, xmpinfo); + + xmpinfo = + gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, + "exif:GPSTrack", "exif:GPSTrackRef", serialize_exif_gps_direction, + serialize_exif_gps_directionref, deserialize_exif_gps_track); + _gst_xmp_schema_add_mapping (schema, xmpinfo); + + xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, + "exif:GPSImgDirection", "exif:GPSImgDirectionRef", + serialize_exif_gps_direction, serialize_exif_gps_directionref, + deserialize_exif_gps_img_direction); + _gst_xmp_schema_add_mapping (schema, xmpinfo); - array = g_ptr_array_sized_new (2); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSImgDirection"; - xmpinfo->serialize = serialize_exif_gps_direction; - xmpinfo->deserialize = deserialize_exif_gps_img_direction; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - xmpinfo = g_slice_new (XmpTag); - xmpinfo->tag_name = "exif:GPSImgDirectionRef"; - xmpinfo->serialize = serialize_exif_gps_directionref; - xmpinfo->deserialize = deserialize_exif_gps_img_direction; - xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE; - g_ptr_array_add (array, xmpinfo); - _gst_xmp_schema_add_mapping (schema, - GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, array); _gst_xmp_add_schema ("exif", schema); /* photoshop schema */ schema = gst_xmp_schema_new (); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_COUNTRY, "photoshop:Country", - GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_CITY, - "photoshop:City", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + "photoshop:City", GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_add_schema ("photoshop", schema); /* iptc4xmpcore schema */ schema = gst_xmp_schema_new (); _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_SUBLOCATION, "Iptc4xmpCore:Location", - GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL); + GstXmpTagTypeSimple, NULL, NULL); _gst_xmp_add_schema ("Iptc4xmpCore", schema); return NULL; @@ -1540,62 +1548,93 @@ gst_value_serialize_xmp (const GValue * value) } static void -write_one_tag (const GstTagList * list, const gchar * tag, - GPtrArray * xmp_tag_array, gpointer user_data) +write_one_tag (const GstTagList * list, XmpTag * xmp_tag, gpointer user_data) { - guint i = 0, ct = gst_tag_list_get_tag_size (list, tag), tag_index; + guint i = 0, ct; XmpSerializationData *serialization_data = user_data; GString *data = serialization_data->data; char *s; - for (tag_index = 0; tag_index < xmp_tag_array->len; tag_index++) { - XmpTag *xmp_tag; + /* struct type handled differently */ + if (xmp_tag->type == GstXmpTagTypeStruct || + xmp_tag->type == GstXmpTagTypeCompound) { + GSList *iter; + gboolean use_it = FALSE; + + /* check if any of the inner tags are present on the taglist */ + for (iter = xmp_tag->children; iter && !use_it; iter = g_slist_next (iter)) { + XmpTag *child_tag = iter->data; - xmp_tag = g_ptr_array_index (xmp_tag_array, tag_index); - string_open_tag (data, xmp_tag->tag_name); + if (gst_tag_list_get_value_index (list, child_tag->gst_tag, 0) != NULL) { + use_it = TRUE; + break; + } + } - /* fast path for single valued tag */ - if (ct == 1 || xmp_tag->type == GST_XMP_TAG_TYPE_SIMPLE) { + if (use_it) { + if (xmp_tag->tag_name) + string_open_tag (data, xmp_tag->tag_name); + /* now write it */ + for (iter = xmp_tag->children; iter; iter = g_slist_next (iter)) { + write_one_tag (list, iter->data, user_data); + } + if (xmp_tag->tag_name) + string_close_tag (data, xmp_tag->tag_name); + } + return; + } + + /* at this point we must have a gst_tag */ + g_assert (xmp_tag->gst_tag); + if (gst_tag_list_get_value_index (list, xmp_tag->gst_tag, 0) == NULL) + return; + + ct = gst_tag_list_get_tag_size (list, xmp_tag->gst_tag); + string_open_tag (data, xmp_tag->tag_name); + + /* fast path for single valued tag */ + if (ct == 1 || xmp_tag->type == GstXmpTagTypeSimple) { + if (xmp_tag->serialize) { + s = xmp_tag->serialize (gst_tag_list_get_value_index (list, + xmp_tag->gst_tag, 0)); + } else { + s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, + xmp_tag->gst_tag, 0)); + } + if (s) { + g_string_append (data, s); + g_free (s); + } else { + GST_WARNING ("unhandled type for %s to xmp", xmp_tag->gst_tag); + } + } else { + const gchar *typename; + + typename = xmp_tag_get_type_name (xmp_tag); + + string_open_tag (data, typename); + for (i = 0; i < ct; i++) { + GST_DEBUG ("mapping %s[%u/%u] to xmp", xmp_tag->gst_tag, i, ct); if (xmp_tag->serialize) { - s = xmp_tag->serialize (gst_tag_list_get_value_index (list, tag, 0)); + s = xmp_tag->serialize (gst_tag_list_get_value_index (list, + xmp_tag->gst_tag, i)); } else { - s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, tag, - 0)); + s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, + xmp_tag->gst_tag, i)); } if (s) { + string_open_tag (data, "rdf:li"); g_string_append (data, s); + string_close_tag (data, "rdf:li"); g_free (s); } else { - GST_WARNING ("unhandled type for %s to xmp", tag); - } - } else { - const gchar *typename; - - typename = xmp_tag_get_type_name (xmp_tag); - - string_open_tag (data, typename); - for (i = 0; i < ct; i++) { - GST_DEBUG ("mapping %s[%u/%u] to xmp", tag, i, ct); - if (xmp_tag->serialize) { - s = xmp_tag->serialize (gst_tag_list_get_value_index (list, tag, i)); - } else { - s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, tag, - i)); - } - if (s) { - string_open_tag (data, "rdf:li"); - g_string_append (data, s); - string_close_tag (data, "rdf:li"); - g_free (s); - } else { - GST_WARNING ("unhandled type for %s to xmp", tag); - } + GST_WARNING ("unhandled type for %s to xmp", xmp_tag->gst_tag); } - string_close_tag (data, typename); } - - string_close_tag (data, xmp_tag->tag_name); + string_close_tag (data, typename); } + + string_close_tag (data, xmp_tag->tag_name); } /** @@ -1652,7 +1691,6 @@ gst_tag_list_to_xmp_buffer_full (const GstTagList * list, gboolean read_only, /* use all schemas */ schemas = gst_tag_xmp_list_schemas (); } - i = 0; for (i = 0; schemas[i] != NULL; i++) { GstXmpSchema *schema = _gst_xmp_get_schema (schemas[i]); GHashTableIter iter; @@ -1664,12 +1702,7 @@ gst_tag_list_to_xmp_buffer_full (const GstTagList * list, gboolean read_only, /* Iterate over the hashtable */ g_hash_table_iter_init (&iter, schema); while (g_hash_table_iter_next (&iter, &key, &value)) { - const gchar *tag = g_quark_to_string (GPOINTER_TO_UINT (key)); - - if (gst_tag_list_get_value_index (list, tag, 0) != NULL) { - write_one_tag (list, tag, value, (gpointer) & serialization_data); - } - + write_one_tag (list, value, (gpointer) & serialization_data); } } -- 2.34.1