From 1adb9a0030129aaa1b6e5cf3f784ed2a2d8eb745 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 18 Feb 2014 15:14:40 +0100 Subject: [PATCH] Add a notion of 'name' in GESTimelineElement https://bugzilla.gnome.org/show_bug.cgi?id=729382 --- docs/libs/ges-sections.txt | 4 + ges/ges-internal.h | 9 +++ ges/ges-timeline-element.c | 159 ++++++++++++++++++++++++++++++++++++-- ges/ges-timeline-element.h | 11 +++ ges/ges-timeline.c | 50 ++++++++++++ ges/ges-timeline.h | 1 + ges/ges-xml-formatter.c | 3 +- tests/check/ges/basic.c | 109 +++++++++++++++----------- tests/check/ges/clip.c | 23 +++--- tests/check/ges/group.c | 4 +- tests/check/ges/layer.c | 42 +++++----- tests/check/ges/timelineedition.c | 42 +++++----- tests/check/ges/uriclip.c | 4 +- 13 files changed, 354 insertions(+), 107 deletions(-) diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index e44b2e5..9ec0ed9 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -369,6 +369,7 @@ ges_timeline_get_auto_transition ges_timeline_set_auto_transition ges_timeline_get_snapping_distance ges_timeline_set_snapping_distance +ges_timeline_get_element GESTimelinePrivate GESTimelineClass @@ -441,6 +442,8 @@ ges_timeline_element_roll_end ges_timeline_element_trim ges_timeline_element_get_toplevel_parent ges_timeline_element_copy +ges_timeline_element_get_name +ges_timeline_element_set_name GES_TIMELINE_ELEMENT_PARENT GES_TIMELINE_ELEMENT_TIMELINE GES_TIMELINE_ELEMENT_START @@ -449,6 +452,7 @@ GES_TIMELINE_ELEMENT_INPOINT GES_TIMELINE_ELEMENT_DURATION GES_TIMELINE_ELEMENT_MAX_DURATION GES_TIMELINE_ELEMENT_PRIORITY +GES_TIMELINE_ELEMENT_NAME GESTimelineElementPrivate ges_timeline_element_get_type diff --git a/ges/ges-internal.h b/ges/ges-internal.h index f09d66a..4aca1d1 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -91,6 +91,15 @@ void timeline_remove_group (GESTimeline *timeline, GESGroup *group); +G_GNUC_INTERNAL +gboolean +timeline_add_element (GESTimeline *timeline, + GESTimelineElement *element); +G_GNUC_INTERNAL +gboolean +timeline_remove_element (GESTimeline *timeline, + GESTimelineElement *element); + G_GNUC_INTERNAL void ges_asset_cache_init (void); diff --git a/ges/ges-timeline-element.c b/ges/ges-timeline-element.c index 585b77e..a702c81 100644 --- a/ges/ges-timeline-element.c +++ b/ges/ges-timeline-element.c @@ -30,6 +30,10 @@ #include "ges-extractable.h" #include "ges-meta-container.h" #include "ges-internal.h" +#include + +/* maps type name quark => count */ +static GData *object_name_counts = NULL; static void extractable_set_asset (GESExtractable * extractable, GESAsset * asset) @@ -58,6 +62,7 @@ enum PROP_DURATION, PROP_MAX_DURATION, PROP_PRIORITY, + PROP_NAME, PROP_LAST }; @@ -96,6 +101,9 @@ _get_property (GObject * object, guint property_id, case PROP_PRIORITY: g_value_set_uint (value, self->priority); break; + case PROP_NAME: + g_value_take_string (value, ges_timeline_element_get_name (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec); } @@ -129,21 +137,23 @@ _set_property (GObject * object, guint property_id, case PROP_MAX_DURATION: ges_timeline_element_set_max_duration (self, g_value_get_uint64 (value)); break; + case PROP_NAME: + ges_timeline_element_set_name (self, g_value_get_string (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec); } } static void -ges_timeline_element_init (GESTimelineElement * ges_timeline_element) +ges_timeline_element_finalize (GObject * self) { - + G_OBJECT_CLASS (ges_timeline_element_parent_class)->finalize (self); } static void -ges_timeline_element_finalize (GObject * self) +ges_timeline_element_init (GESTimelineElement * ges_timeline_element) { - G_OBJECT_CLASS (ges_timeline_element_parent_class)->finalize (self); } static void @@ -216,11 +226,20 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass) /** * GESTimelineElement:priority: * - * The layer priority of the object. + * The priority of the object. */ properties[PROP_PRIORITY] = g_param_spec_uint ("priority", "Priority", "The priority of the object", 0, G_MAXUINT, 0, G_PARAM_READWRITE); + /** + * GESTimelineElement:name: + * + * The name of the object + */ + properties[PROP_NAME] = + g_param_spec_string ("name", "Name", "The name of the timeline object", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, PROP_LAST, properties); object_class->finalize = ges_timeline_element_finalize; @@ -239,6 +258,55 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass) klass->trim = NULL; } +static gboolean +_set_name_default (GESTimelineElement * self) +{ + const gchar *type_name; + gint count; + gchar *name; + GQuark q; + guint i, l; + + if (!object_name_counts) { + g_datalist_init (&object_name_counts); + } + + q = g_type_qname (G_OBJECT_TYPE (self)); + count = GPOINTER_TO_INT (g_datalist_id_get_data (&object_name_counts, q)); + g_datalist_id_set_data (&object_name_counts, q, GINT_TO_POINTER (count + 1)); + + /* GstFooSink -> foosink */ + type_name = g_quark_to_string (q); + if (strncmp (type_name, "GES", 3) == 0) + type_name += 3; + /* give the 20th "uriclip" element and the first "uriclip2" (if needed in the future) + * different names */ + l = strlen (type_name); + if (l > 0 && g_ascii_isdigit (type_name[l - 1])) { + name = g_strdup_printf ("%s-%d", type_name, count); + } else { + name = g_strdup_printf ("%s%d", type_name, count); + } + + l = strlen (name); + for (i = 0; i < l; i++) + name[i] = g_ascii_tolower (name[i]); + + g_free (self->name); + if (G_UNLIKELY (self->parent != NULL)) + goto had_parent; + + self->name = name; + + return TRUE; + +had_parent: + { + GST_WARNING ("parented objects can't be renamed"); + return FALSE; + } +} + /********************************************* * API implementation * *********************************************/ @@ -338,6 +406,16 @@ ges_timeline_element_set_timeline (GESTimelineElement * self, if (timeline != NULL && G_UNLIKELY (self->timeline != NULL)) goto had_timeline; + if (timeline == NULL) { + if (self->timeline) { + if (!timeline_remove_element (self->timeline, self)) + return FALSE; + } + } else { + if (!timeline_add_element (timeline, self)) + return FALSE; + } + self->timeline = timeline; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TIMELINE]); @@ -830,7 +908,10 @@ ges_timeline_element_copy (GESTimelineElement * self, gboolean deep) n_params = 0; for (n = 0; n < n_specs; ++n) { + /* We do not want the timeline or the name to be copied */ if (g_strcmp0 (specs[n]->name, "parent") && + g_strcmp0 (specs[n]->name, "timeline") && + g_strcmp0 (specs[n]->name, "name") && (specs[n]->flags & G_PARAM_READWRITE) == G_PARAM_READWRITE) { params[n_params].name = g_intern_string (specs[n]->name); g_value_init (¶ms[n_params].value, specs[n]->value_type); @@ -880,3 +961,71 @@ ges_timeline_element_get_toplevel_parent (GESTimelineElement * self) return gst_object_ref (toplevel); } + +/** + * ges_timeline_element_get_name: + * @self: a #GESTimelineElement + * + * + * Returns a copy of the name of @self. + * Caller should g_free() the return value after usage. + * + * Returns: (transfer full): The name of @self + */ +gchar * +ges_timeline_element_get_name (GESTimelineElement * self) +{ + g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL); + + return g_strdup (self->name); +} + +/** + * ges_timeline_element_set_name: + * @self: a #GESTimelineElement + * + * + * Sets the name of object, or gives @self a guaranteed unique name (if name is NULL). + * This function makes a copy of the provided name, so the caller retains ownership + * of the name it sent. + */ +gboolean +ges_timeline_element_set_name (GESTimelineElement * self, const gchar * name) +{ + gboolean result, readd_to_timeline = FALSE; + + g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE); + + /* parented objects cannot be renamed */ + if (self->timeline != NULL) { + GESTimelineElement *tmp = ges_timeline_get_element (self->timeline, name); + + if (tmp) { + gst_object_unref (tmp); + goto had_timeline; + } + + timeline_remove_element (self->timeline, self); + readd_to_timeline = TRUE; + } + + if (name != NULL) { + g_free (self->name); + self->name = g_strdup (name); + result = TRUE; + } else { + result = _set_name_default (self); + } + + if (readd_to_timeline) + timeline_add_element (self->timeline, self); + + return result; + + /* error */ +had_timeline: + { + GST_WARNING ("Objects already in a timeline can't be renamed"); + return FALSE; + } +} diff --git a/ges/ges-timeline-element.h b/ges/ges-timeline-element.h index c8cfda8..d787d66 100644 --- a/ges/ges-timeline-element.h +++ b/ges/ges-timeline-element.h @@ -101,6 +101,14 @@ typedef struct _GESTimelineElementPrivate GESTimelineElementPrivate; #define GES_TIMELINE_ELEMENT_TIMELINE(obj) (((GESTimelineElement*)obj)->timeline) /** + * GES_TIMELINE_ELEMENT_NAME: + * @obj: a #GESTimelineElement + * + * The name of the object. + */ +#define GES_TIMELINE_ELEMENT_NAME(obj) (((GESTimelineElement*)obj)->name) + +/** * GESTimelineElement: * @parent: The #GESTimelineElement that controls the object * @asset: The #GESAsset from which the object has been extracted @@ -128,6 +136,7 @@ struct _GESTimelineElement GstClockTime maxduration; guint32 priority; GESTimeline *timeline; + gchar *name; /*< private >*/ GESTimelineElementPrivate *priv; @@ -209,6 +218,8 @@ gboolean ges_timeline_element_roll_start (GESTimelineElement *self, gboolean ges_timeline_element_roll_end (GESTimelineElement *self, GstClockTime end); gboolean ges_timeline_element_trim (GESTimelineElement *self, GstClockTime start); GESTimelineElement * ges_timeline_element_copy (GESTimelineElement *self, gboolean deep); +gchar * ges_timeline_element_get_name (GESTimelineElement *self); +gboolean ges_timeline_element_set_name (GESTimelineElement *self, const gchar *name); G_END_DECLS diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index e8090dc..ae807ad 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -187,6 +187,8 @@ struct _GESTimelinePrivate GList *groups; guint group_id; + + GHashTable *all_elements; }; /* private structure to contain our track-related information */ @@ -557,6 +559,9 @@ ges_timeline_init (GESTimeline * self) g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gst_object_unref); priv->needs_transitions_update = TRUE; + priv->all_elements = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, gst_object_unref); + priv->group_id = -1; g_signal_connect_after (self, "select-tracks-for-object", @@ -2387,6 +2392,27 @@ pad_removed_cb (GESTrack * track, GstPad * pad, TrackPrivate * tr_priv) tr_priv->pad = NULL; } +gboolean +timeline_add_element (GESTimeline * timeline, GESTimelineElement * element) +{ + GST_DEBUG_OBJECT (timeline, "Adding element: %s", element->name); + if (g_hash_table_contains (timeline->priv->all_elements, element->name)) { + GST_WARNING_OBJECT (timeline, "Already in %s the timeline", element->name); + return FALSE; + } + + g_hash_table_insert (timeline->priv->all_elements, + ges_timeline_element_get_name (element), gst_object_ref (element)); + + return TRUE; +} + +gboolean +timeline_remove_element (GESTimeline * timeline, GESTimelineElement * element) +{ + return g_hash_table_remove (timeline->priv->all_elements, element->name); +} + /**** API *****/ /** * ges_timeline_new: @@ -3027,3 +3053,27 @@ ges_timeline_set_snapping_distance (GESTimeline * timeline, timeline->priv->snapping_distance = snapping_distance; } + +/** + * ges_timeline_get_element: + * @timeline: a #GESTimeline + * + * Gets a #GESTimelineElement contained in the timeline + * + * Returns: (transfer full): The #GESTimelineElement or %NULL if + * not found. + */ +GESTimelineElement * +ges_timeline_get_element (GESTimeline * timeline, const gchar * name) +{ + GESTimelineElement *ret; + + g_return_val_if_fail (GES_IS_TIMELINE (timeline), NULL); + + ret = g_hash_table_lookup (timeline->priv->all_elements, name); + + if (ret) + return gst_object_ref (ret); + + return NULL; +} diff --git a/ges/ges-timeline.h b/ges/ges-timeline.h index dbd6f25..709fbf2 100644 --- a/ges/ges-timeline.h +++ b/ges/ges-timeline.h @@ -124,6 +124,7 @@ gboolean ges_timeline_get_auto_transition (GESTimeline * timeline); void ges_timeline_set_auto_transition (GESTimeline * timeline, gboolean auto_transition); GstClockTime ges_timeline_get_snapping_distance (GESTimeline * timeline); void ges_timeline_set_snapping_distance (GESTimeline * timeline, GstClockTime snapping_distance); +GESTimelineElement * ges_timeline_get_element (GESTimeline * timeline, const gchar *name); G_END_DECLS diff --git a/ges/ges-xml-formatter.c b/ges/ges-xml-formatter.c index 979f01d..b2ffcc6 100644 --- a/ges/ges-xml-formatter.c +++ b/ges/ges-xml-formatter.c @@ -702,7 +702,8 @@ _can_serialize_spec (GParamSpec * spec) { if (spec->flags & G_PARAM_WRITABLE && !(spec->flags & G_PARAM_CONSTRUCT_ONLY) && !g_type_is_a (G_PARAM_SPEC_VALUE_TYPE (spec), G_TYPE_OBJECT) - && g_strcmp0 (spec->name, "name") + && (!(g_type_is_a (spec->owner_type, GST_TYPE_OBJECT) && + !g_strcmp0 (spec->name, "name"))) && G_PARAM_SPEC_VALUE_TYPE (spec) != G_TYPE_GTYPE) return TRUE; diff --git a/tests/check/ges/basic.c b/tests/check/ges/basic.c index 26bd00c..15bedb9 100644 --- a/tests/check/ges/basic.c +++ b/tests/check/ges/basic.c @@ -90,7 +90,7 @@ GST_START_TEST (test_ges_scenario) tmp_layer = ges_clip_get_layer (GES_CLIP (source)); fail_unless (tmp_layer == layer); /* The timeline stole our reference */ - ASSERT_OBJECT_REFCOUNT (source, "source", 1); + ASSERT_OBJECT_REFCOUNT (source, "source + 1 timeline", 2); gst_object_unref (tmp_layer); ASSERT_OBJECT_REFCOUNT (layer, "layer", 1); @@ -101,13 +101,13 @@ GST_START_TEST (test_ges_scenario) /* There are 3 references: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4); /* There are 3 references: * 1 by the clip - * 1 by the timeline + * 2 by the timeline * 1 by the track */ - ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3); + ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4); GST_DEBUG ("Remove the Clip from the layer"); @@ -232,13 +232,13 @@ GST_START_TEST (test_ges_timeline_add_layer) /* There are 3 references: * 1 by the clip * 1 by the trackelement - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4); /* There are 3 references: * 1 by the clip * 1 by the timeline - * 1 by the trackelement */ - ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3); + * 2 by the trackelement */ + ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4); trackelements = GES_CONTAINER_CHILDREN (s2); trackelement = GES_TRACK_ELEMENT (trackelements->data); @@ -247,8 +247,8 @@ GST_START_TEST (test_ges_timeline_add_layer) /* There are 3 references: * 1 by the clip * 1 by the timeline - * 1 by the trackelement */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (trackelement), "trackelement", 3); + * 2 by the trackelement */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (trackelement), "trackelement", 4); trackelements = GES_CONTAINER_CHILDREN (s3); trackelement = GES_TRACK_ELEMENT (trackelements->data); @@ -257,8 +257,8 @@ GST_START_TEST (test_ges_timeline_add_layer) /* There are 3 references: * 1 by the clip * 1 by the timeline - * 1 by the trackelement */ - ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 3); + * 2 by the trackelement */ + ASSERT_OBJECT_REFCOUNT (trackelement, "trackelement", 4); /* theoretically this is all we need to do to ensure cleanup */ gst_object_unref (timeline); @@ -339,8 +339,8 @@ GST_START_TEST (test_ges_timeline_add_layer_first) /* Each object has 3 references: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); } trackelements = GES_CONTAINER_CHILDREN (s2); @@ -349,8 +349,8 @@ GST_START_TEST (test_ges_timeline_add_layer_first) /* Each object has 3 references: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); } trackelements = GES_CONTAINER_CHILDREN (s3); @@ -359,8 +359,8 @@ GST_START_TEST (test_ges_timeline_add_layer_first) /* Each object has 3 references: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); } /* theoretically this is all we need to do to ensure cleanup */ @@ -447,14 +447,14 @@ GST_START_TEST (test_ges_timeline_remove_track) /* There are 3 references held: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); } /* There are 3 references held: * 1 by the container * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 4); trackelements = GES_CONTAINER_CHILDREN (s2); fail_unless (trackelements != NULL); @@ -463,14 +463,14 @@ GST_START_TEST (test_ges_timeline_remove_track) /* There are 3 references held: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); } /* There are 3 references held: * 1 by the container * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (t2, "t2", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (t2, "t2", 4); trackelements = GES_CONTAINER_CHILDREN (s3); fail_unless (trackelements != NULL); @@ -479,14 +479,14 @@ GST_START_TEST (test_ges_timeline_remove_track) /* There are 3 references held: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); } /* There are 3 references held: * 1 by the container * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (t3, "t3", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (t3, "t3", 4); /* remove the track and check that the track elements have been released */ fail_unless (ges_timeline_remove_track (timeline, track)); @@ -613,17 +613,17 @@ GST_START_TEST (test_ges_timeline_multiple_tracks) /* There are 3 references held: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); fail_unless (ges_track_element_get_track (tmp->data) == track1); } gst_object_ref (t1); /* There are 3 references held: * 1 by the container * 1 by the track - * 1 by the timeline + * 2 by the timeline * 1 added by ourselves above (gst_object_ref (t1)) */ - ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 4); + ASSERT_OBJECT_REFCOUNT (t1, "trackelement", 5); trackelements = GES_CONTAINER_CHILDREN (s2); fail_unless (trackelements != NULL); @@ -632,17 +632,17 @@ GST_START_TEST (test_ges_timeline_multiple_tracks) /* There are 3 references held: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); fail_unless (ges_track_element_get_track (tmp->data) == track2); } gst_object_ref (t2); /* There are 3 references held: * 1 by the container * 1 by the track - * 1 by the timeline + * 2 by the timeline * 1 added by ourselves above (gst_object_ref (t2)) */ - ASSERT_OBJECT_REFCOUNT (t2, "t2", 4); + ASSERT_OBJECT_REFCOUNT (t2, "t2", 5); trackelements = GES_CONTAINER_CHILDREN (s3); fail_unless (trackelements != NULL); @@ -651,17 +651,17 @@ GST_START_TEST (test_ges_timeline_multiple_tracks) /* There are 3 references held: * 1 by the clip * 1 by the track - * 1 by the timeline */ - ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 3); + * 2 by the timeline */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_ELEMENT (tmp->data), "trackelement", 4); fail_unless (ges_track_element_get_track (tmp->data) == track1); } gst_object_ref (t3); /* There are 3 references held: * 1 by the container * 1 by the track - * 1 by the timeline + * 2 by the timeline * 1 added by ourselves above (gst_object_ref (t3)) */ - ASSERT_OBJECT_REFCOUNT (t3, "t3", 4); + ASSERT_OBJECT_REFCOUNT (t3, "t3", 5); gst_object_unref (t1); gst_object_unref (t2); @@ -706,6 +706,28 @@ GST_START_TEST (test_ges_pipeline_change_state) GST_END_TEST; +GST_START_TEST (test_ges_timeline_element_name) +{ + GESClip *clip; + GESAsset *asset; + GESTimeline *timeline; + GESLayer *layer; + + ges_init (); + + timeline = ges_timeline_new_audio_video (); + layer = ges_layer_new (); + fail_unless (ges_timeline_add_layer (timeline, layer)); + + asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL); + clip = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN); + gst_object_unref (asset); + + fail_unless_equals_string (GES_TIMELINE_ELEMENT_NAME (clip), "testclip0"); +} + +GST_END_TEST; + static Suite * ges_suite (void) { @@ -721,6 +743,7 @@ ges_suite (void) tcase_add_test (tc_chain, test_ges_timeline_remove_track); tcase_add_test (tc_chain, test_ges_timeline_multiple_tracks); tcase_add_test (tc_chain, test_ges_pipeline_change_state); + tcase_add_test (tc_chain, test_ges_timeline_element_name); return s; } diff --git a/tests/check/ges/clip.c b/tests/check/ges/clip.c index bd65246..aa539d9 100644 --- a/tests/check/ges/clip.c +++ b/tests/check/ges/clip.c @@ -181,9 +181,11 @@ GST_START_TEST (test_split_object) fail_unless (splitclip != clip); /* We own the only ref */ - ASSERT_OBJECT_REFCOUNT (splitclip, "splitclip", 1); - /* 1 ref for the Clip, 1 ref for the Track and 1 ref for the timeline */ - ASSERT_OBJECT_REFCOUNT (splittrackelement, "splittrackelement", 3); + ASSERT_OBJECT_REFCOUNT (splitclip, "1 ref for us + 1 for the timeline", 2); + /* 1 ref for the Clip, 1 ref for the Track and 2 ref for the timeline + * (1 for the "all_element" hashtable, another for the sequence of TrackElement*/ + ASSERT_OBJECT_REFCOUNT (splittrackelement, + "1 ref for the Clip, 1 ref for the Track and 2 ref for the timeline", 4); check_destroyed (G_OBJECT (timeline), G_OBJECT (splitclip), clip, splittrackelement, NULL); @@ -216,7 +218,7 @@ GST_START_TEST (test_clip_group_ungroup) assert_is_type (asset, GES_TYPE_ASSET); clip = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN); - ASSERT_OBJECT_REFCOUNT (clip, "1 layer", 1); + ASSERT_OBJECT_REFCOUNT (clip, "1 layer + 1 timeline.all_elements", 2); assert_equals_uint64 (_START (clip), 0); assert_equals_uint64 (_INPOINT (clip), 0); assert_equals_uint64 (_DURATION (clip), 10); @@ -229,20 +231,23 @@ GST_START_TEST (test_clip_group_ungroup) assert_equals_uint64 (_START (clip), 0); assert_equals_uint64 (_INPOINT (clip), 0); assert_equals_uint64 (_DURATION (clip), 10); - ASSERT_OBJECT_REFCOUNT (clip, "1 for the layer + 1 in containers list", 2); + ASSERT_OBJECT_REFCOUNT (clip, "1 for the layer + 1 for the timeline + " + "1 in containers list", 3); clip2 = containers->next->data; fail_if (clip2 == clip); + fail_unless (GES_TIMELINE_ELEMENT_TIMELINE (clip2) != NULL); assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip2)), 1); assert_equals_uint64 (_START (clip2), 0); assert_equals_uint64 (_INPOINT (clip2), 0); assert_equals_uint64 (_DURATION (clip2), 10); - ASSERT_OBJECT_REFCOUNT (clip2, "1 for the layer + 1 in containers list", 2); + ASSERT_OBJECT_REFCOUNT (clip2, "1 for the layer + 1 for the timeline +" + " 1 in containers list", 3); tmp = ges_track_get_elements (audio_track); assert_equals_int (g_list_length (tmp), 1); ASSERT_OBJECT_REFCOUNT (tmp->data, "1 for the track + 1 for the container " - "+ 1 for the timeline + 1 in tmp list", 4); + "+ 2 for the timeline + 1 in tmp list", 5); assert_equals_int (ges_track_element_get_track_type (tmp->data), GES_TRACK_TYPE_AUDIO); assert_equals_int (ges_clip_get_supported_formats (GES_CLIP @@ -251,7 +256,7 @@ GST_START_TEST (test_clip_group_ungroup) tmp = ges_track_get_elements (video_track); assert_equals_int (g_list_length (tmp), 1); ASSERT_OBJECT_REFCOUNT (tmp->data, "1 for the track + 1 for the container " - "+ 1 for the timeline + 1 in tmp list", 4); + "+ 2 for the timeline + 1 in tmp list", 5); assert_equals_int (ges_track_element_get_track_type (tmp->data), GES_TRACK_TYPE_VIDEO); assert_equals_int (ges_clip_get_supported_formats (GES_CLIP @@ -302,7 +307,7 @@ GST_START_TEST (test_clip_group_ungroup) tmp = ges_track_get_elements (video_track); assert_equals_int (g_list_length (tmp), 1); ASSERT_OBJECT_REFCOUNT (tmp->data, "1 for the track + 1 for the container " - "+ 1 for the timeline + 1 in tmp list", 4); + "+ 2 for the timeline + 1 in tmp list", 5); assert_equals_int (ges_track_element_get_track_type (tmp->data), GES_TRACK_TYPE_VIDEO); fail_unless (GES_CONTAINER (ges_timeline_element_get_parent (tmp->data)) == diff --git a/tests/check/ges/group.c b/tests/check/ges/group.c index c7c0a2a..f8b588d 100644 --- a/tests/check/ges/group.c +++ b/tests/check/ges/group.c @@ -66,7 +66,7 @@ GST_START_TEST (test_move_group) g_list_free (clips); fail_unless (GES_IS_GROUP (group)); - ASSERT_OBJECT_REFCOUNT (group, "1 ref for the timeline", 1); + ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); fail_unless (g_list_length (GES_CONTAINER_CHILDREN (group)) == 3); assert_equals_int (GES_CONTAINER_HEIGHT (group), 2); @@ -299,7 +299,7 @@ GST_START_TEST (test_move_group) CHECK_OBJECT_PROPS (clip2, 55, 0, 65); CHECK_OBJECT_PROPS (group, 10, 0, 110); - ASSERT_OBJECT_REFCOUNT (group, "1 ref for the timeline", 1); + ASSERT_OBJECT_REFCOUNT (group, "2 ref for the timeline", 2); check_destroyed (G_OBJECT (timeline), G_OBJECT (group), NULL); gst_object_unref (asset); } diff --git a/tests/check/ges/layer.c b/tests/check/ges/layer.c index 6721b92..032e2b1 100644 --- a/tests/check/ges/layer.c +++ b/tests/check/ges/layer.c @@ -394,7 +394,7 @@ GST_START_TEST (test_single_layer_automatic_transition) assert_equals_uint64 (_START (transition), 500); assert_equals_uint64 (_DURATION (transition), 500); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Moving first source to 250"); ges_timeline_element_set_start (src, 250); @@ -579,14 +579,14 @@ GST_START_TEST (test_single_layer_automatic_transition) assert_is_type (transition, GES_TYPE_TRANSITION_CLIP); assert_equals_uint64 (_START (transition), 600); assert_equals_uint64 (_DURATION (transition), 1250 - 600); - ASSERT_OBJECT_REFCOUNT (transition, "The layer and ourself own a ref", 2); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3); current = current->next; transition = current->data; assert_is_type (transition, GES_TYPE_TRANSITION_CLIP); assert_equals_uint64 (_START (transition), 600); assert_equals_uint64 (_DURATION (transition), 1250 - 600); - ASSERT_OBJECT_REFCOUNT (transition, "The layer and ourself own a ref", 2); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3); current = current->next; fail_unless (current->data == src); @@ -596,14 +596,14 @@ GST_START_TEST (test_single_layer_automatic_transition) assert_is_type (transition, GES_TYPE_TRANSITION_CLIP); assert_equals_uint64 (_START (transition), 1250); assert_equals_uint64 (_DURATION (transition), 1400 - 1250); - ASSERT_OBJECT_REFCOUNT (transition, "The layer and ourself own a ref", 2); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3); current = current->next; transition = current->data; assert_is_type (transition, GES_TYPE_TRANSITION_CLIP); assert_equals_uint64 (_START (transition), 1250); assert_equals_uint64 (_DURATION (transition), 1400 - 1250); - ASSERT_OBJECT_REFCOUNT (transition, "The layer and ourself own a ref", 2); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline + ourself", 3); current = current->next; fail_unless (current->data == src2); @@ -806,7 +806,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) assert_equals_uint64 (_START (transition), 500); assert_equals_uint64 (_DURATION (transition), 500); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Adding clip 2 from 500 -- 1000 to second layer"); src2 = GES_TIMELINE_ELEMENT (ges_layer_add_asset (layer1, asset, 0, @@ -850,7 +850,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) assert_equals_uint64 (_START (transition), 500); assert_equals_uint64 (_DURATION (transition), 500); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking transitions on second layer"); current = objects = ges_layer_get_clips (layer1); @@ -898,7 +898,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) assert_equals_uint64 (_START (transition), 500); assert_equals_uint64 (_DURATION (transition), 500); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking transitions has been added on second layer"); current = objects = ges_layer_get_clips (layer1); @@ -917,7 +917,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) assert_equals_uint64 (_START (transition), 500); assert_equals_uint64 (_DURATION (transition), 500); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Moving src3 to 1000. should remove transition"); ges_timeline_element_set_start (src3, 1000); @@ -956,7 +956,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) assert_equals_uint64 (_START (transition), 500); assert_equals_uint64 (_DURATION (transition), 500); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking transitions has been removed on second layer"); current = objects = ges_layer_get_clips (layer1); @@ -964,7 +964,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) fail_unless (current->data == src2); fail_unless (current->next->data == src3); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Moving src3 to first layer, should add a transition"); ges_clip_move_to_layer (GES_CLIP (src3), layer); @@ -1023,14 +1023,14 @@ GST_START_TEST (test_multi_layer_automatic_transition) fail_unless (current->data == src3); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking second layer"); current = objects = ges_layer_get_clips (layer1); assert_equals_int (g_list_length (objects), 1); fail_unless (current->data == src2); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Moving src to second layer, should remove first transition on first layer"); @@ -1073,7 +1073,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) current = current->next; fail_unless (current->data == src3); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking second layer"); current = objects = ges_layer_get_clips (layer1); @@ -1081,7 +1081,7 @@ GST_START_TEST (test_multi_layer_automatic_transition) assert_is_type (current->data, GES_TYPE_TEST_CLIP); assert_is_type (current->next->data, GES_TYPE_TEST_CLIP); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Edit src to first layer start=1500"); ges_container_edit (GES_CONTAINER (src), NULL, 0, @@ -1139,14 +1139,14 @@ GST_START_TEST (test_multi_layer_automatic_transition) current = current->next; fail_unless (current->data == src); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking second layer"); current = objects = ges_layer_get_clips (layer1); assert_equals_int (g_list_length (objects), 1); assert_is_type (current->data, GES_TYPE_TEST_CLIP); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Ripple src1 to 700"); ges_container_edit (GES_CONTAINER (src1), NULL, 0, @@ -1204,14 +1204,14 @@ GST_START_TEST (test_multi_layer_automatic_transition) current = current->next; fail_unless (current->data == src); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Checking second layer"); current = objects = ges_layer_get_clips (layer1); assert_equals_int (g_list_length (objects), 1); assert_is_type (current->data, GES_TYPE_TEST_CLIP); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); gst_object_unref (timeline); } @@ -1368,7 +1368,7 @@ GST_START_TEST (test_layer_activate_automatic_transition) current = current->next; fail_unless (current->data == src3); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); GST_DEBUG ("Moving src2 to 1200, check everything updates properly"); ges_timeline_element_set_start (src2, 1200); @@ -1441,7 +1441,7 @@ GST_START_TEST (test_layer_activate_automatic_transition) current = current->next; fail_unless (current->data == src3); g_list_free_full (objects, gst_object_unref); - ASSERT_OBJECT_REFCOUNT (transition, "Only the layer owns a ref", 1); + ASSERT_OBJECT_REFCOUNT (transition, "layer + timeline", 2); gst_object_unref (timeline); diff --git a/tests/check/ges/timelineedition.c b/tests/check/ges/timelineedition.c index 66560a6..c448a0b 100644 --- a/tests/check/ges/timelineedition.c +++ b/tests/check/ges/timelineedition.c @@ -290,12 +290,8 @@ GST_START_TEST (test_snapping) fail_unless (ges_track_element_get_track (trackelement) == track); assert_equals_uint64 (_DURATION (trackelement), 37); - /* We have 3 references to trackelement from: - * track + timeline + clip */ - ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3); - /* We have 1 ref to clip1: - * + layer */ - ASSERT_OBJECT_REFCOUNT (clip, "First clip", 1); + ASSERT_OBJECT_REFCOUNT (trackelement, "track + timeline + clip", 4); + ASSERT_OBJECT_REFCOUNT (clip, "layer + timeline", 2); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip1))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip1)) != NULL); @@ -305,8 +301,8 @@ GST_START_TEST (test_snapping) assert_equals_uint64 (_DURATION (trackelement1), 15); /* Same ref logic */ - ASSERT_OBJECT_REFCOUNT (trackelement1, "First trackelement", 3); - ASSERT_OBJECT_REFCOUNT (clip1, "First clip", 1); + ASSERT_OBJECT_REFCOUNT (trackelement1, "First trackelement", 4); + ASSERT_OBJECT_REFCOUNT (clip1, "First clip", 2); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip2))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip2)) != NULL); @@ -316,8 +312,8 @@ GST_START_TEST (test_snapping) assert_equals_uint64 (_DURATION (trackelement2), 60); /* Same ref logic */ - ASSERT_OBJECT_REFCOUNT (trackelement2, "First trackelement", 3); - ASSERT_OBJECT_REFCOUNT (clip2, "First clip", 1); + ASSERT_OBJECT_REFCOUNT (trackelement2, "First trackelement", 4); + ASSERT_OBJECT_REFCOUNT (clip2, "First clip", 2); /* Snaping to edge, so no move */ g_object_set (timeline, "snapping-distance", (guint64) 3, NULL); @@ -461,12 +457,12 @@ GST_START_TEST (test_snapping) CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60); /* Check we didn't lose/screwed any references */ - ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3); - ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 3); - ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 3); - ASSERT_OBJECT_REFCOUNT (clip, "First clip", 1); - ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 1); - ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 1); + ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 4); + ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 4); + ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 4); + ASSERT_OBJECT_REFCOUNT (clip, "First clip", 2); + ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 2); + ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 2); check_destroyed (G_OBJECT (timeline), G_OBJECT (trackelement), trackelement1, trackelement2, clip, clip1, clip2, layer, NULL); @@ -817,14 +813,12 @@ GST_START_TEST (test_timeline_edition_mode) /* We have 3 references: * track + timeline + clip */ - ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3); - ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 3); - ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 3); - /* We have 1 ref: - * + layer */ - ASSERT_OBJECT_REFCOUNT (clip, "First clip", 1); - ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 1); - ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 1); + ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 4); + ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 4); + ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 4); + ASSERT_OBJECT_REFCOUNT (clip, "First clip", 2); + ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 2); + ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 2); /* Ripple clip end to 52 * New timeline: diff --git a/tests/check/ges/uriclip.c b/tests/check/ges/uriclip.c index 81a7016..e624c3b 100644 --- a/tests/check/ges/uriclip.c +++ b/tests/check/ges/uriclip.c @@ -257,8 +257,8 @@ GST_START_TEST (test_filesource_images) fail_unless (ges_track_element_get_track (track_element) == v); fail_unless (GES_IS_IMAGE_SOURCE (track_element)); - ASSERT_OBJECT_REFCOUNT (track_element, "1 in track, 1 in clip 1 in timeline", - 3); + ASSERT_OBJECT_REFCOUNT (track_element, "1 in track, 1 in clip 2 in timeline", + 4); gst_object_unref (timeline); } -- 2.7.4