/** * gst_object_replace: * @oldobj: (inout) (transfer full): pointer to a place of a #GstObject to * replace * @newobj: (transfer none): a new #GstObject * * Unrefs the #GstObject pointed to by @oldobj, refs @newobj and * puts @newobj in *@oldobj. Be carefull when calling this * function, it does not take any locks. You might want to lock * the object owning @oldobj pointer before calling this * function. * * Make sure not to LOCK @oldobj because it might be unreffed * which could cause a deadlock when it is disposed. * * Since 0.10.36, this function operates atomically. */ void gst_object_replace (GstObject ** oldobj, GstObject * newobj) { GstObject *oldptr; g_return_if_fail (oldobj != NULL); g_return_if_fail (*oldobj == NULL || GST_IS_OBJECT (*oldobj)); g_return_if_fail (newobj == NULL || GST_IS_OBJECT (newobj)); #ifdef DEBUG_REFCOUNT GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p %s (%d) with %p %s (%d)", *oldobj, *oldobj ? GST_STR_NULL (GST_OBJECT_NAME (*oldobj)) : "(NONE)", *oldobj ? G_OBJECT (*oldobj)->ref_count : 0, newobj, newobj ? GST_STR_NULL (GST_OBJECT_NAME (newobj)) : "(NONE)", newobj ? G_OBJECT (newobj)->ref_count : 0); #endif if (newobj) g_object_ref (newobj); do { oldptr = *oldobj; } while (!G_ATOMIC_POINTER_COMPARE_AND_EXCHANGE (oldobj, oldptr, newobj)); if (oldptr) g_object_unref (oldptr); }
EXPORT_C #endif void gst_object_replace (GstObject ** oldobj, GstObject * newobj) { g_return_if_fail (oldobj != NULL); g_return_if_fail (*oldobj == NULL || GST_IS_OBJECT (*oldobj)); g_return_if_fail (newobj == NULL || GST_IS_OBJECT (newobj)); #ifdef DEBUG_REFCOUNT GST_CAT_LOG (GST_CAT_REFCOUNTING, "replace %p %s (%d) with %p %s (%d)", *oldobj, *oldobj ? GST_STR_NULL (GST_OBJECT_NAME (*oldobj)) : "(NONE)", *oldobj ? G_OBJECT (*oldobj)->ref_count : 0, newobj, newobj ? GST_STR_NULL (GST_OBJECT_NAME (newobj)) : "(NONE)", newobj ? G_OBJECT (newobj)->ref_count : 0); #endif if (G_LIKELY (*oldobj != newobj)) { if (newobj) gst_object_ref (newobj); if (*oldobj) gst_object_unref (*oldobj); *oldobj = newobj; } }
/** * gst_object_set_parent: * @object: a #GstObject * @parent: new parent of object * * Sets the parent of @object to @parent. The object's reference count will * be incremented, and any floating reference will be removed (see gst_object_ref_sink()). * * Returns: TRUE if @parent could be set or FALSE when @object * already had a parent or @object and @parent are the same. * * MT safe. Grabs and releases @object's LOCK. */ gboolean gst_object_set_parent (GstObject * object, GstObject * parent) { g_return_val_if_fail (GST_IS_OBJECT (object), FALSE); g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE); g_return_val_if_fail (object != parent, FALSE); GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "set parent (ref and sink)"); GST_OBJECT_LOCK (object); if (G_UNLIKELY (object->parent != NULL)) goto had_parent; object->parent = parent; gst_object_ref_sink (object); GST_OBJECT_UNLOCK (object); /* FIXME, this does not work, the deep notify takes the lock from the parent * object and deadlocks when the parent holds its lock when calling this * function (like _element_add_pad()) */ /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */ return TRUE; /* ERROR handling */ had_parent: { GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "set parent failed, object already had a parent"); GST_OBJECT_UNLOCK (object); return FALSE; } }
static void check_gst_log_handler (GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function, gint line, GObject * object, GstDebugMessage * _message, gpointer data) { const gchar *message = gst_debug_message_get (_message); gchar *msg, *obj_str; const gchar *level_str, *cat_str; GstClockTime elapsed; //-- check message contents if (__check_method && (strstr (function, __check_method) != NULL) && __check_test && (strstr (message, __check_test) != NULL)) __check_error_trapped = TRUE; else if (__check_method && (strstr (function, __check_method) != NULL) && !__check_test) __check_error_trapped = TRUE; else if (__check_test && (strstr (message, __check_test) != NULL) && !__check_method) __check_error_trapped = TRUE; if (level > gst_debug_category_get_threshold (category)) return; elapsed = GST_CLOCK_DIFF (_priv_bt_info_start_time, gst_util_get_timestamp ()); level_str = gst_debug_level_get_name (level); cat_str = gst_debug_category_get_name (category); if (object) { if (GST_IS_OBJECT (object)) { obj_str = g_strdup_printf ("<%s,%" G_OBJECT_REF_COUNT_FMT ">", GST_OBJECT_NAME (object), G_OBJECT_LOG_REF_COUNT (object)); } else if (GST_IS_OBJECT (object)) { obj_str = g_strdup_printf ("<%s,%" G_OBJECT_REF_COUNT_FMT ">", G_OBJECT_TYPE_NAME (object), G_OBJECT_LOG_REF_COUNT (object)); } else { obj_str = g_strdup_printf ("%p", object); } } else { obj_str = g_strdup (""); } msg = g_alloca (95 + strlen (cat_str) + strlen (level_str) + strlen (message) + strlen (file) + strlen (function) + strlen (obj_str)); g_sprintf (msg, "%" GST_TIME_FORMAT " %" PID_FMT " %" PTR_FMT " %-7s %20s %s:%d:%s:%s %s", GST_TIME_ARGS (elapsed), getpid (), g_thread_self (), level_str, cat_str, file, line, function, obj_str, message); g_free (obj_str); check_print_handler (msg); }
/** * gst_child_proxy_set_valist: * @object: the parent object * @first_property_name: name of the first property to set * @var_args: value for the first property, followed optionally by more name/value pairs, followed by NULL * * Sets properties of the parent object and its children. */ void gst_child_proxy_set_valist (GstChildProxy * object, const gchar * first_property_name, va_list var_args) { const gchar *name; gchar *error = NULL; GValue value = { 0, }; GParamSpec *pspec; GObject *target; g_return_if_fail (GST_IS_CHILD_PROXY (object)); name = first_property_name; /* iterate over pairs */ while (name) { if (!gst_child_proxy_lookup (object, name, &target, &pspec)) goto not_found; G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args, G_VALUE_NOCOPY_CONTENTS, &error); if (error) goto cant_copy; g_object_set_property (target, pspec->name, &value); g_object_unref (target); g_value_unset (&value); name = va_arg (var_args, gchar *); } return; not_found: { g_warning ("no property %s in object %s", name, (GST_IS_OBJECT (object) ? GST_OBJECT_NAME (object) : "")); return; } cant_copy: { g_warning ("error copying value %s in object %s: %s", pspec->name, (GST_IS_OBJECT (object) ? GST_OBJECT_NAME (object) : ""), error); g_value_unset (&value); g_object_unref (target); return; } }
void gst_debugserver_log_send_log (GstDebugserverLog * log, GstDebugserverTcp * tcp_server, GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function, gint line, GObject * object, GstDebugMessage * message) { GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT; GstDebugger__LogInfo log_info = GST_DEBUGGER__LOG_INFO__INIT; log_info.level = (gint) level; log_info.category = (gchar *) gst_debug_category_get_name (category); log_info.file = (gchar *) file; log_info.function = (gchar *) function; log_info.line = line; if (GST_IS_OBJECT (object)) { log_info.object = GST_OBJECT_NAME (object); } else { log_info.object = (gchar *) G_OBJECT_TYPE_NAME (object); } log_info.message = (gchar *) gst_debug_message_get (message); gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_LOG_INFO; gst_data.log_info = &log_info; gst_debugserver_hooks_send_data (&log->hooks, tcp_server, &gst_data); }
EXPORT_C #endif gboolean gst_object_set_name (GstObject * object, const gchar * name) { gboolean result; g_return_val_if_fail (GST_IS_OBJECT (object), FALSE); GST_OBJECT_LOCK (object); /* parented objects cannot be renamed */ if (G_UNLIKELY (object->parent != NULL)) goto had_parent; if (name != NULL) { g_free (object->name); object->name = g_strdup (name); GST_OBJECT_UNLOCK (object); result = TRUE; } else { GST_OBJECT_UNLOCK (object); result = gst_object_set_name_default (object); } return result; /* error */ had_parent: { GST_WARNING ("parented objects can't be renamed"); GST_OBJECT_UNLOCK (object); return FALSE; } }
EXPORT_C #endif void gst_object_unparent (GstObject * object) { GstObject *parent; g_return_if_fail (GST_IS_OBJECT (object)); GST_OBJECT_LOCK (object); parent = object->parent; if (G_LIKELY (parent != NULL)) { GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unparent"); object->parent = NULL; GST_OBJECT_UNLOCK (object); g_signal_emit (object, gst_object_signals[PARENT_UNSET], 0, parent); gst_object_unref (object); } else { GST_OBJECT_UNLOCK (object); } }
/** * gst_child_proxy_set_property: * @object: the parent object * @name: name of the property to set * @value: new #GValue for the property * * Sets a single property using the GstChildProxy mechanism. */ void gst_child_proxy_set_property (GstChildProxy * object, const gchar * name, const GValue * value) { GParamSpec *pspec; GObject *target; g_return_if_fail (GST_IS_CHILD_PROXY (object)); g_return_if_fail (name != NULL); g_return_if_fail (G_IS_VALUE (value)); if (!gst_child_proxy_lookup (object, name, &target, &pspec)) goto not_found; g_object_set_property (target, pspec->name, value); g_object_unref (target); return; not_found: { g_warning ("cannot set property %s on object %s", name, (GST_IS_OBJECT (object) ? GST_OBJECT_NAME (object) : "")); return; } }
static void gst_log_android_handler(GstDebugCategory *category, GstDebugLevel level, const gchar *file, const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer data) { gchar *obj = NULL; OWR_UNUSED(data); if (level > gst_debug_category_get_threshold(category)) return; if (GST_IS_PAD(object) && GST_OBJECT_NAME(object)) { obj = g_strdup_printf("<%s:%s>", GST_DEBUG_PAD_NAME(object)); } else if (GST_IS_OBJECT(object)) { obj = g_strdup_printf("<%s>", GST_OBJECT_NAME(object)); } __android_log_print(ANDROID_LOG_INFO, "gst_log", "%p %s %s %s:%d:%s:%s %s\n", (void *)g_thread_self(), gst_debug_level_get_name(level), gst_debug_category_get_name(category), file, line, function, obj ? obj : "", gst_debug_message_get(message)); g_free(obj); }
GstCaps * gst_type_find_helper_get_range (GstObject * obj, GstTypeFindHelperGetRangeFunction func, guint64 size, GstTypeFindProbability * prob) { GstTypeFindHelper helper; GstTypeFind find; GSList *walk; GList *l, *type_list; GstCaps *result = NULL; g_return_val_if_fail (GST_IS_OBJECT (obj), NULL); g_return_val_if_fail (func != NULL, NULL); helper.buffers = NULL; helper.size = size; helper.last_offset = 0; helper.func = func; helper.best_probability = 0; helper.caps = NULL; helper.obj = obj; find.data = &helper; find.peek = helper_find_peek; find.suggest = helper_find_suggest; if (size == 0 || size == (guint64) - 1) { find.get_length = NULL; } else { find.get_length = helper_find_get_length; } /* FIXME: we need to keep this list within the registry */ type_list = gst_type_find_factory_get_list (); type_list = g_list_sort (type_list, type_find_factory_rank_cmp); for (l = type_list; l; l = l->next) { helper.factory = GST_TYPE_FIND_FACTORY (l->data); gst_type_find_factory_call_function (helper.factory, &find); if (helper.best_probability >= GST_TYPE_FIND_MAXIMUM) break; } gst_plugin_feature_list_free (type_list); for (walk = helper.buffers; walk; walk = walk->next) gst_buffer_unref (GST_BUFFER_CAST (walk->data)); g_slist_free (helper.buffers); if (helper.best_probability > 0) result = helper.caps; if (prob) *prob = helper.best_probability; GST_LOG_OBJECT (obj, "Returning %" GST_PTR_FORMAT " (probability = %u)", result, (guint) helper.best_probability); return result; }
/** * gst_index_get_writer_id: * @index: the index to get a unique write id for * @writer: the GstObject to allocate an id for * @id: a pointer to a gint to hold the id * * Before entries can be added to the index, a writer * should obtain a unique id. The methods to add new entries * to the index require this id as an argument. * * The application can implement a custom function to map the writer object * to a string. That string will be used to register or look up an id * in the index. * * <note> * The caller must not hold @writer's #GST_OBJECT_LOCK, as the default * resolver may call functions that take the object lock as well, and * the lock is not recursive. * </note> * * Returns: TRUE if the writer would be mapped to an id. */ gboolean gst_index_get_writer_id (GstIndex * index, GstObject * writer, gint * id) { gchar *writer_string = NULL; GstIndexEntry *entry; GstIndexClass *iclass; gboolean success = FALSE; g_return_val_if_fail (GST_IS_INDEX (index), FALSE); g_return_val_if_fail (GST_IS_OBJECT (writer), FALSE); g_return_val_if_fail (id, FALSE); *id = -1; /* first try to get a previously cached id */ entry = g_hash_table_lookup (index->writers, writer); if (entry == NULL) { iclass = GST_INDEX_GET_CLASS (index); /* let the app make a string */ if (index->resolver) { gboolean res; res = index->resolver (index, writer, &writer_string, index->resolver_user_data); if (!res) return FALSE; } else { g_warning ("no resolver found"); return FALSE; } /* if the index has a resolver, make it map this string to an id */ if (iclass->get_writer_id) { success = iclass->get_writer_id (index, id, writer_string); } /* if the index could not resolve, we allocate one ourselves */ if (!success) { *id = ++index->last_id; } entry = gst_index_add_id (index, *id, writer_string); if (!entry) { /* index is probably not writable, make an entry anyway * to keep it in our cache */ entry = g_slice_new (GstIndexEntry); entry->type = GST_INDEX_ENTRY_ID; entry->id = *id; entry->data.id.description = writer_string; } g_hash_table_insert (index->writers, writer, entry); } else { *id = entry->id; } return TRUE; }
static void gst_object_real_restore_thyself (GstObject * object, xmlNodePtr self) { g_return_if_fail (GST_IS_OBJECT (object)); g_return_if_fail (self != NULL); gst_class_signal_emit_by_name (object, "object_loaded", self); }
EXPORT_C #endif gboolean gst_object_set_parent (GstObject * object, GstObject * parent) { g_return_val_if_fail (GST_IS_OBJECT (object), FALSE); g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE); g_return_val_if_fail (object != parent, FALSE); GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "set parent (ref and sink)"); GST_OBJECT_LOCK (object); if (G_UNLIKELY (object->parent != NULL)) goto had_parent; /* sink object, we don't call our own function because we don't * need to release/acquire the lock needlessly or touch the refcount * in the floating case. */ object->parent = parent; if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) { GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unsetting floating flag"); GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING); GST_OBJECT_UNLOCK (object); } else { GST_OBJECT_UNLOCK (object); gst_object_ref (object); } g_signal_emit (object, gst_object_signals[PARENT_SET], 0, parent); return TRUE; /* ERROR handling */ had_parent: { GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "set parent failed, object already had a parent"); GST_OBJECT_UNLOCK (object); return FALSE; } }
void gst_object_set_name_prefix (GstObject * object, const gchar * name_prefix) { g_return_if_fail (GST_IS_OBJECT (object)); GST_OBJECT_LOCK (object); g_free (object->name_prefix); object->name_prefix = g_strdup (name_prefix); /* NULL gives NULL */ GST_OBJECT_UNLOCK (object); }
/** * gst_child_proxy_lookup: * @childproxy: child proxy object to lookup the property in * @name: name of the property to look up * @target: (out) (allow-none) (transfer full): pointer to a #GObject that * takes the real object to set property on * @pspec: (out) (allow-none) (transfer none): pointer to take the #GParamSpec * describing the property * * Looks up which object and #GParamSpec would be effected by the given @name. * * MT safe. * * Returns: TRUE if @target and @pspec could be found. FALSE otherwise. In that * case the values for @pspec and @target are not modified. Unref @target after * usage. For plain GObjects @target is the same as @object. */ gboolean gst_child_proxy_lookup (GstChildProxy * childproxy, const gchar * name, GObject ** target, GParamSpec ** pspec) { GObject *object; gboolean res = FALSE; gchar **names, **current; g_return_val_if_fail (GST_IS_CHILD_PROXY (childproxy), FALSE); g_return_val_if_fail (name != NULL, FALSE); object = g_object_ref (childproxy); current = names = g_strsplit (name, "::", -1); /* find the owner of the property */ while (current[1]) { GObject *next; if (!GST_IS_CHILD_PROXY (object)) { GST_INFO ("object %s is not a parent, so you cannot request a child by name %s", (GST_IS_OBJECT (object) ? GST_OBJECT_NAME (object) : ""), current[0]); break; } next = gst_child_proxy_get_child_by_name (GST_CHILD_PROXY (object), current[0]); if (!next) { GST_INFO ("no such object %s", current[0]); break; } g_object_unref (object); object = next; current++; } /* look for psec */ if (current[1] == NULL) { GParamSpec *spec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), current[0]); if (spec == NULL) { GST_INFO ("no param spec named %s", current[0]); } else { if (pspec) *pspec = spec; if (target) { g_object_ref (object); *target = object; } res = TRUE; } } g_object_unref (object); g_strfreev (names); return res; }
GstCaps * gst_type_find_helper (GstPad * src, guint64 size) { GstTypeFindHelperGetRangeFunction func; g_return_val_if_fail (GST_IS_OBJECT (src), NULL); g_return_val_if_fail (GST_PAD_GETRANGEFUNC (src) != NULL, NULL); func = (GstTypeFindHelperGetRangeFunction) (GST_PAD_GETRANGEFUNC (src)); return gst_type_find_helper_get_range (GST_OBJECT (src), func, size, NULL); }
/** * gst_object_restore_thyself: * @object: a #GstObject to load into * @self: The XML node to load @object from * * Restores @object with the data from the parent XML node. */ void gst_object_restore_thyself (GstObject * object, xmlNodePtr self) { GstObjectClass *oclass; g_return_if_fail (GST_IS_OBJECT (object)); g_return_if_fail (self != NULL); oclass = GST_OBJECT_GET_CLASS (object); if (oclass->restore_thyself) oclass->restore_thyself (object, self); }
void rbcltgst_initialize_gst_object (VALUE obj, gpointer gstobj) { /* Grab the floating reference if the object is a subclass of GstObject */ if (GST_IS_OBJECT (gstobj)) { gst_object_ref (gstobj); gst_object_sink (gstobj); } G_INITIALIZE (obj, gstobj); }
/** * gst_object_get_name: * @object: a #GstObject * * Returns a copy of the name of @object. * Caller should g_free() the return value after usage. * For a nameless object, this returns NULL, which you can safely g_free() * as well. * * Free-function: g_free * * Returns: (transfer full): the name of @object. g_free() after usage. * * MT safe. This function grabs and releases @object's LOCK. */ gchar * gst_object_get_name (GstObject * object) { gchar *result = NULL; g_return_val_if_fail (GST_IS_OBJECT (object), NULL); GST_OBJECT_LOCK (object); result = g_strdup (object->name); GST_OBJECT_UNLOCK (object); return result; }
/** * gst_object_get_parent: * @object: a #GstObject * * Returns the parent of @object. This function increases the refcount * of the parent object so you should gst_object_unref() it after usage. * * Returns: (transfer full): parent of @object, this can be NULL if @object * has no parent. unref after usage. * * MT safe. Grabs and releases @object's LOCK. */ GstObject * gst_object_get_parent (GstObject * object) { GstObject *result = NULL; g_return_val_if_fail (GST_IS_OBJECT (object), NULL); GST_OBJECT_LOCK (object); result = object->parent; if (G_LIKELY (result)) gst_object_ref (result); GST_OBJECT_UNLOCK (object); return result; }
void pr_helper(unsigned int level, void *object, const char *file, const char *function, unsigned int line, const char *fmt, ...) { char *tmp; va_list args; va_start(args, fmt); if (vasprintf(&tmp, fmt, args) < 0) goto leave; if (level <= 1) { #ifdef SYSLOG if (object && GST_IS_OBJECT(object) && GST_OBJECT_NAME(object)) syslog(log_level_to_syslog(level), "%s: %s", GST_OBJECT_NAME(object), tmp); else syslog(log_level_to_syslog(level), "%s", tmp); #endif if (level == 0) g_printerr("%s: %s\n", function, tmp); else g_print("%s: %s\n", function, tmp); } else if (level == 2) g_print("%s:%s(%u): %s\n", file, function, line, tmp); #if defined(DEVEL) || defined(DEBUG) else if (level == 3) g_print("%s: %s\n", function, tmp); #endif #ifdef DEBUG else if (level == 4) g_print("%s:%s(%u): %s\n", file, function, line, tmp); #endif #ifndef GST_DISABLE_GST_DEBUG gst_debug_log_valist(gstdsp_debug, log_level_to_gst(level), file, function, line, object, fmt, args); #endif free(tmp); leave: va_end(args); }
/** * gst_object_ref_sink: * @object: a #GstObject to sink * * Increase the reference count of @object, and possibly remove the floating * reference, if @object has a floating reference. * * In other words, if the object is floating, then this call "assumes ownership" * of the floating reference, converting it to a normal reference by clearing * the floating flag while leaving the reference count unchanged. If the object * is not floating, then this call adds a new normal reference increasing the * reference count by one. * * MT safe. This function grabs and releases @object lock. * * Since: 0.10.24 */ void gst_object_ref_sink (gpointer object) { g_return_if_fail (GST_IS_OBJECT (object)); GST_OBJECT_LOCK (object); if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) { GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "unsetting floating flag"); GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING); GST_OBJECT_UNLOCK (object); } else { GST_OBJECT_UNLOCK (object); gst_object_ref (object); } }
/** * gst_object_save_thyself: * @object: a #GstObject to save * @parent: The parent XML node to save @object into * * Saves @object into the parent XML node. * * Returns: the new xmlNodePtr with the saved object */ xmlNodePtr gst_object_save_thyself (GstObject * object, xmlNodePtr parent) { GstObjectClass *oclass; g_return_val_if_fail (GST_IS_OBJECT (object), parent); g_return_val_if_fail (parent != NULL, parent); oclass = GST_OBJECT_GET_CLASS (object); if (oclass->save_thyself) oclass->save_thyself (object, parent); g_signal_emit (object, gst_object_signals[OBJECT_SAVED], 0, parent); return parent; }
EXPORT_C #endif gchar * gst_object_get_path_string (GstObject * object) { GSList *parentage; GSList *parents; void *parent; gchar *prevpath, *path; const gchar *typename; gchar *component; gchar *separator; /* ref object before adding to list */ gst_object_ref (object); parentage = g_slist_prepend (NULL, object); path = g_strdup (""); /* first walk the object hierarchy to build a list of the parents, * be carefull here with refcounting. */ do { if (GST_IS_OBJECT (object)) { parent = gst_object_get_parent (object); /* add parents to list, refcount remains increased while * we handle the object */ if (parent) parentage = g_slist_prepend (parentage, parent); } else { break; } object = parent; } while (object != NULL); /* then walk the parent list and print them out. we need to * decrease the refcounting on each element after we handled * it. */ for (parents = parentage; parents; parents = g_slist_next (parents)) { if (G_IS_OBJECT (parents->data)) { typename = G_OBJECT_TYPE_NAME (parents->data); } else {
EXPORT_C #endif void gst_object_sink (gpointer object) { g_return_if_fail (GST_IS_OBJECT (object)); GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "sink"); GST_OBJECT_LOCK (object); if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) { GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "clear floating flag"); GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING); GST_OBJECT_UNLOCK (object); gst_object_unref (object); } else { GST_OBJECT_UNLOCK (object); } }
static GObject * gst_child_proxy_default_get_child_by_name (GstChildProxy * parent, const gchar * name) { guint count, i; GObject *object, *result; gchar *object_name; g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), NULL); g_return_val_if_fail (name != NULL, NULL); result = NULL; count = gst_child_proxy_get_children_count (parent); for (i = 0; i < count; i++) { gboolean eq; if (!(object = gst_child_proxy_get_child_by_index (parent, i))) continue; if (!GST_IS_OBJECT (object)) { goto next; } object_name = gst_object_get_name (GST_OBJECT_CAST (object)); if (object_name == NULL) { g_warning ("child %u of parent %s has no name", i, GST_OBJECT_NAME (parent)); goto next; } eq = g_str_equal (object_name, name); g_free (object_name); if (eq) { result = object; break; } next: g_object_unref (object); } return result; }
/* Changing a GObject property of a GstObject will result in "deep_notify" * signals being emitted by the object itself, as well as in each parent * object. This is so that an application can connect a listener to the * top-level bin to catch property-change notifications for all contained * elements. * * This function is not MT safe in glib < 2.8 so we need to lock it with a * classwide mutex in that case. * * MT safe. */ static void gst_object_dispatch_properties_changed (GObject * object, guint n_pspecs, GParamSpec ** pspecs) { GstObject *gst_object, *parent, *old_parent; guint i; gchar *name, *debug_name; GstObjectClass *klass; /* we fail when this is not a GstObject */ g_return_if_fail (GST_IS_OBJECT (object)); klass = GST_OBJECT_GET_CLASS (object); /* do the standard dispatching */ G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); gst_object = GST_OBJECT_CAST (object); name = gst_object_get_name (gst_object); debug_name = GST_STR_NULL (name); /* now let the parent dispatch those, too */ parent = gst_object_get_parent (gst_object); while (parent) { for (i = 0; i < n_pspecs; i++) { GST_LOG_OBJECT (parent, "deep notification from %s (%s)", debug_name, pspecs[i]->name); g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY], g_quark_from_string (pspecs[i]->name), GST_OBJECT_CAST (object), pspecs[i]); } old_parent = parent; parent = gst_object_get_parent (old_parent); gst_object_unref (old_parent); } g_free (name); }
/** * gst_object_unparent: * @object: a #GstObject to unparent * * Clear the parent of @object, removing the associated reference. * This function decreases the refcount of @object. * * MT safe. Grabs and releases @object's lock. */ void gst_object_unparent (GstObject * object) { GstObject *parent; g_return_if_fail (GST_IS_OBJECT (object)); GST_OBJECT_LOCK (object); parent = object->parent; if (G_LIKELY (parent != NULL)) { GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "unparent"); object->parent = NULL; GST_OBJECT_UNLOCK (object); /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */ gst_object_unref (object); } else { GST_OBJECT_UNLOCK (object); } }
static void _determine_reporting_level (GstValidateMonitor * monitor) { GstValidateRunner *runner; GstObject *object, *parent; gchar *object_name; GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN; object = gst_validate_monitor_get_target (monitor); runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor)); do { if (!GST_IS_OBJECT (object)) break; /* Let's allow for singling out pads */ if (GST_IS_PAD (object)) { level = _get_report_level_for_pad (runner, object); if (level != GST_VALIDATE_SHOW_UNKNOWN) break; } object_name = gst_object_get_name (object); level = gst_validate_runner_get_reporting_level_for_name (runner, object_name); parent = gst_object_get_parent (object); gst_object_unref (object); object = parent; g_free (object_name); } while (object && level == GST_VALIDATE_SHOW_UNKNOWN); if (object) gst_object_unref (object); if (runner) gst_object_unref (runner); monitor->level = level; }