void TagExtractor::printOneTag( const GstTagList * list, const gchar * tag, gpointer user_data ) { int i, num; num = gst_tag_list_get_tag_size( list, tag ); for (i = 0; i < num; ++i) { const GValue *val; /* Note: when looking for specific tags, use the gst_tag_list_get_xyz() API, * we only use the GValue approach here because it is more generic */ val = gst_tag_list_get_value_index( list, tag, i ); if( G_VALUE_HOLDS_STRING (val)) { g_print( "\t%20s : %s\n", tag, g_value_get_string( val ) ); } else if( G_VALUE_HOLDS_UINT (val)) { g_print( "\t%20s : %u\n", tag, g_value_get_uint( val ) ); } else if( G_VALUE_HOLDS_DOUBLE (val)) { g_print( "\t%20s : %g\n", tag, g_value_get_double( val ) ); } else if( G_VALUE_HOLDS_BOOLEAN (val)) { g_print( "\t%20s : %s\n", tag, (g_value_get_boolean( val )) ? "true" : "false" ); } else if( GST_VALUE_HOLDS_BUFFER (val)) { GstBuffer *buf = gst_value_get_buffer (val); guint buffer_size = gst_buffer_get_size( buf ); g_print( "\t%20s : buffer of size %u\n", tag, buffer_size ); } else if( GST_VALUE_HOLDS_DATE_TIME (val)) { GstDateTime *dt = (GstDateTime*) g_value_get_boxed( val ); gchar *dt_str = gst_date_time_to_iso8601_string( dt ); g_print( "\t%20s : %s\n", tag, dt_str ); g_free( dt_str ); } else { g_print( "\t%20s : tag of type '%s'\n", tag, G_VALUE_TYPE_NAME (val)); } } }
static void write_exif_ascii_tag_from_taglist (GstExifWriter * writer, const GstTagList * taglist, const GstExifTagMatch * exiftag) { gchar *str = NULL; gboolean cleanup = FALSE; const GValue *value; gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag); if (tag_size != 1) { /* FIXME support this by serializing them with a ','? */ GST_WARNING ("Multiple string tags not supported yet"); return; } value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0); /* do some conversion if needed */ switch (G_VALUE_TYPE (value)) { case G_TYPE_STRING: str = (gchar *) g_value_get_string (value); break; default: GST_WARNING ("Conversion from %s to ascii string not supported", G_VALUE_TYPE_NAME (value)); break; } if (str == NULL) return; write_exif_ascii_tag (writer, exiftag->exif_tag, str); if (cleanup) g_free (str); }
static void bbd_pipeline_process_tag (const GstTagList *tag_list, const gchar *tag_name, BansheeBpmDetector *detector) { const GValue *value; gint value_count; double bpm; g_return_if_fail (detector != NULL); if (detector->progress_cb == NULL) { return; } if (strcmp (tag_name, GST_TAG_BEATS_PER_MINUTE)) { return; } value_count = gst_tag_list_get_tag_size (tag_list, tag_name); if (value_count < 1) { return; } value = gst_tag_list_get_value_index (tag_list, tag_name, 0); if (value != NULL && G_VALUE_HOLDS_DOUBLE (value)) { bpm = g_value_get_double (value); detector->progress_cb (bpm); } }
static void print_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) { gint i, num; num = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < num; ++i) { const GValue *val; val = gst_tag_list_get_value_index (list, tag, i); if (G_VALUE_HOLDS_STRING (val)) { g_print (" %s : %s \n", tag, g_value_get_string (val)); } else if (G_VALUE_HOLDS_UINT (val)) { g_print (" %s : %u \n", tag, g_value_get_uint (val)); } else if (G_VALUE_HOLDS_DOUBLE (val)) { g_print (" %s : %g \n", tag, g_value_get_double (val)); } else if (G_VALUE_HOLDS_BOOLEAN (val)) { g_print (" %s : %s \n", tag, g_value_get_boolean (val) ? "true" : "false"); } else if (GST_VALUE_HOLDS_DATE_TIME (val)) { GstDateTime *dt = g_value_get_boxed (val); gchar *dt_str = gst_date_time_to_iso8601_string (dt); g_print (" %s : %s \n", tag, dt_str); g_free (dt_str); } else { g_print (" %s : tag of type '%s' \n", tag, G_VALUE_TYPE_NAME (val)); } } }
CAMLprim value ocaml_gstreamer_message_parse_tag(value _msg) { CAMLparam1(_msg); CAMLlocal4(v,s,t,ans); GstMessage *msg = Message_val(_msg); GstTagList *tags = NULL; const GValue *val; const gchar *tag; int taglen; int i, j, n; caml_release_runtime_system(); gst_message_parse_tag(msg, &tags); taglen = gst_tag_list_n_tags(tags); caml_acquire_runtime_system(); ans = caml_alloc_tuple(taglen); for(i = 0; i < taglen; i++) { t = caml_alloc_tuple(2); // Tag name tag = gst_tag_list_nth_tag_name(tags, i); Store_field(t, 0, caml_copy_string(tag)); // Tag fields n = gst_tag_list_get_tag_size(tags, tag); v = caml_alloc_tuple(n); for (j = 0; j < n; j++) { val = gst_tag_list_get_value_index(tags, tag, j); if (G_VALUE_HOLDS_STRING(val)) { s = caml_copy_string(g_value_get_string(val)); } else if (GST_VALUE_HOLDS_DATE_TIME(val)) { GstDateTime *dt = g_value_get_boxed(val); gchar *dt_str = gst_date_time_to_iso8601_string(dt); s = caml_copy_string(dt_str); g_free(dt_str); } else { //TODO: better typed handling of non-string values? char *vc = g_strdup_value_contents(val); s = caml_copy_string(vc); free(vc); } Store_field(v, j, s); } Store_field(t, 1, v); Store_field(ans, i, t); } gst_tag_list_unref(tags); CAMLreturn(ans); }
static void tag_list_foreach (const GstTagList * taglist, const gchar * tag, guint * p_num) { guint tag_size; tag_size = gst_tag_list_get_tag_size (taglist, tag); GST_LOG ("%u+%u tag = %s", *p_num, tag_size, tag); *p_num += tag_size; }
/** * rb_gst_process_tag_string: * @taglist: a #GstTagList containing a string tag * @tag: tag name * @field: returns the #RBMetaDataField corresponding to the tag * @value: returns the tag value * * Processes a tag string, determining the metadata field identifier * corresponding to the tag name, and converting the tag data into the * appropriate value type. * * Return value: %TRUE if the tag was successfully converted. */ gboolean rb_gst_process_tag_string (const GstTagList *taglist, const char *tag, RBMetaDataField *field, GValue *value) { const GValue *tagval; if (gst_tag_list_get_tag_size (taglist, tag) < 0) { rb_debug ("no values in taglist for tag %s", tag); return FALSE; } /* only handle a few fields here */ if (!strcmp (tag, GST_TAG_TITLE)) *field = RB_METADATA_FIELD_TITLE; else if (!strcmp (tag, GST_TAG_GENRE)) *field = RB_METADATA_FIELD_GENRE; else if (!strcmp (tag, GST_TAG_COMMENT)) *field = RB_METADATA_FIELD_COMMENT; else if (!strcmp (tag, GST_TAG_BITRATE)) *field = RB_METADATA_FIELD_BITRATE; else if (!strcmp (tag, GST_TAG_MUSICBRAINZ_TRACKID)) *field = RB_METADATA_FIELD_MUSICBRAINZ_TRACKID; else { rb_debug ("tag %s doesn't correspond to a metadata field we're interested in", tag); return FALSE; } /* most of the fields we care about are strings */ switch (*field) { case RB_METADATA_FIELD_BITRATE: g_value_init (value, G_TYPE_ULONG); break; case RB_METADATA_FIELD_TITLE: case RB_METADATA_FIELD_GENRE: case RB_METADATA_FIELD_COMMENT: case RB_METADATA_FIELD_MUSICBRAINZ_TRACKID: default: g_value_init (value, G_TYPE_STRING); break; } tagval = gst_tag_list_get_value_index (taglist, tag, 0); if (!g_value_transform (tagval, value)) { rb_debug ("Could not transform tag value type %s into %s", g_type_name (G_VALUE_TYPE (tagval)), g_type_name (G_VALUE_TYPE (value))); g_value_unset (value); return FALSE; } return TRUE; }
void TagExtractor::parseOneTag( const GstTagList * list, const gchar * tag, gpointer user_data ) { int i, num; num = gst_tag_list_get_tag_size( list, tag ); for (i = 0; i < num; ++i) { const GValue *val; val = gst_tag_list_get_value_index( list, tag, i ); if( g_strcmp0( tag, "artist" ) == 0 ) { g_print( " artist: %s", g_value_get_string( val ) ); } } }
static void print_tag (const GstTagList * list, const gchar * tag, gpointer unused) { gint i, count; count = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < count; i++) { gchar *str; if (gst_tag_get_type (tag) == G_TYPE_STRING) { if (!gst_tag_list_get_string_index (list, tag, i, &str)) g_assert_not_reached (); } else if (gst_tag_get_type (tag) == GST_TYPE_BUFFER) { GstBuffer *img; img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i)); if (img) { gchar *caps_str; caps_str = GST_BUFFER_CAPS (img) ? gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown"); str = g_strdup_printf ("buffer of %u bytes, type: %s", GST_BUFFER_SIZE (img), caps_str); g_free (caps_str); } else { str = g_strdup ("NULL buffer"); } } else { str = g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i)); } if (i == 0) { g_print ("%16s: %s\n", gst_tag_get_nick (tag), str); } else { g_print ("%16s: %s\n", "", str); } g_free (str); } }
/* checks that a tag contains the given values and not more values */ static void check_tags (const GstTagList * list, const gchar * tag, const gchar * value, ...) { va_list args; gchar *str; guint i = 0; va_start (args, value); while (value != NULL) { fail_unless (gst_tag_list_get_string_index (list, tag, i, &str)); fail_unless (strcmp (value, str) == 0); g_free (str); value = va_arg (args, gchar *); i++; } fail_unless (i == gst_tag_list_get_tag_size (list, tag)); va_end (args); }
static void print_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) { int i, num; num = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < num; ++i) { const GValue *val; /* Note: when looking for specific tags, use the g_tag_list_get_xyz() API, * we only use the GValue approach here because it is more generic */ val = gst_tag_list_get_value_index (list, tag, i); if (G_VALUE_HOLDS_STRING (val)) { const char* unformatted = g_value_get_string (val); gchar* formatted = strescape(unformatted,"\"","\""); g_print ("(%s . \"%s\")\n", tag, formatted); g_free(formatted); } else if (G_VALUE_HOLDS_UINT (val)) { unsigned int uint = g_value_get_uint (val); if(uint > 0xf) g_print ("(%s . #x%x)\n", tag, uint); } else if (G_VALUE_HOLDS_DOUBLE (val)) { g_print ("(%s . %g)\n", tag, g_value_get_double (val)); } else if (G_VALUE_HOLDS_BOOLEAN (val)) { g_print ("(%s . %s)\n", tag, (g_value_get_boolean (val)) ? "#t" : "#f"); } else if (GST_VALUE_HOLDS_BUFFER (val)) { g_print ("(%s . (buffer %u))", tag, gst_buffer_get_size(gst_value_get_buffer (val))); } else if (GST_VALUE_HOLDS_DATE_TIME (val)) { GDate* date = (GDate*)g_value_get_boxed(val); g_print ("(%s . (date 0 0 0 %u %u %u))\n", tag, g_date_get_day(date), g_date_get_month(date), g_date_get_year (date)); } else { g_print ("(%20s . (type %s))", tag, G_VALUE_TYPE_NAME (val)); } } }
static void send_tag (const GstTagList * list, const gchar * tag, gpointer data) { InsanityGstPipelineTest *ptest = INSANITY_GST_PIPELINE_TEST (data); gint i, count; GValue string_value = { 0 }; char label[48]; count = gst_tag_list_get_tag_size (list, tag); g_value_init (&string_value, G_TYPE_STRING); ptest->priv->tag_count++; for (i = 0; i < count; i++) { gchar *str; if (gst_tag_get_type (tag) == G_TYPE_STRING) { if (!gst_tag_list_get_string_index (list, tag, i, &str)) g_assert_not_reached (); } else if (gst_tag_get_type (tag) == GST_TYPE_SAMPLE) { GstSample *img; img = gst_value_get_sample (gst_tag_list_get_value_index (list, tag, i)); if (img) { GstBuffer *buffer; GstCaps *caps; gchar *caps_str; buffer = gst_sample_get_buffer (img); caps = gst_sample_get_caps (img); caps_str = caps ? gst_caps_to_string (caps) : g_strdup ("unknown"); str = g_strdup_printf ("sample of %" G_GSIZE_FORMAT " bytes, type: %s", gst_buffer_get_size (buffer), caps_str); g_free (caps_str); } else { str = g_strdup ("NULL sample"); } } else if (gst_tag_get_type (tag) == GST_TYPE_DATE_TIME) { GstDateTime *dt = NULL; gst_tag_list_get_date_time_index (list, tag, i, &dt); str = gst_date_time_to_iso8601_string (dt); gst_date_time_unref (dt); } else { str = g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i)); } if (i == 0) { g_value_set_string (&string_value, gst_tag_get_nick (tag)); snprintf (label, sizeof (label), "tags.%u.id", ptest->priv->tag_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); } g_value_set_string (&string_value, str); if (count > 1) snprintf (label, sizeof (label), "tags.%u.value.%u", ptest->priv->tag_count, i); else snprintf (label, sizeof (label), "tags.%u.value", ptest->priv->tag_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); g_free (str); } }
guint get_num_values_for_tag(tag_list const &p_tag_list, std::string const &p_name) { g_assert(!p_name.empty()); return p_tag_list.is_empty() ? 0 : gst_tag_list_get_tag_size(p_tag_list.get_tag_list(), p_name.c_str()); }
static void write_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) { guint i = 0, ct = gst_tag_list_get_tag_size (list, tag), tag_index; GString *data = user_data; GPtrArray *xmp_tag_array = NULL; char *s; GSList *xmptaglist; /* map gst-tag to xmp tag */ xmptaglist = _xmp_tag_get_mapping (tag); if (xmptaglist) { /* FIXME - we are always chosing the first tag mapped on the list */ xmp_tag_array = (GPtrArray *) xmptaglist->data; } if (!xmp_tag_array) { GST_WARNING ("no mapping for %s to xmp", tag); return; } for (tag_index = 0; tag_index < xmp_tag_array->len; tag_index++) { XmpTag *xmp_tag; xmp_tag = g_ptr_array_index (xmp_tag_array, tag_index); string_open_tag (data, xmp_tag->tag_name); /* fast path for single valued tag */ if (ct == 1) { if (xmp_tag->serialize) { s = xmp_tag->serialize (gst_tag_list_get_value_index (list, tag, 0)); } else { s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, tag, 0)); } if (s) { g_string_append (data, s); g_free (s); } else { GST_WARNING ("unhandled type for %s to xmp", tag); } } else { string_open_tag (data, "rdf:Bag"); 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); } } string_close_tag (data, "rdf:Bag"); } string_close_tag (data, xmp_tag->tag_name); } }
// ---------------------------------------------------------------------------- // Handle the "tag" message void GStreamerImportFileHandle::OnTag(GstAppSink * WXUNUSED(appsink), GstTagList *tags) { // Collect all of the associates tags for (guint i = 0, icnt = gst_tag_list_n_tags(tags); i < icnt; i++) { wxString string; // Get tag name...should always succeed...no need to release const gchar *name = gst_tag_list_nth_tag_name(tags, i); if (!name) { continue; } // For each tag, determine its type and retrieve if possible for (guint j = 0, jcnt = gst_tag_list_get_tag_size(tags, name); j < jcnt; j++) { const GValue *val; val = gst_tag_list_get_value_index(tags, name, j); if (G_VALUE_HOLDS_STRING(val)) { string = wxString::FromUTF8(g_value_get_string(val)); } else if (G_VALUE_HOLDS_UINT(val)) { string.Printf(wxT("%u"), (unsigned int) g_value_get_uint(val)); } else if (G_VALUE_HOLDS_DOUBLE(val)) { string.Printf(wxT("%g"), g_value_get_double(val)); } else if (G_VALUE_HOLDS_BOOLEAN(val)) { string = g_value_get_boolean(val) ? wxT("true") : wxT("false"); } else if (GST_VALUE_HOLDS_DATE_TIME(val)) { GstDateTime *dt = (GstDateTime *) g_value_get_boxed(val); gchar *str = gst_date_time_to_iso8601_string(dt); string = wxString::FromUTF8(str).c_str(); g_free(str); } else if (G_VALUE_HOLDS(val, G_TYPE_DATE)) { gchar *str = gst_value_serialize(val); string = wxString::FromUTF8(str).c_str(); g_free(str); } else { wxLogMessage(wxT("Tag %s has unhandled type: %s"), wxString::FromUTF8(name).c_str(), wxString::FromUTF8(G_VALUE_TYPE_NAME(val)).c_str()); continue; } // Translate known tag names wxString tag; if (strcmp(name, GST_TAG_TITLE) == 0) { tag = TAG_TITLE; } else if (strcmp(name, GST_TAG_ARTIST) == 0) { tag = TAG_ARTIST; } else if (strcmp(name, GST_TAG_ALBUM) == 0) { tag = TAG_ALBUM; } else if (strcmp(name, GST_TAG_TRACK_NUMBER) == 0) { tag = TAG_TRACK; } else if (strcmp(name, GST_TAG_DATE) == 0) { tag = TAG_YEAR; } else if (strcmp(name, GST_TAG_GENRE) == 0) { tag = TAG_GENRE; } else if (strcmp(name, GST_TAG_COMMENT) == 0) { tag = TAG_COMMENTS; } else { tag = wxString::FromUTF8(name).c_str(); } if (jcnt > 1) { tag.Printf(wxT("%s:%d"), tag.c_str(), j); } // Store the tag mTags.SetTag(tag, string); } } }
static void rc_tag_get_tag(const GstTagList *tags, RCMusicMetaData *mmd) { gchar *tag_title = NULL; gchar *tag_artist = NULL; gchar *tag_filetype = NULL; gchar *tag_album = NULL; gchar *tag_comment = NULL; gchar *tag_cuelist = NULL; GstBuffer *tag_image = NULL; guint bitrates = 0; guint tracknum = 0; guint tag_cue_num = 0; guint i = 0; if(mmd==NULL || mmd->uri==NULL || tags==NULL) return; if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &tag_filetype)) { if(tag_filetype!=NULL) { if(mmd->file_type!=NULL) g_free(mmd->file_type); mmd->file_type = g_strdup(tag_filetype); g_free(tag_filetype); } } if(gst_tag_list_get_string(tags, GST_TAG_TITLE, &tag_title)) { if(tag_title!=NULL) { if(mmd->title!=NULL) g_free(mmd->title); mmd->title = g_strdup(tag_title); g_free(tag_title); } } if(gst_tag_list_get_string(tags, GST_TAG_ARTIST, &tag_artist)) { if(tag_artist!=NULL) { if(mmd->artist!=NULL) g_free(mmd->artist); mmd->artist = g_strdup(tag_artist); g_free(tag_artist); } } if(gst_tag_list_get_string(tags, GST_TAG_ALBUM, &tag_album)) { if(tag_album!=NULL) { if(mmd->album!=NULL) g_free(mmd->album); mmd->album = g_strdup(tag_album); g_free(tag_album); } } if(gst_tag_list_get_string(tags, GST_TAG_COMMENT, &tag_comment)) { if(tag_comment!=NULL) { if(mmd->comment!=NULL) g_free(mmd->comment); mmd->comment = g_strdup(tag_comment); g_free(tag_comment); } } if(gst_tag_list_get_buffer(tags, GST_TAG_IMAGE, &tag_image)) { if(tag_image!=NULL) { if(mmd->image!=NULL) gst_buffer_unref(mmd->image); mmd->image = tag_image; } } if(gst_tag_list_get_buffer(tags, GST_TAG_PREVIEW_IMAGE, &tag_image)) { if(tag_image==NULL) mmd->image = tag_image; else gst_buffer_unref(tag_image); } if(gst_tag_list_get_uint(tags, GST_TAG_NOMINAL_BITRATE, &bitrates)) if(bitrates>0) mmd->bitrate = bitrates; if(gst_tag_list_get_uint(tags, GST_TAG_TRACK_NUMBER, &tracknum)) mmd->tracknum = tracknum; tag_cue_num = gst_tag_list_get_tag_size(tags, GST_TAG_EXTENDED_COMMENT); for(i=0;i<tag_cue_num && mmd->emb_cue==NULL;i++) { if(gst_tag_list_get_string_index(tags, GST_TAG_EXTENDED_COMMENT, i, &tag_cuelist)) { if(!strncmp(tag_cuelist, "cuesheet=", 9)) { if(mmd->emb_cue!=NULL) g_free(mmd->emb_cue); mmd->emb_cue = g_strdup(tag_cuelist+9); } if(tag_cuelist!=NULL) g_free(tag_cuelist); } } }
/* * Makes a pipeline in the form: * filesrc location=file ! demuxer ! fakesink * * And gets the tags that are posted on the bus to compare * with the tags in 'tag_str' */ static void test_demux_tags (const gchar * tag_str, const gchar * demuxer, const gchar * file) { GstElement *pipeline; GstBus *bus; GMainLoop *loop; GstTagList *sent_tags; gint i, j, k, n_recv, n_sent; const gchar *name_sent, *name_recv; const GValue *value_sent, *value_recv; gboolean found; gint comparison; GstElement *demux; gchar *launch_str; guint bus_watch = 0; GST_DEBUG ("testing tags : %s", tag_str); if (received_tags) { gst_tag_list_free (received_tags); received_tags = NULL; } launch_str = g_strdup_printf ("filesrc location=%s ! %s name=demux ! " "fakesink", file, demuxer); pipeline = gst_parse_launch (launch_str, NULL); g_free (launch_str); fail_unless (pipeline != NULL); demux = gst_bin_get_by_name (GST_BIN (pipeline), "demux"); fail_unless (demux != NULL); loop = g_main_loop_new (NULL, TRUE); fail_unless (loop != NULL); bus = gst_element_get_bus (pipeline); fail_unless (bus != NULL); bus_watch = gst_bus_add_watch (bus, bus_handler, loop); gst_object_unref (bus); sent_tags = gst_tag_list_new_from_string (tag_str); fail_unless (sent_tags != NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); g_main_loop_run (loop); GST_DEBUG ("mainloop done : %p", received_tags); /* verify tags */ fail_unless (received_tags != NULL); n_recv = gst_tag_list_n_tags (received_tags); n_sent = gst_tag_list_n_tags (sent_tags); fail_unless (n_recv >= n_sent); /* FIXME: compare taglits values */ for (i = 0; i < n_sent; i++) { name_sent = gst_tag_list_nth_tag_name (sent_tags, i); found = FALSE; for (j = 0; j < n_recv; j++) { name_recv = gst_tag_list_nth_tag_name (received_tags, j); if (!strcmp (name_sent, name_recv)) { guint sent_len, recv_len; sent_len = gst_tag_list_get_tag_size (sent_tags, name_sent); recv_len = gst_tag_list_get_tag_size (received_tags, name_recv); fail_unless (sent_len == recv_len, "tag item %s has been received with different size", name_sent); for (k = 0; k < sent_len; k++) { value_sent = gst_tag_list_get_value_index (sent_tags, name_sent, k); value_recv = gst_tag_list_get_value_index (received_tags, name_recv, k); comparison = gst_value_compare (value_sent, value_recv); if (comparison != GST_VALUE_EQUAL) { gchar *vs = g_strdup_value_contents (value_sent); gchar *vr = g_strdup_value_contents (value_recv); GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", G_VALUE_TYPE_NAME (value_sent), vs, G_VALUE_TYPE_NAME (value_recv), vr); g_free (vs); g_free (vr); } fail_unless (comparison == GST_VALUE_EQUAL, "tag item %s has been received with different type or value", name_sent); found = TRUE; break; } } } fail_unless (found, "tag item %s is lost", name_sent); } gst_tag_list_free (received_tags); received_tags = NULL; gst_tag_list_free (sent_tags); gst_element_set_state (pipeline, GST_STATE_NULL); g_main_loop_unref (loop); g_object_unref (demux); g_object_unref (pipeline); g_source_remove (bus_watch); }