mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
track-object: Keep a reference to our gnlobject
Avoid refering to an object that doesn't exists and segfault in some cases. We do not need to increase the reference to the gnlobj when the trackobject is removed from a track because the TrackObject as its own reference and will handle the disposal gracefully. Add some guard around related APIs
This commit is contained in:
parent
20e7d4349c
commit
9ee94b3d40
2 changed files with 26 additions and 8 deletions
|
@ -198,9 +198,29 @@ static void
|
||||||
ges_track_object_dispose (GObject * object)
|
ges_track_object_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GESTrackObjectPrivate *priv = GES_TRACK_OBJECT (object)->priv;
|
GESTrackObjectPrivate *priv = GES_TRACK_OBJECT (object)->priv;
|
||||||
|
|
||||||
if (priv->properties_hashtable)
|
if (priv->properties_hashtable)
|
||||||
g_hash_table_destroy (priv->properties_hashtable);
|
g_hash_table_destroy (priv->properties_hashtable);
|
||||||
|
|
||||||
|
if (priv->gnlobject) {
|
||||||
|
GstState cstate;
|
||||||
|
|
||||||
|
if (priv->track != NULL) {
|
||||||
|
GST_ERROR_OBJECT (object, "Still in %p, this means that you forgot"
|
||||||
|
" to remove it from the GESTrack it is contained in. You always need"
|
||||||
|
" to remove a GESTrackObject from its track before dropping the last"
|
||||||
|
" reference\n"
|
||||||
|
"This problem may also be caused by a refcounting bug in"
|
||||||
|
" the application or GES itself.", priv->track);
|
||||||
|
gst_element_get_state (priv->gnlobject, &cstate, NULL, 0);
|
||||||
|
if (cstate != GST_STATE_NULL)
|
||||||
|
gst_element_set_state (priv->gnlobject, GST_STATE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_unref (priv->gnlobject);
|
||||||
|
priv->gnlobject = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (ges_track_object_parent_class)->dispose (object);
|
G_OBJECT_CLASS (ges_track_object_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,7 +800,7 @@ ensure_gnl_object (GESTrackObject * object)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (object, "Got a valid GnlObject, now filling it in");
|
GST_DEBUG_OBJECT (object, "Got a valid GnlObject, now filling it in");
|
||||||
|
|
||||||
object->priv->gnlobject = gnlobject;
|
object->priv->gnlobject = gst_object_ref (gnlobject);
|
||||||
|
|
||||||
if (object->priv->timelineobj)
|
if (object->priv->timelineobj)
|
||||||
res = ges_timeline_object_fill_track_object (object->priv->timelineobj,
|
res = ges_timeline_object_fill_track_object (object->priv->timelineobj,
|
||||||
|
@ -921,6 +941,8 @@ ges_track_object_get_timeline_object (GESTrackObject * object)
|
||||||
GstElement *
|
GstElement *
|
||||||
ges_track_object_get_gnlobject (GESTrackObject * object)
|
ges_track_object_get_gnlobject (GESTrackObject * object)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), NULL);
|
||||||
|
|
||||||
return object->priv->gnlobject;
|
return object->priv->gnlobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,6 +958,8 @@ ges_track_object_get_gnlobject (GESTrackObject * object)
|
||||||
GstElement *
|
GstElement *
|
||||||
ges_track_object_get_element (GESTrackObject * object)
|
ges_track_object_get_element (GESTrackObject * object)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), NULL);
|
||||||
|
|
||||||
return object->priv->element;
|
return object->priv->element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,19 +548,13 @@ ges_track_remove_object (GESTrack * track, GESTrackObject * object)
|
||||||
if ((gnlobject = ges_track_object_get_gnlobject (object))) {
|
if ((gnlobject = ges_track_object_get_gnlobject (object))) {
|
||||||
GST_DEBUG ("Removing GnlObject '%s' from composition '%s'",
|
GST_DEBUG ("Removing GnlObject '%s' from composition '%s'",
|
||||||
GST_ELEMENT_NAME (gnlobject), GST_ELEMENT_NAME (priv->composition));
|
GST_ELEMENT_NAME (gnlobject), GST_ELEMENT_NAME (priv->composition));
|
||||||
/* We can't just set state of gnlobject to GST_STATE_NULL, because it will
|
|
||||||
* result in deadlock. Adding a ref to the gnlobj so we finalize it after
|
|
||||||
* removing it from the composition */
|
|
||||||
gst_object_ref (gnlobject);
|
|
||||||
if (!gst_bin_remove (GST_BIN (priv->composition), gnlobject)) {
|
if (!gst_bin_remove (GST_BIN (priv->composition), gnlobject)) {
|
||||||
GST_WARNING ("Failed to remove gnlobject from composition");
|
GST_WARNING ("Failed to remove gnlobject from composition");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_element_set_state (gnlobject, GST_STATE_NULL);
|
gst_element_set_state (gnlobject, GST_STATE_NULL);
|
||||||
/* Wait for the state change to actually happen */
|
|
||||||
gst_element_get_state (gnlobject, NULL, NULL, GST_CLOCK_TIME_NONE);
|
|
||||||
gst_object_unref (gnlobject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (object, sort_track_objects_cb, NULL);
|
g_signal_handlers_disconnect_by_func (object, sort_track_objects_cb, NULL);
|
||||||
|
|
Loading…
Reference in a new issue