TimelineObject: Hold a reference to the controlled TrackObject

This commit is contained in:
Edward Hervey 2010-12-20 11:56:37 +01:00
parent 648f8802db
commit c90f399bfb
3 changed files with 86 additions and 21 deletions

View file

@ -343,6 +343,8 @@ ges_timeline_object_create_track_objects_func (GESTimelineObject * object,
* Add a track object to the timeline object. Should only be called by * Add a track object to the timeline object. Should only be called by
* subclasses implementing the create_track_objects (plural) vmethod. * subclasses implementing the create_track_objects (plural) vmethod.
* *
* Takes a reference on @trobj.
*
* Returns: %TRUE on success, %FALSE on failure. * Returns: %TRUE on success, %FALSE on failure.
*/ */
@ -359,6 +361,7 @@ ges_timeline_object_add_track_object (GESTimelineObject * object, GESTrackObject
return FALSE; return FALSE;
ges_track_object_set_timeline_object (trobj, object); ges_track_object_set_timeline_object (trobj, object);
g_object_ref (trobj);
mapping = g_slice_new0 (ObjectMapping); mapping = g_slice_new0 (ObjectMapping);
mapping->object = trobj; mapping->object = trobj;
@ -445,6 +448,8 @@ ges_timeline_object_release_track_object (GESTimelineObject * object,
ges_track_object_set_timeline_object (trackobject, NULL); ges_track_object_set_timeline_object (trackobject, NULL);
GST_DEBUG ("Removing reference to track object %p", trackobject);
g_object_unref (trackobject); g_object_unref (trackobject);
/* FIXME : resync properties ? */ /* FIXME : resync properties ? */

View file

@ -107,14 +107,22 @@ GST_START_TEST (test_ges_scenario)
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (source)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (source));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
trackobject = GES_TRACK_OBJECT (trackobjects->data); trackobject = GES_TRACK_OBJECT (trackobjects->data);
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 2); /* There are 3 references:
* 1 by the timelineobject
* 1 by the track
* 1 added by the call to _get_track_objects() above */
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 3);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 1); /* There are 2 references:
* 1 by the timelineobject
* 1 by the track */
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 2);
GST_DEBUG ("Remove the TimelineObject from the layer"); GST_DEBUG ("Remove the TimelineObject from the layer");
/* Now remove the timelineobject */ /* Now remove the timelineobject */
g_object_ref (source); g_object_ref (source);
ASSERT_OBJECT_REFCOUNT (layer, "layer", 1); ASSERT_OBJECT_REFCOUNT (layer, "layer", 1);
@ -229,12 +237,19 @@ GST_START_TEST (test_ges_timeline_add_layer)
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
trackobject = GES_TRACK_OBJECT (trackobjects->data); trackobject = GES_TRACK_OBJECT (trackobjects->data);
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 2); /* There are 3 references:
* 1 by the timelineobject
* 1 by the trackobject
* 1 added by the call to _get_track_objects() above */
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 3);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 1); /* There are 2 references:
* 1 by the timelineobject
* 1 by the trackobject */
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 2);
trackobjects = trackobjects =
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2));
@ -244,7 +259,10 @@ GST_START_TEST (test_ges_timeline_add_layer)
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (trackobject), "trackobject", 1); /* There are 2 references:
* 1 by the timelineobject
* 1 by the trackobject */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (trackobject), "trackobject", 2);
trackobjects = trackobjects =
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3));
@ -254,7 +272,10 @@ GST_START_TEST (test_ges_timeline_add_layer)
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 1); /* There are 2 references:
* 1 by the timelineobject
* 1 by the trackobject */
ASSERT_OBJECT_REFCOUNT (trackobject, "trackobject", 2);
/* theoretically this is all we need to do to ensure cleanup */ /* theoretically this is all we need to do to ensure cleanup */
g_object_unref (timeline); g_object_unref (timeline);
@ -330,7 +351,11 @@ GST_START_TEST (test_ges_timeline_add_layer_first)
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 2); /* Each object has 3 references:
* 1 by the timelineobject
* 1 by the track
* 1 added by _get_track_object() above */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3);
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
@ -339,7 +364,11 @@ GST_START_TEST (test_ges_timeline_add_layer_first)
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 2); /* Each object has 3 references:
* 1 by the timelineobject
* 1 by the track
* 1 added by _get_track_object() above */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3);
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
@ -348,7 +377,11 @@ GST_START_TEST (test_ges_timeline_add_layer_first)
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 2); /* Each object has 3 references:
* 1 by the timelineobject
* 1 by the track
* 1 added by _get_track_object() above */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3);
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_list_free (trackobjects); g_list_free (trackobjects);
@ -426,37 +459,61 @@ GST_START_TEST (test_ges_timeline_remove_track)
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
t1 = GES_TRACK_OBJECT ((trackobjects)->data); t1 = GES_TRACK_OBJECT ((trackobjects)->data);
g_object_ref (t1);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
/* There are 3 references held:
* 1 by the timelineobject
* 1 by the track
* 1 added by the call to _get_track_objects() above */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3); ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3);
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_object_ref (t1);
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (t1, "trackobject", 2); /* There are 3 references held:
* 1 by the timelinobject
* 1 by the track
* 1 added by ourselves above (g_object_ref (t1)) */
ASSERT_OBJECT_REFCOUNT (t1, "trackobject", 3);
trackobjects = trackobjects =
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
t2 = GES_TRACK_OBJECT (trackobjects->data); t2 = GES_TRACK_OBJECT (trackobjects->data);
g_object_ref (t2);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
/* There are 3 references held:
* 1 by the timelineobject
* 1 by the track
* 1 added by the call to _get_track_objects() above */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3); ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3);
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_object_ref (t2);
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (t2, "t2", 2); /* There are 3 references held:
* 1 by the timelinobject
* 1 by the track
* 1 added by ourselves above (g_object_ref (t1)) */
ASSERT_OBJECT_REFCOUNT (t2, "t2", 3);
trackobjects = trackobjects =
ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3)); ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3));
fail_unless (trackobjects != NULL); fail_unless (trackobjects != NULL);
t3 = GES_TRACK_OBJECT (trackobjects->data); t3 = GES_TRACK_OBJECT (trackobjects->data);
g_object_ref (t3);
for (tmp = trackobjects; tmp; tmp = tmp->next) { for (tmp = trackobjects; tmp; tmp = tmp->next) {
/* There are 3 references held:
* 1 by the timelineobject
* 1 by the track
* 1 added by the call to _get_track_objects() above */
ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3); ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 3);
g_object_unref (GES_TRACK_OBJECT (tmp->data)); g_object_unref (GES_TRACK_OBJECT (tmp->data));
} }
g_object_ref (t3);
g_list_free (trackobjects); g_list_free (trackobjects);
ASSERT_OBJECT_REFCOUNT (t3, "t3", 2); /* There are 3 references held:
* 1 by the timelinobject
* 1 by the track
* 1 added by ourselves above (g_object_ref (t1)) */
ASSERT_OBJECT_REFCOUNT (t3, "t3", 3);
/* remove the track and check that the track objects have been released */ /* remove the track and check that the track objects have been released */
fail_unless (ges_timeline_remove_track (timeline, track)); fail_unless (ges_timeline_remove_track (timeline, track));

