diff --git a/ChangeLog b/ChangeLog index 8347ec569b..c3a711bf37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-04-17 Ronald S. Bultje + + * gst/elements/gsttypefindelement.c: (gst_type_find_element_init), + (push_buffer_store), (gst_type_find_element_handle_event), + (gst_type_find_element_change_state): + Allow event caching while typefinding so we don't lose events. + * gst/elements/gsttypefindelement.h: + Allow event caching while typefinding so we don't lose events. + * gst/gsttag.c: (_gst_tag_initialize): + * gst/gsttag.h: + Add language-code tag. + * gst/registries/gstlibxmlregistry.c: (load_pad_template), + (load_feature), (load_paths): + Fix memleaks (#300736), based on patch from Kjartan Maraas + . + 2005-04-14 Ronald S. Bultje * docs/faq/using.xml: diff --git a/gst/elements/gsttypefindelement.c b/gst/elements/gsttypefindelement.c index 593ec1cb0c..c4a5f00180 100644 --- a/gst/elements/gsttypefindelement.c +++ b/gst/elements/gsttypefindelement.c @@ -197,6 +197,7 @@ gst_type_find_element_init (GstTypeFindElement * typefind) gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); typefind->caps = NULL; + typefind->pending_events = NULL; typefind->min_probability = 1; typefind->max_probability = GST_TYPE_FIND_MAXIMUM; @@ -412,7 +413,18 @@ push_buffer_store (GstTypeFindElement * typefind) { guint size = gst_buffer_store_get_size (typefind->store, 0); GstBuffer *buffer; + const GList *item; + /* handle pending events */ + for (item = typefind->pending_events; item; item = item->next) { + GstEvent *e = item->data; + + gst_pad_push (typefind->src, GST_DATA (e)); + } + g_list_free (typefind->pending_events); + typefind->pending_events = NULL; + + /* data */ gst_pad_push (typefind->src, GST_DATA (gst_event_new_discontinuous (TRUE, GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, GST_FORMAT_UNDEFINED))); @@ -494,7 +506,8 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event) } break; default: - gst_data_unref (GST_DATA (event)); + typefind->pending_events = g_list_append (typefind->pending_events, + event); break; } break; @@ -816,6 +829,9 @@ gst_type_find_element_change_state (GstElement * element) case GST_STATE_PAUSED_TO_READY: stop_typefinding (typefind); gst_caps_replace (&typefind->caps, NULL); + g_list_foreach (typefind->pending_events, (GFunc) gst_data_unref, NULL); + g_list_free (typefind->pending_events); + typefind->pending_events = NULL; break; default: break; diff --git a/gst/elements/gsttypefindelement.h b/gst/elements/gsttypefindelement.h index 43debd5e28..0b243dbd94 100644 --- a/gst/elements/gsttypefindelement.h +++ b/gst/elements/gsttypefindelement.h @@ -51,6 +51,7 @@ struct _GstTypeFindElement { guint min_probability; guint max_probability; GstCaps * caps; + GList * pending_events; guint mode; guint64 waiting_for_discont_offset; diff --git a/gst/gsttag.c b/gst/gsttag.c index 127a7d2218..d8d90bbd8d 100644 --- a/gst/gsttag.c +++ b/gst/gsttag.c @@ -188,6 +188,9 @@ _gst_tag_initialize (void) G_TYPE_DOUBLE, _("replaygain album gain"), _("album gain in db"), NULL); gst_tag_register (GST_TAG_ALBUM_PEAK, GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("replaygain album peak"), _("peak of the album"), NULL); + gst_tag_register (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META, G_TYPE_STRING, + _("language code"), + _("language code for this stream, conforming to ISO-639-1"), NULL); } /** diff --git a/gst/gsttag.h b/gst/gsttag.h index 5651178e60..b24244c861 100644 --- a/gst/gsttag.h +++ b/gst/gsttag.h @@ -430,6 +430,12 @@ GstTagList * gst_event_tag_get_list (GstEvent * tag_event); * peak of the album */ #define GST_TAG_ALBUM_PEAK "replaygain-album-peak" +/** + * GST_TAG_LANGUAGE_CODE: + * + * Language code (ISO-639-1) + */ +#define GST_TAG_LANGUAGE_CODE "language-code" G_END_DECLS diff --git a/gst/gsttaglist.c b/gst/gsttaglist.c index 127a7d2218..d8d90bbd8d 100644 --- a/gst/gsttaglist.c +++ b/gst/gsttaglist.c @@ -188,6 +188,9 @@ _gst_tag_initialize (void) G_TYPE_DOUBLE, _("replaygain album gain"), _("album gain in db"), NULL); gst_tag_register (GST_TAG_ALBUM_PEAK, GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("replaygain album peak"), _("peak of the album"), NULL); + gst_tag_register (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META, G_TYPE_STRING, + _("language code"), + _("language code for this stream, conforming to ISO-639-1"), NULL); } /** diff --git a/gst/gsttaglist.h b/gst/gsttaglist.h index 5651178e60..b24244c861 100644 --- a/gst/gsttaglist.h +++ b/gst/gsttaglist.h @@ -430,6 +430,12 @@ GstTagList * gst_event_tag_get_list (GstEvent * tag_event); * peak of the album */ #define GST_TAG_ALBUM_PEAK "replaygain-album-peak" +/** + * GST_TAG_LANGUAGE_CODE: + * + * Language code (ISO-639-1) + */ +#define GST_TAG_LANGUAGE_CODE "language-code" G_END_DECLS diff --git a/gst/registries/gstlibxmlregistry.c b/gst/registries/gstlibxmlregistry.c index b56238d5e3..9e6392e975 100644 --- a/gst/registries/gstlibxmlregistry.c +++ b/gst/registries/gstlibxmlregistry.c @@ -680,11 +680,12 @@ load_pad_template (xmlTextReaderPtr reader) } else if (g_str_equal (tag, "presence")) { read_enum (reader, GST_TYPE_PAD_PRESENCE, &presence); } else if (!strncmp (tag, "caps", 4)) { - char *s = NULL; + gchar *s = NULL; - if (!caps && read_string (reader, &s)) + if (!caps && read_string (reader, &s)) { caps = gst_caps_from_string (s); - g_free (s); + g_free (s); + } } } } @@ -699,14 +700,15 @@ load_feature (xmlTextReaderPtr reader) { int ret; int depth = xmlTextReaderDepth (reader); - const gchar *feature_name = - (const gchar *) xmlTextReaderGetAttribute (reader, BAD_CAST "typename"); + guchar *feature_name = + xmlTextReaderGetAttribute (reader, BAD_CAST "typename"); GstPluginFeature *feature; GType type; if (!feature_name) return NULL; - type = g_type_from_name (feature_name); + type = g_type_from_name ((gchar *) feature_name); + xmlFree (feature_name); if (!type) return NULL; feature = g_object_new (type, NULL); @@ -744,9 +746,10 @@ load_feature (xmlTextReaderPtr reader) if (read_string (reader, &s)) { if (g_ascii_strncasecmp (s, "sink", 4) == 0) { factory->uri_type = GST_URI_SINK; - } else if (g_ascii_strncasecmp (s, "source", 5) == 0) { + } else if (g_ascii_strncasecmp (s, "source", 6) == 0) { factory->uri_type = GST_URI_SRC; } + g_free (s); } } else if (g_str_equal (tag, "uri_protocol")) { gchar *s = NULL; @@ -756,8 +759,10 @@ load_feature (xmlTextReaderPtr reader) } else if (g_str_equal (tag, "interface")) { gchar *s = NULL; - if (read_string (reader, &s)) + if (read_string (reader, &s)) { __gst_element_factory_add_interface (factory, s); + g_free (s); + } } else if (g_str_equal (tag, "padtemplate")) { GstPadTemplate *template = load_pad_template (reader); @@ -779,7 +784,7 @@ load_feature (xmlTextReaderPtr reader) } else if (g_str_equal (tag, "caps")) { gchar *s = NULL; - if (read_string (reader, &s)) { + if (!factory->caps && read_string (reader, &s)) { factory->caps = gst_caps_from_string (s); g_free (s); } @@ -865,11 +870,12 @@ load_paths (xmlTextReaderPtr reader, GstXMLRegistry * registry) if (g_str_equal (tag, "path")) { gchar *s = NULL; - if (read_string (reader, &s) && - !g_list_find_custom (GST_REGISTRY (registry)->paths, s, - (GCompareFunc) strcmp)) - gst_registry_add_path (GST_REGISTRY (registry), s); - g_free (s); + if (read_string (reader, &s)) { + if (!g_list_find_custom (GST_REGISTRY (registry)->paths, s, + (GCompareFunc) strcmp)) + gst_registry_add_path (GST_REGISTRY (registry), s); + g_free (s); + } } } } diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c index 593ec1cb0c..c4a5f00180 100644 --- a/plugins/elements/gsttypefindelement.c +++ b/plugins/elements/gsttypefindelement.c @@ -197,6 +197,7 @@ gst_type_find_element_init (GstTypeFindElement * typefind) gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); typefind->caps = NULL; + typefind->pending_events = NULL; typefind->min_probability = 1; typefind->max_probability = GST_TYPE_FIND_MAXIMUM; @@ -412,7 +413,18 @@ push_buffer_store (GstTypeFindElement * typefind) { guint size = gst_buffer_store_get_size (typefind->store, 0); GstBuffer *buffer; + const GList *item; + /* handle pending events */ + for (item = typefind->pending_events; item; item = item->next) { + GstEvent *e = item->data; + + gst_pad_push (typefind->src, GST_DATA (e)); + } + g_list_free (typefind->pending_events); + typefind->pending_events = NULL; + + /* data */ gst_pad_push (typefind->src, GST_DATA (gst_event_new_discontinuous (TRUE, GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, GST_FORMAT_UNDEFINED))); @@ -494,7 +506,8 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event) } break; default: - gst_data_unref (GST_DATA (event)); + typefind->pending_events = g_list_append (typefind->pending_events, + event); break; } break; @@ -816,6 +829,9 @@ gst_type_find_element_change_state (GstElement * element) case GST_STATE_PAUSED_TO_READY: stop_typefinding (typefind); gst_caps_replace (&typefind->caps, NULL); + g_list_foreach (typefind->pending_events, (GFunc) gst_data_unref, NULL); + g_list_free (typefind->pending_events); + typefind->pending_events = NULL; break; default: break; diff --git a/plugins/elements/gsttypefindelement.h b/plugins/elements/gsttypefindelement.h index 43debd5e28..0b243dbd94 100644 --- a/plugins/elements/gsttypefindelement.h +++ b/plugins/elements/gsttypefindelement.h @@ -51,6 +51,7 @@ struct _GstTypeFindElement { guint min_probability; guint max_probability; GstCaps * caps; + GList * pending_events; guint mode; guint64 waiting_for_discont_offset;