gboolean groj_tag_catch_double(GstTagList *taglist, char *tagname, char *plugin, struct RojDouble *tag) { int n, size = gst_tag_list_n_tags(taglist); for (n=0; n<size; ++n) { if (!strcmp(gst_tag_list_nth_tag_name(taglist, n), tagname)){ gst_tag_list_get_double (taglist, gst_tag_list_nth_tag_name(taglist, n), &tag->val); g_print("\t\e[1;32m(assign in %s to %s): %g\e[0m\n", plugin, tagname, tag->val); tag->flag = TRUE; return TRUE; } }
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); }
tag_list calculate_new_tags(tag_list const &p_reference, tag_list const &p_other) { tag_list result; guint num_tags; if (p_other.is_empty()) return result; num_tags = gst_tag_list_n_tags(p_other.get_tag_list()); for (guint num = 0; num < num_tags; ++num) { std::string name(gst_tag_list_nth_tag_name(p_other.get_tag_list(), num)); guint num_tag_values_in_other = get_num_values_for_tag(p_other, name); // If the reference list already has this tag, check if the values differ. // If it doesn't have this tag yet, it is an addition, so add the tag to // the result right away. if (has_value(p_reference, name)) { guint num_tag_values_in_reference = get_num_values_for_tag(p_reference, name); // If the number of tag values differ, add the other's values to // the result, assuming a change (an addition). // If the numbers are the same, compare each value pair. if (num_tag_values_in_other == num_tag_values_in_reference) { bool equal = true; for (guint index = 0; index < num_tag_values_in_other; ++index) { GValue const *other_value = get_raw_value(p_other, name, index); GValue const *reference_value = get_raw_value(p_reference, name, index); if (gst_value_compare(other_value, reference_value) != GST_VALUE_EQUAL) { equal = false; break; } } if (equal) continue; } } for (guint index = 0; index < num_tag_values_in_other; ++index) add_raw_value(result, get_raw_value(p_other, name, index), name, GST_TAG_MERGE_APPEND); } return result; }
/* * 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); }
// ---------------------------------------------------------------------------- // 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); } } }