View file

@ -57,8 +57,9 @@ GST_START_TEST (test_filesource_basic)
track); track);
fail_unless (trackobject != NULL); fail_unless (trackobject != NULL);
/* The track holds a reference to the object */ /* The track holds a reference to the object
ASSERT_OBJECT_REFCOUNT (trackobject, "Track Object", 1); * and the timelineobject holds a reference on the object */
ASSERT_OBJECT_REFCOUNT (trackobject, "Track Object", 2);
fail_unless (ges_timeline_object_release_track_object (GES_TIMELINE_OBJECT fail_unless (ges_timeline_object_release_track_object (GES_TIMELINE_OBJECT
(source), trackobject) == TRUE); (source), trackobject) == TRUE);
@ -175,8 +176,9 @@ GST_START_TEST (test_filesource_images)
trobj = ges_timeline_object_create_track_object (tlobj, v); trobj = ges_timeline_object_create_track_object (tlobj, v);
fail_unless (GES_IS_TRACK_IMAGE_SOURCE (trobj)); fail_unless (GES_IS_TRACK_IMAGE_SOURCE (trobj));
/* The track holds a reference to the object */ /* The track holds a reference to the object
ASSERT_OBJECT_REFCOUNT (trobj, "Video Track Object", 1); * and the timelinobject holds a reference to the object */
ASSERT_OBJECT_REFCOUNT (trobj, "Video Track Object", 2);
ges_track_remove_object (v, trobj); ges_track_remove_object (v, trobj);
ges_timeline_object_release_track_object (tlobj, trobj); ges_timeline_object_release_track_object (tlobj, trobj);
@ -187,8 +189,9 @@ GST_START_TEST (test_filesource_images)
trobj = ges_timeline_object_create_track_object (tlobj, a); trobj = ges_timeline_object_create_track_object (tlobj, a);
fail_unless (GES_IS_TRACK_AUDIO_TEST_SOURCE (trobj)); fail_unless (GES_IS_TRACK_AUDIO_TEST_SOURCE (trobj));
/* The track holds a reference to the object */ /* The track holds a reference to the object
ASSERT_OBJECT_REFCOUNT (trobj, "Audio Track Object", 1); * And the timelineobject holds a reference to the object */
ASSERT_OBJECT_REFCOUNT (trobj, "Audio Track Object", 2);
ges_track_remove_object (v, trobj); ges_track_remove_object (v, trobj);
ges_timeline_object_release_track_object (tlobj, trobj); ges_timeline_object_release_track_object (tlobj, trobj);