diff --git a/ges/ges-custom-timeline-source.c b/ges/ges-custom-timeline-source.c index fa019d931b..a6dcfe484f 100644 --- a/ges/ges-custom-timeline-source.c +++ b/ges/ges-custom-timeline-source.c @@ -136,9 +136,9 @@ ges_custom_timeline_source_fill_track_object (GESTimelineObject * object, static GESTrackObject * ges_custom_timeline_source_create_track_object (GESTimelineObject * obj, - GESTrack * track) + GESTrackType type) { - return g_object_new (GES_TYPE_TRACK_SOURCE, NULL); + return g_object_new (GES_TYPE_TRACK_SOURCE, "track-type", type, NULL); } static void diff --git a/ges/ges-pitivi-formatter.c b/ges/ges-pitivi-formatter.c index 1e07f76960..c9c551eca0 100644 --- a/ges/ges-pitivi-formatter.c +++ b/ges/ges-pitivi-formatter.c @@ -905,6 +905,8 @@ make_source (GESFormatter * self, GList * reflist, GHashTable * source_table) effect = ges_track_parse_launch_effect_new ((gchar *) g_hash_table_lookup (props_table, (gchar *) "effect_name")); + ges_track_object_set_track_type (GES_TRACK_OBJECT (effect), + (video ? GES_TRACK_TYPE_VIDEO : GES_TRACK_TYPE_AUDIO)); effect_table = g_hash_table_lookup (props_table, (gchar *) "effect_props"); diff --git a/ges/ges-timeline-file-source.c b/ges/ges-timeline-file-source.c index 40ee945297..fb6d92dc9d 100644 --- a/ges/ges-timeline-file-source.c +++ b/ges/ges-timeline-file-source.c @@ -64,7 +64,7 @@ enum static GESTrackObject * ges_timeline_filesource_create_track_object (GESTimelineObject * obj, - GESTrack * track); + GESTrackType type); void ges_timeline_filesource_set_uri (GESTimelineFileSource * self, gchar * uri); @@ -401,32 +401,34 @@ ges_timeline_filesource_get_uri (GESTimelineFileSource * self) static GESTrackObject * ges_timeline_filesource_create_track_object (GESTimelineObject * obj, - GESTrack * track) + GESTrackType type) { GESTimelineFileSourcePrivate *priv = GES_TIMELINE_FILE_SOURCE (obj)->priv; GESTrackObject *res; if (priv->is_image) { - if (track->type != GES_TRACK_TYPE_VIDEO) { + if (type != GES_TRACK_TYPE_VIDEO) { GST_DEBUG ("Object is still image, not adding any audio source"); return NULL; } else { GST_DEBUG ("Creating a GESTrackImageSource"); res = (GESTrackObject *) ges_track_image_source_new (priv->uri); } - } - else { + } else { GST_DEBUG ("Creating a GESTrackFileSource"); /* FIXME : Implement properly ! */ res = (GESTrackObject *) ges_track_filesource_new (priv->uri); /* If mute and track is audio, deactivate the track object */ - if (track->type == GES_TRACK_TYPE_AUDIO && priv->mute) + if (type == GES_TRACK_TYPE_AUDIO && priv->mute) ges_track_object_set_active (res, FALSE); } + if (res) + ges_track_object_set_track_type (res, type); + return res; } diff --git a/ges/ges-timeline-object.c b/ges/ges-timeline-object.c index 237d4d020b..1696fb66d6 100644 --- a/ges/ges-timeline-object.c +++ b/ges/ges-timeline-object.c @@ -1,6 +1,8 @@ /* GStreamer Editing Services * Copyright (C) 2009 Edward Hervey * 2009 Nokia Corporation + * 2012 Collabora Ltd. + * Author: Sebastian Dröge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -39,9 +41,8 @@ gboolean ges_timeline_object_fill_track_object_func (GESTimelineObject * object, GESTrackObject * trackobj, GstElement * gnlobj); -gboolean -ges_timeline_object_create_track_objects_func (GESTimelineObject - * object, GESTrack * track); +GList *ges_timeline_object_create_track_objects_func (GESTimelineObject + * object, GESTrackType type); void default_set_max_duration (GESTimelineObject * object, guint64 maxduration); @@ -244,6 +245,7 @@ ges_timeline_object_class_init (GESTimelineObjectClass * klass) object_class->set_property = ges_timeline_object_set_property; klass->create_track_objects = ges_timeline_object_create_track_objects_func; klass->set_max_duration = default_set_max_duration; + klass->create_track_object = NULL; klass->track_object_added = NULL; klass->track_object_released = NULL; @@ -453,30 +455,28 @@ ges_meta_container_interface_init (GESMetaContainerInterface * iface) /** * ges_timeline_object_create_track_object: * @object: The origin #GESTimelineObject - * @track: The #GESTrack to create a #GESTrackObject for. + * @type: The #GESTrackType to create a #GESTrackObject for. * - * Creates a #GESTrackObject for the provided @track. The timeline object + * Creates a #GESTrackObject for the provided @type. The timeline object * keep a reference to the newly created trackobject, you therefore need to * call @ges_timeline_object_release_track_object when you are done with it. * * Returns: (transfer none): A #GESTrackObject. Returns NULL if the #GESTrackObject could not * be created. */ - GESTrackObject * ges_timeline_object_create_track_object (GESTimelineObject * object, - GESTrack * track) + GESTrackType type) { GESTimelineObjectClass *class; GESTrackObject *res; g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), NULL); - g_return_val_if_fail (GES_IS_TRACK (track), NULL); - if (!(track->type & object->priv->supportedformats)) { - GST_DEBUG ("We don't support this track format (supported: %i caps %" - GST_PTR_FORMAT ")", object->priv->supportedformats, - ges_track_get_caps (track)); + GST_DEBUG_OBJECT (object, "Creating track object for %s", + ges_track_type_name (type)); + if (!(type & object->priv->supportedformats)) { + GST_DEBUG_OBJECT (object, "We don't support this track type %i", type); return NULL; } @@ -487,7 +487,7 @@ ges_timeline_object_create_track_object (GESTimelineObject * object, return NULL; } - res = class->create_track_object (object, track); + res = class->create_track_object (object, type); return res; } @@ -495,34 +495,34 @@ ges_timeline_object_create_track_object (GESTimelineObject * object, /** * ges_timeline_object_create_track_objects: * @object: The origin #GESTimelineObject - * @track: The #GESTrack to create each #GESTrackObject for. + * @type: The #GESTrackType to create each #GESTrackObject for. * - * Creates all #GESTrackObjects supported by this object and adds them to the - * provided track. The track is responsible for calling - * #ges_timeline_release_track_object on these objects when it is finished - * with them. + * Creates all #GESTrackObjects supported by this object provided track. + * The track is responsible for calling #ges_timeline_release_track_object + * on these objects when it is finished with them. * - * Returns: %TRUE if each track object was created successfully, or %FALSE if an - * error occured. + * Returns: (element-type GESTrackObject) (transfer-full): A #GList of + * newly created #GESTrackObject-s */ -gboolean +GList * ges_timeline_object_create_track_objects (GESTimelineObject * object, - GESTrack * track) + GESTrackType type) { GESTimelineObjectClass *klass; - g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), FALSE); - g_return_val_if_fail (GES_IS_TRACK (track), FALSE); + g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), NULL); klass = GES_TIMELINE_OBJECT_GET_CLASS (object); if (!(klass->create_track_objects)) { GST_WARNING ("no GESTimelineObject::create_track_objects implentation"); - return FALSE; + return NULL; } - return klass->create_track_objects (object, track); + GST_DEBUG_OBJECT (object, "Creating TrackObjects for type: %s", + ges_track_type_name (type)); + return klass->create_track_objects (object, type); } /* Default implementation of default_set_max_duration */ @@ -537,22 +537,21 @@ default_set_max_duration (GESTimelineObject * object, guint64 maxduration) /* * default implementation of GESTimelineObjectClass::create_track_objects */ -gboolean +GList * ges_timeline_object_create_track_objects_func (GESTimelineObject * object, - GESTrack * track) + GESTrackType type) { GESTrackObject *result; - result = ges_timeline_object_create_track_object (object, track); + GST_DEBUG_OBJECT (object, "Creating trackobject for track: %s", + ges_track_type_name (type)); + result = ges_timeline_object_create_track_object (object, type); if (!result) { GST_DEBUG ("Did not create track object"); - return FALSE; + return NULL; } - if (ges_timeline_object_add_track_object (object, result) == FALSE) - return FALSE; - - return ges_track_add_object (track, result); + return g_list_append (NULL, result); } /** diff --git a/ges/ges-timeline-object.h b/ges/ges-timeline-object.h index e7bfe59a3f..299e7de290 100644 --- a/ges/ges-timeline-object.h +++ b/ges/ges-timeline-object.h @@ -36,6 +36,7 @@ G_BEGIN_DECLS #define GES_TIMELINE_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GES_TYPE_TIMELINE_OBJECT, GESTimelineObjectClass)) typedef struct _GESTimelineObjectPrivate GESTimelineObjectPrivate; +typedef struct _GESTimelineObjectClassPrivate GESTimelineObjectClassPrivate; /** * GESFillTrackObjectFunc: @@ -58,7 +59,7 @@ typedef gboolean (*GESFillTrackObjectFunc) (GESTimelineObject *object, /** * GESCreateTrackObjectFunc: * @object: a #GESTimelineObject - * @track: a #GESTrack + * @type: a #GESTrackType * * Creates the 'primary' track object for this @object. * @@ -78,14 +79,13 @@ typedef gboolean (*GESFillTrackObjectFunc) (GESTimelineObject *object, * Returns: the #GESTrackObject to be used, or %NULL if it can't provide one * for the given @track. */ -typedef GESTrackObject *(*GESCreateTrackObjectFunc) (GESTimelineObject * - object, - GESTrack *track); +typedef GESTrackObject *(*GESCreateTrackObjectFunc) (GESTimelineObject * object, + GESTrackType type); /** * GESCreateTrackObjectsFunc: * @object: a #GESTimelineObject - * @track: a #GESTrack + * @type: a #GESTrackType * * Create all track objects this object handles for this type of track. * @@ -94,12 +94,12 @@ typedef GESTrackObject *(*GESCreateTrackObjectFunc) (GESTimelineObject * * * For each object created, the subclass must call * ges_timeline_object_add_track_object() with the newly created object - * and provided @track. + * and provided @type. * * Returns: %TRUE on success %FALSE on failure. */ -typedef gboolean (*GESCreateTrackObjectsFunc) (GESTimelineObject *object, - GESTrack *track); + +typedef GList * (*GESCreateTrackObjectsFunc) (GESTimelineObject * object, GESTrackType type); /** * GES_TIMELINE_OBJECT_START: @@ -241,8 +241,8 @@ void ges_timeline_object_set_layer (GESTimelineObject *object, /* TrackObject handling */ GList* ges_timeline_object_get_track_objects (GESTimelineObject *object); GESTrackType ges_timeline_object_get_supported_formats (GESTimelineObject *object); -GESTrackObject *ges_timeline_object_create_track_object (GESTimelineObject *object, GESTrack *track); -gboolean ges_timeline_object_create_track_objects (GESTimelineObject *object, GESTrack *track); +GESTrackObject *ges_timeline_object_create_track_object (GESTimelineObject *object, GESTrackType type); +GList * ges_timeline_object_create_track_objects (GESTimelineObject *object, GESTrackType type); gboolean ges_timeline_object_release_track_object (GESTimelineObject *object, GESTrackObject *trackobject); void ges_timeline_object_set_supported_formats (GESTimelineObject *object, GESTrackType supportedformats); gboolean ges_timeline_object_add_asset (GESTimelineObject *object, GESAsset *asset); @@ -250,7 +250,6 @@ gboolean ges_timeline_object_add_track_object (GESTimelineObject *obje gboolean ges_timeline_object_fill_track_object (GESTimelineObject *object, GESTrackObject *trackobj, GstElement *gnlobj); GESTrackObject *ges_timeline_object_find_track_object (GESTimelineObject *object, GESTrack *track, GType type); - /* Layer */ GESTimelineLayer *ges_timeline_object_get_layer (GESTimelineObject *object); gboolean ges_timeline_object_is_moving_from_layer (GESTimelineObject *object); diff --git a/ges/ges-timeline-parse-launch-effect.c b/ges/ges-timeline-parse-launch-effect.c index d0b192f3b8..69480dd220 100644 --- a/ges/ges-timeline-parse-launch-effect.c +++ b/ges/ges-timeline-parse-launch-effect.c @@ -55,7 +55,7 @@ enum static void ges_timeline_parse_launch_effect_finalize (GObject * object); static GESTrackObject * ges_tl_parse_launch_effect_create_track_obj (GESTimelineObject * self, - GESTrack * track); + GESTrackType type); static void ges_timeline_parse_launch_effect_finalize (GObject * object) @@ -166,28 +166,22 @@ ges_timeline_parse_launch_effect_init (GESTimelineParseLaunchEffect * self) static GESTrackObject * ges_tl_parse_launch_effect_create_track_obj (GESTimelineObject * self, - GESTrack * track) + GESTrackType type) { + const gchar *bin_description = NULL; GESTimelineParseLaunchEffect *effect = GES_TIMELINE_PARSE_LAUNCH_EFFECT (self); - if (track->type == GES_TRACK_TYPE_VIDEO) { - if (effect->priv->video_bin_description != NULL) { - GST_DEBUG ("Creating a GESTrackEffect for the video track"); - return GES_TRACK_OBJECT (ges_track_parse_launch_effect_new - (effect->priv->video_bin_description)); - } - GST_DEBUG ("Can't create the track Object, the" - "video_bin_description is not set"); + if (type == GES_TRACK_TYPE_VIDEO) { + bin_description = effect->priv->video_bin_description; + } else if (type == GES_TRACK_TYPE_AUDIO) { + bin_description = effect->priv->audio_bin_description; } - if (track->type == GES_TRACK_TYPE_AUDIO) { - if (effect->priv->audio_bin_description != NULL) { - GST_DEBUG ("Creating a GESTrackEffect for the audio track"); - return GES_TRACK_OBJECT (ges_track_parse_launch_effect_new - (effect->priv->audio_bin_description)); - } - GST_DEBUG ("Can't create the track Object, the" - "audio_bin_description is not set"); + + if (bin_description) { + /* FIXME Work with a GESAsset here! */ + return g_object_new (GES_TYPE_TRACK_PARSE_LAUNCH_EFFECT, "bin-description", + bin_description, "track-type", type, NULL); } GST_WARNING ("Effect doesn't handle this track type"); diff --git a/ges/ges-timeline-standard-transition.c b/ges/ges-timeline-standard-transition.c index 428252b1f6..69e6b99117 100644 --- a/ges/ges-timeline-standard-transition.c +++ b/ges/ges-timeline-standard-transition.c @@ -57,7 +57,7 @@ enum }; static GESTrackObject *ges_tl_transition_create_track_object (GESTimelineObject - * self, GESTrack * track); + * self, GESTrackType type); static void ges_timeline_standard_transition_track_object_added (GESTimelineObject * obj, GESTrackObject * tckobj); @@ -309,7 +309,7 @@ ges_timeline_standard_transition_track_object_added (GESTimelineObject * obj, static GESTrackObject * ges_tl_transition_create_track_object (GESTimelineObject * obj, - GESTrack * track) + GESTrackType type) { GESTimelineStandardTransition *transition = (GESTimelineStandardTransition *) obj; @@ -319,7 +319,7 @@ ges_tl_transition_create_track_object (GESTimelineObject * obj, GST_DEBUG ("Creating a GESTrackTransition"); supportedformats = ges_timeline_object_get_supported_formats (obj); - if (track->type == GES_TRACK_TYPE_VIDEO) { + if (type == GES_TRACK_TYPE_VIDEO) { if (supportedformats == GES_TRACK_TYPE_UNKNOWN || supportedformats & GES_TRACK_TYPE_VIDEO) { GESTrackVideoTransition *trans; @@ -333,7 +333,7 @@ ges_tl_transition_create_track_object (GESTimelineObject * obj, " supportedformats"); } - } else if (track->type == GES_TRACK_TYPE_AUDIO) { + } else if (type == GES_TRACK_TYPE_AUDIO) { if (supportedformats == GES_TRACK_TYPE_UNKNOWN || supportedformats & GES_TRACK_TYPE_AUDIO) diff --git a/ges/ges-timeline-test-source.c b/ges/ges-timeline-test-source.c index f02a95d38f..47c1010092 100644 --- a/ges/ges-timeline-test-source.c +++ b/ges/ges-timeline-test-source.c @@ -59,7 +59,7 @@ enum static GESTrackObject * ges_timeline_test_source_create_track_object (GESTimelineObject * obj, - GESTrack * track); + GESTrackType type); static void ges_timeline_test_source_get_property (GObject * object, guint property_id, @@ -353,20 +353,19 @@ ges_timeline_test_source_get_volume (GESTimelineTestSource * self) static GESTrackObject * ges_timeline_test_source_create_track_object (GESTimelineObject * obj, - GESTrack * track) + GESTrackType type) { GESTimelineTestSourcePrivate *priv = GES_TIMELINE_TEST_SOURCE (obj)->priv; GESTrackObject *res = NULL; - GST_DEBUG ("Creating a GESTrackTestSource"); + GST_DEBUG ("Creating a GESTrackTestSource for type: %s", + ges_track_type_name (type)); - if (track->type == GES_TRACK_TYPE_VIDEO) { + if (type == GES_TRACK_TYPE_VIDEO) { res = (GESTrackObject *) ges_track_video_test_source_new (); ges_track_video_test_source_set_pattern ( (GESTrackVideoTestSource *) res, priv->vpattern); - } - - else if (track->type == GES_TRACK_TYPE_AUDIO) { + } else if (type == GES_TRACK_TYPE_AUDIO) { res = (GESTrackObject *) ges_track_audio_test_source_new (); if (priv->mute) diff --git a/ges/ges-timeline-text-overlay.c b/ges/ges-timeline-text-overlay.c index 009826295d..405452f7e9 100644 --- a/ges/ges-timeline-text-overlay.c +++ b/ges/ges-timeline-text-overlay.c @@ -65,7 +65,7 @@ enum static GESTrackObject * ges_timeline_text_overlay_create_track_object (GESTimelineObject * obj, - GESTrack * track); + GESTrackType type); static void ges_timeline_text_overlay_get_property (GObject * object, guint property_id, @@ -603,7 +603,7 @@ ges_timeline_text_overlay_get_ypos (GESTimelineTextOverlay * self) static GESTrackObject * ges_timeline_text_overlay_create_track_object (GESTimelineObject * obj, - GESTrack * track) + GESTrackType type) { GESTimelineTextOverlayPrivate *priv = GES_TIMELINE_TEXT_OVERLAY (obj)->priv; @@ -611,7 +611,7 @@ ges_timeline_text_overlay_create_track_object (GESTimelineObject * obj, GST_DEBUG ("Creating a GESTrackOverlay"); - if (track->type == GES_TRACK_TYPE_VIDEO) { + if (type == GES_TRACK_TYPE_VIDEO) { res = (GESTrackObject *) ges_track_text_overlay_new (); GST_DEBUG ("Setting text property"); ges_track_text_overlay_set_text ((GESTrackTextOverlay *) res, priv->text); diff --git a/ges/ges-timeline-title-source.c b/ges/ges-timeline-title-source.c index dbaf315493..5319d7720d 100644 --- a/ges/ges-timeline-title-source.c +++ b/ges/ges-timeline-title-source.c @@ -71,7 +71,7 @@ enum static GESTrackObject * ges_timeline_title_source_create_track_object (GESTimelineObject * obj, - GESTrack * track); + GESTrackType type); static void ges_timeline_title_source_track_object_added (GESTimelineObject * obj, @@ -704,7 +704,7 @@ ges_timeline_title_source_track_object_added (GESTimelineObject * obj, static GESTrackObject * ges_timeline_title_source_create_track_object (GESTimelineObject * obj, - GESTrack * track) + GESTrackType type) { GESTimelineTitleSourcePrivate *priv = GES_TIMELINE_TITLE_SOURCE (obj)->priv; @@ -712,7 +712,7 @@ ges_timeline_title_source_create_track_object (GESTimelineObject * obj, GST_DEBUG_OBJECT (obj, "a GESTrackTitleSource"); - if (track->type == GES_TRACK_TYPE_VIDEO) { + if (type == GES_TRACK_TYPE_VIDEO) { res = (GESTrackObject *) ges_track_title_source_new (); GST_DEBUG_OBJECT (obj, "text property"); ges_track_title_source_set_text ((GESTrackTitleSource *) res, priv->text); diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index 610e1eb188..3881114dfe 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -2,6 +2,8 @@ * Copyright (C) 2009 Edward Hervey * 2009 Nokia Corporation * 2012 Thibault Saunier + * 2012 Collabora Ltd. + * Author: Sebastian Dröge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -44,6 +46,8 @@ typedef struct _MoveContext MoveContext; +static GPtrArray *select_tracks_for_object_default (GESTimeline * timeline, + GESTimelineObject * tl_obj, GESTrackObject * tr_obj, gpointer user_data); static inline void init_movecontext (MoveContext * mv_ctx); static void ges_extractable_interface_init (GESExtractableInterface * iface); static void ges_meta_container_interface_init @@ -171,6 +175,7 @@ enum LAYER_REMOVED, SNAPING_STARTED, SNAPING_ENDED, + SELECT_TRACKS_FOR_OBJECT, LAST_SIGNAL }; @@ -321,6 +326,20 @@ ges_timeline_finalize (GObject * object) G_OBJECT_CLASS (ges_timeline_parent_class)->finalize (object); } +/* we collect the first result */ +static gboolean +_gst_array_accumulator (GSignalInvocationHint * ihint, + GValue * return_accu, const GValue * handler_return, gpointer dummy) +{ + gpointer array; + + array = g_value_get_boxed (handler_return); + if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP)) + g_value_set_boxed (return_accu, array); + + return FALSE; +} + static void ges_timeline_class_init (GESTimelineClass * klass) { @@ -467,6 +486,21 @@ ges_timeline_class_init (GESTimelineClass * klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 3, GES_TYPE_TRACK_OBJECT, GES_TYPE_TRACK_OBJECT, G_TYPE_UINT64); + + /** + * GESTimeline::select-tracks-for-object: + * @timeline: the #GESTimeline + * @timeline-object: The #GESTimelineObject on which @track-object will land + * @track-object: The #GESTrackObject for which to choose the tracks it should land into + * + * Returns: (transfer full) (element-type GESTrack): a #GPtrArray of #GESTrack-s where that object should be added + * + * Since: 0.10.XX + */ + ges_timeline_signals[SELECT_TRACKS_FOR_OBJECT] = + g_signal_new ("select-tracks-for-object", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, _gst_array_accumulator, NULL, NULL, + G_TYPE_PTR_ARRAY, 2, GES_TYPE_TIMELINE_OBJECT, GES_TYPE_TRACK_OBJECT); } static void @@ -495,6 +529,9 @@ ges_timeline_init (GESTimeline * self) (GDestroyNotify) _destroy_obj_iters); priv->starts_ends = g_sequence_new (g_free); priv->tracksources = g_sequence_new (g_object_unref); + + g_signal_connect_after (self, "select-tracks-for-object", + G_CALLBACK (select_tracks_for_object_default), NULL); } /* Private methods */ @@ -1415,23 +1452,114 @@ timeline_context_to_layer (GESTimeline * timeline, gint offset) } static void -add_object_to_track (GESTimelineObject * object, GESTrack * track) +add_object_to_track (GESTimelineObject * object, GESTrackObject * track_object, + GESTrack * track) { - if (!ges_timeline_object_create_track_objects (object, track)) { - if ((track->type & ges_timeline_object_get_supported_formats (object))) { - GST_WARNING ("Error creating track objects"); - } + if (!ges_timeline_object_add_track_object (object, track_object)) { + GST_WARNING_OBJECT (object, + "Failed to add track object to timeline object"); + gst_object_unref (track_object); + return; + } + + if (!ges_track_add_object (track, track_object)) { + GST_WARNING_OBJECT (object, "Failed to add track object to track"); + ges_timeline_object_release_track_object (object, track_object); + gst_object_unref (track_object); + return; } } -static void -add_object_to_tracks (GESTimeline * timeline, GESTimelineObject * object) +static GPtrArray * +select_tracks_for_object_default (GESTimeline * timeline, + GESTimelineObject * tl_obj, GESTrackObject * tr_object, gpointer user_data) { + GPtrArray *result; GList *tmp; - for (tmp = timeline->tracks; tmp; tmp = g_list_next (tmp)) { - GST_LOG_OBJECT (timeline, "Trying with track %" GST_PTR_FORMAT, tmp->data); - add_object_to_track (object, GES_TRACK (tmp->data)); + result = g_ptr_array_new (); + + for (tmp = timeline->tracks; tmp; tmp = tmp->next) { + GESTrack *track = GES_TRACK (tmp->data); + + if ((track->type & ges_track_object_get_track_type (tr_object))) { + gst_object_ref (track); + g_ptr_array_add (result, track); + } + } + + return result; +} + +static void +add_object_to_tracks (GESTimeline * timeline, GESTimelineObject * object, + GESTrack * track) +{ + gint i; + GPtrArray *tracks = NULL; + GESTrackType types, visited_type = 1; + GList *tmp, *l, *track_objects; + + GST_DEBUG_OBJECT (timeline, "Creating %" GST_PTR_FORMAT + " trackobjects and adding them to our tracks", object); + + types = ges_timeline_object_get_supported_formats (object); + if (track) { + if ((types & track->type) == 0) + return; + types = track->type; + } + + for (i = 0, tmp = timeline->tracks; tmp; tmp = tmp->next, i++) { + GESTrack *track = GES_TRACK (tmp->data); + + if (((track->type & types) == 0 || (track->type & visited_type))) + continue; + + track_objects = ges_timeline_object_create_track_objects (object, + track->type); + for (l = track_objects; l; l = l->next) { + GESTrack *tmp_track; + GESTrackObject *track_object = l->data; + + GST_DEBUG_OBJECT (timeline, "Got trackobject: %" GST_PTR_FORMAT + "Asking to which track it should be added", track_object); + + g_signal_emit (G_OBJECT (timeline), + ges_timeline_signals[SELECT_TRACKS_FOR_OBJECT], 0, object, + track_object, &tracks); + + if (!tracks || tracks->len == 0) { + GST_DEBUG_OBJECT (timeline, "Got no Track to add %p into", object); + goto next_track_object; + } + + for (i = 0; i < tracks->len; i++) { + GESTrackObject *track_object_copy; + + tmp_track = g_ptr_array_index (tracks, i); + if (track && tmp_track != track) { + GST_LOG_OBJECT (timeline, + "Not adding %" GST_PTR_FORMAT " to any track", track_object); + continue; + } + + track_object_copy = ges_track_object_copy (track_object, TRUE); + + GST_LOG_OBJECT (timeline, "Trying to add %p to track %p", + track_object_copy, tmp_track); + add_object_to_track (object, track_object_copy, tmp_track); + + gst_object_unref (tmp_track); + } + + next_track_object: + if (tracks) { + g_ptr_array_unref (tracks); + tracks = NULL; + } + gst_object_unref (track_object); + } } } @@ -1447,7 +1575,7 @@ layer_object_added_cb (GESTimelineLayer * layer, GESTimelineObject * object, } GST_DEBUG ("New TimelineObject %p added to layer %p", object, layer); - add_object_to_tracks (timeline, object); + add_object_to_tracks (timeline, object, NULL); GST_DEBUG ("Done"); } @@ -1480,7 +1608,7 @@ layer_object_removed_cb (GESTimelineLayer * layer, GESTimelineObject * object, for (tmp = trackobjects; tmp; tmp = tmp->next) { GESTrackObject *trobj = (GESTrackObject *) tmp->data; - GST_DEBUG ("Trying to remove TrackObject %p", trobj); + GST_DEBUG_OBJECT (timeline, "Trying to remove TrackObject %p", trobj); if (G_LIKELY (g_list_find_custom (timeline->priv->priv_tracks, ges_track_object_get_track (trobj), (GCompareFunc) custom_find_track))) { @@ -1939,9 +2067,10 @@ ges_timeline_add_track (GESTimeline * timeline, GESTrack * track) objects = ges_timeline_layer_get_objects (tmp->data); for (obj = objects; obj; obj = obj->next) { - add_object_to_track (obj->data, track); - g_object_unref (obj->data); - obj->data = NULL; + GESTimelineObject *object = obj->data; + + add_object_to_tracks (timeline, object, track); + g_object_unref (object); } g_list_free (objects); } diff --git a/ges/ges-track-audio-test-source.c b/ges/ges-track-audio-test-source.c index 350f7051d7..191d904af9 100644 --- a/ges/ges-track-audio-test-source.c +++ b/ges/ges-track-audio-test-source.c @@ -186,5 +186,6 @@ ges_track_audio_test_source_get_volume (GESTrackAudioTestSource * self) GESTrackAudioTestSource * ges_track_audio_test_source_new (void) { - return g_object_new (GES_TYPE_TRACK_AUDIO_TEST_SOURCE, NULL); + return g_object_new (GES_TYPE_TRACK_AUDIO_TEST_SOURCE, "track-type", + GES_TRACK_TYPE_AUDIO, NULL); } diff --git a/ges/ges-track-audio-transition.c b/ges/ges-track-audio-transition.c index 476b4e8f25..352ee845e0 100644 --- a/ges/ges-track-audio-transition.c +++ b/ges/ges-track-audio-transition.c @@ -272,5 +272,6 @@ ges_track_audio_transition_duration_changed (GESTrackObject * object, GESTrackAudioTransition * ges_track_audio_transition_new (void) { - return g_object_new (GES_TYPE_TRACK_AUDIO_TRANSITION, NULL); + return g_object_new (GES_TYPE_TRACK_AUDIO_TRANSITION, "track-type", + GES_TRACK_TYPE_AUDIO, NULL); } diff --git a/ges/ges-track-image-source.c b/ges/ges-track-image-source.c index 61834838ed..9fcf73cc19 100644 --- a/ges/ges-track-image-source.c +++ b/ges/ges-track-image-source.c @@ -188,5 +188,6 @@ ges_track_image_source_init (GESTrackImageSource * self) GESTrackImageSource * ges_track_image_source_new (gchar * uri) { - return g_object_new (GES_TYPE_TRACK_IMAGE_SOURCE, "uri", uri, NULL); + return g_object_new (GES_TYPE_TRACK_IMAGE_SOURCE, "uri", uri, "track-type", + GES_TRACK_TYPE_VIDEO, NULL); } diff --git a/ges/ges-track-object.c b/ges/ges-track-object.c index 0b82c7744f..b53f787662 100644 --- a/ges/ges-track-object.c +++ b/ges/ges-track-object.c @@ -50,6 +50,8 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GESTrackObject, ges_track_object, struct _GESTrackObjectPrivate { + GESTrackType track_type; + /* These fields are only used before the gnlobject is available */ guint64 pending_start; guint64 pending_inpoint; @@ -86,6 +88,7 @@ enum PROP_ACTIVE, PROP_LOCKED, PROP_MAX_DURATION, + PROP_TRACK_TYPE, PROP_LAST }; @@ -165,6 +168,9 @@ ges_track_object_get_property (GObject * object, guint property_id, case PROP_MAX_DURATION: g_value_set_uint64 (value, tobj->priv->maxduration); break; + case PROP_TRACK_TYPE: + g_value_set_flags (value, tobj->priv->track_type); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -198,6 +204,9 @@ ges_track_object_set_property (GObject * object, guint property_id, case PROP_MAX_DURATION: ges_track_object_set_max_duration (tobj, g_value_get_uint64 (value)); break; + case PROP_TRACK_TYPE: + tobj->priv->track_type = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -336,10 +345,20 @@ ges_track_object_class_init (GESTrackObjectClass * klass) * * Since: 0.10.XX */ - g_object_class_install_property (object_class, PROP_MAX_DURATION, + properties[PROP_MAX_DURATION] = g_param_spec_uint64 ("max-duration", "Maximum duration", - "The maximum duration of the object", 0, G_MAXUINT64, G_MAXUINT64, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + "The maximum duration of the object", 0, G_MAXUINT64, G_MAXUINT64, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + + g_object_class_install_property (object_class, PROP_MAX_DURATION, + properties[PROP_MAX_DURATION]); + + properties[PROP_TRACK_TYPE] = g_param_spec_flags ("track-type", "Track Type", + "The track type of the object", GES_TYPE_TRACK_TYPE, + GES_TRACK_TYPE_UNKNOWN, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_class_install_property (object_class, PROP_TRACK_TYPE, + properties[PROP_TRACK_TYPE]); + /** * GESTrackObject::deep-notify: @@ -564,6 +583,25 @@ ges_track_object_set_active (GESTrackObject * object, gboolean active) return TRUE; } +void +ges_track_object_set_track_type (GESTrackObject * object, GESTrackType type) +{ + g_return_if_fail (GES_IS_TRACK_OBJECT (object)); + + if (object->priv->track_type != type) { + object->priv->track_type = type; + g_object_notify_by_pspec (G_OBJECT (object), properties[PROP_TRACK_TYPE]); + } +} + +GESTrackType +ges_track_object_get_track_type (GESTrackObject * object) +{ + g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), GES_TRACK_TYPE_UNKNOWN); + + return object->priv->track_type; +} + /* Callbacks from the GNonLin object */ static void gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED, diff --git a/ges/ges-track-object.h b/ges/ges-track-object.h index 9f6e0bab16..e28d68ca9e 100644 --- a/ges/ges-track-object.h +++ b/ges/ges-track-object.h @@ -152,6 +152,10 @@ gboolean ges_track_object_set_track (GESTrackObject * object, GESTrack * track); GESTrack* ges_track_object_get_track (GESTrackObject * object); +GESTrackType ges_track_object_get_track_type (GESTrackObject * object); +void ges_track_object_set_track_type (GESTrackObject * object, + GESTrackType type); + void ges_track_object_set_timeline_object (GESTrackObject * object, GESTimelineObject * tlobject); GESTimelineObject * diff --git a/ges/ges-track-text-overlay.c b/ges/ges-track-text-overlay.c index 6dcb05c95b..d79de30159 100644 --- a/ges/ges-track-text-overlay.c +++ b/ges/ges-track-text-overlay.c @@ -442,5 +442,6 @@ ges_track_text_overlay_get_ypos (GESTrackTextOverlay * self) GESTrackTextOverlay * ges_track_text_overlay_new (void) { - return g_object_new (GES_TYPE_TRACK_TEXT_OVERLAY, NULL); + return g_object_new (GES_TYPE_TRACK_TEXT_OVERLAY, "track-type", + GES_TRACK_TYPE_VIDEO, NULL); } diff --git a/ges/ges-track-title-source.c b/ges/ges-track-title-source.c index 91f03f04a3..49cfa068e4 100644 --- a/ges/ges-track-title-source.c +++ b/ges/ges-track-title-source.c @@ -472,5 +472,6 @@ ges_track_title_source_get_ypos (GESTrackTitleSource * source) GESTrackTitleSource * ges_track_title_source_new (void) { - return g_object_new (GES_TYPE_TRACK_TITLE_SOURCE, NULL); + return g_object_new (GES_TYPE_TRACK_TITLE_SOURCE, "track-type", + GES_TRACK_TYPE_VIDEO, NULL); } diff --git a/ges/ges-track-video-test-source.c b/ges/ges-track-video-test-source.c index 37dd301828..bba3a9b54c 100644 --- a/ges/ges-track-video-test-source.c +++ b/ges/ges-track-video-test-source.c @@ -116,5 +116,6 @@ ges_track_video_test_source_get_pattern (GESTrackVideoTestSource * source) GESTrackVideoTestSource * ges_track_video_test_source_new (void) { - return g_object_new (GES_TYPE_TRACK_VIDEO_TEST_SOURCE, NULL); + return g_object_new (GES_TYPE_TRACK_VIDEO_TEST_SOURCE, "track-type", + GES_TRACK_TYPE_VIDEO, NULL); } diff --git a/ges/ges-track-video-transition.c b/ges/ges-track-video-transition.c index be5af1a68a..8e356da28a 100644 --- a/ges/ges-track-video-transition.c +++ b/ges/ges-track-video-transition.c @@ -876,5 +876,6 @@ ges_track_video_transition_get_transition_type (GESTrackVideoTransition * trans) GESTrackVideoTransition * ges_track_video_transition_new (void) { - return g_object_new (GES_TYPE_TRACK_VIDEO_TRANSITION, NULL); + return g_object_new (GES_TYPE_TRACK_VIDEO_TRANSITION, "track-type", + GES_TRACK_TYPE_VIDEO, NULL); } diff --git a/ges/ges-track.c b/ges/ges-track.c index e0e83e5107..596843f910 100644 --- a/ges/ges-track.c +++ b/ges/ges-track.c @@ -752,9 +752,10 @@ ges_track_set_caps (GESTrack * track, const GstCaps * caps) GESTrackPrivate *priv; g_return_if_fail (GES_IS_TRACK (track)); - g_return_if_fail (GST_IS_CAPS (caps)); GST_DEBUG ("track:%p, caps:%" GST_PTR_FORMAT, track, caps); + g_return_if_fail (GST_IS_CAPS (caps)); + GST_DEBUG ("IS CAPS MOFOP:%p, caps:%" GST_PTR_FORMAT, track, caps); priv = track->priv; diff --git a/tests/check/ges/backgroundsource.c b/tests/check/ges/backgroundsource.c index c526088dea..a2dd47afa3 100644 --- a/tests/check/ges/backgroundsource.c +++ b/tests/check/ges/backgroundsource.c @@ -57,7 +57,7 @@ GST_START_TEST (test_test_source_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); @@ -138,6 +138,8 @@ GST_START_TEST (test_test_source_in_layer) ges_timeline_object_find_track_object (GES_TIMELINE_OBJECT (source), v, GES_TYPE_TRACK_VIDEO_TEST_SOURCE); + g_assert (GES_IS_TRACK_VIDEO_TEST_SOURCE (trobj)); + ptrn = (ges_track_video_test_source_get_pattern ((GESTrackVideoTestSource *) trobj)); assert_equals_int (ptrn, GES_VIDEO_TEST_PATTERN_WHITE); @@ -257,8 +259,9 @@ GST_START_TEST (test_gap_filling_basic) assert_equals_uint64 (GES_TIMELINE_OBJECT_START (object), 0); assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 5); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); + fail_unless (ges_track_add_object (track, trackobject)); fail_unless (trackobject != NULL); gnlsrc = ges_track_object_get_gnlobject (trackobject); @@ -278,7 +281,7 @@ GST_START_TEST (test_gap_filling_basic) assert_equals_uint64 (GES_TIMELINE_OBJECT_START (object1), 15); assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object1), 5); - trackobject1 = ges_timeline_object_create_track_object (object1, track); + trackobject1 = ges_timeline_object_create_track_object (object1, track->type); ges_timeline_object_add_track_object (object1, trackobject1); fail_unless (ges_track_add_object (track, trackobject1)); fail_unless (trackobject1 != NULL); @@ -305,7 +308,7 @@ GST_START_TEST (test_gap_filling_basic) object2 = GES_TIMELINE_OBJECT (ges_timeline_test_source_new ()); fail_unless (object2 != NULL); g_object_set (object2, "start", (guint64) 35, "duration", (guint64) 5, NULL); - trackobject2 = ges_timeline_object_create_track_object (object2, track); + trackobject2 = ges_timeline_object_create_track_object (object2, track->type); ges_timeline_object_add_track_object (object2, trackobject2); fail_unless (ges_track_add_object (track, trackobject2)); fail_unless (trackobject2 != NULL); diff --git a/tests/check/ges/basic.c b/tests/check/ges/basic.c index a727061661..2f7b3b9192 100644 --- a/tests/check/ges/basic.c +++ b/tests/check/ges/basic.c @@ -1,5 +1,7 @@ /* GStreamer Editing Services * Copyright (C) 2009 Edward Hervey + * 2012 Collabora Ltd. + * Author: Sebastian Dröge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -568,6 +570,187 @@ GST_START_TEST (test_ges_timeline_remove_track) GST_END_TEST; +typedef struct +{ + GESCustomTimelineSource **o1, **o2, **o3; + GESTrack **tr1, **tr2; +} SelectTracksData; + +static GPtrArray * +select_tracks_cb (GESTimeline * timeline, GESTimelineObject * tobj, + GESTrackObject * trobj, SelectTracksData * st_data) +{ + GESTrack *track; + + GPtrArray *ret = g_ptr_array_new (); + track = (tobj == (GESTimelineObject *) * st_data->o2) ? *st_data->tr2 : + *st_data->tr1; + + gst_object_ref (track); + + g_ptr_array_add (ret, track); + + return ret; +} + +GST_START_TEST (test_ges_timeline_multiple_tracks) +{ + GESTimeline *timeline; + GESTimelineLayer *layer, *tmp_layer; + GESTrack *track1, *track2; + GESCustomTimelineSource *s1, *s2, *s3; + GESTrackObject *t1, *t2, *t3; + GList *trackobjects, *tmp, *layers; + SelectTracksData st_data = { &s1, &s2, &s3, &track1, &track2 }; + + ges_init (); + + /* Timeline and 1 Layer */ + GST_DEBUG ("Create a timeline"); + timeline = ges_timeline_new (); + fail_unless (timeline != NULL); + + g_signal_connect (timeline, "select-tracks-for-object", + G_CALLBACK (select_tracks_cb), &st_data); + + GST_DEBUG ("Create a layer"); + layer = ges_timeline_layer_new (); + fail_unless (layer != NULL); + /* Give the Timeline a Track */ + GST_DEBUG ("Create Track 1"); + track1 = ges_track_new (GES_TRACK_TYPE_CUSTOM, gst_caps_ref (GST_CAPS_ANY)); + fail_unless (track1 != NULL); + GST_DEBUG ("Create Track 2"); + track2 = ges_track_new (GES_TRACK_TYPE_CUSTOM, gst_caps_ref (GST_CAPS_ANY)); + fail_unless (track2 != NULL); + + GST_DEBUG ("Add the track 1 to the timeline"); + fail_unless (ges_timeline_add_track (timeline, track1)); + ASSERT_OBJECT_REFCOUNT (track1, "track", 1); + fail_unless (ges_track_get_timeline (track1) == timeline); + fail_unless ((gpointer) GST_ELEMENT_PARENT (track1) == (gpointer) timeline); + + GST_DEBUG ("Add the track 2 to the timeline"); + fail_unless (ges_timeline_add_track (timeline, track2)); + ASSERT_OBJECT_REFCOUNT (track2, "track", 1); + fail_unless (ges_track_get_timeline (track2) == timeline); + fail_unless ((gpointer) GST_ELEMENT_PARENT (track2) == (gpointer) timeline); + + /* Create a source and add it to the Layer */ + GST_DEBUG ("Creating a source"); + s1 = ges_custom_timeline_source_new (my_fill_track_func, NULL); + fail_unless (s1 != NULL); + fail_unless (ges_timeline_layer_add_object (layer, GES_TIMELINE_OBJECT (s1))); + tmp_layer = ges_timeline_object_get_layer (GES_TIMELINE_OBJECT (s1)); + fail_unless (tmp_layer == layer); + g_object_unref (tmp_layer); + + GST_DEBUG ("Creating a source"); + s2 = ges_custom_timeline_source_new (my_fill_track_func, NULL); + fail_unless (s2 != NULL); + fail_unless (ges_timeline_layer_add_object (layer, GES_TIMELINE_OBJECT (s2))); + tmp_layer = ges_timeline_object_get_layer (GES_TIMELINE_OBJECT (s2)); + fail_unless (tmp_layer == layer); + g_object_unref (tmp_layer); + + GST_DEBUG ("Creating a source"); + s3 = ges_custom_timeline_source_new (my_fill_track_func, NULL); + fail_unless (s3 != NULL); + fail_unless (ges_timeline_layer_add_object (layer, GES_TIMELINE_OBJECT (s3))); + tmp_layer = ges_timeline_object_get_layer (GES_TIMELINE_OBJECT (s3)); + fail_unless (tmp_layer == layer); + g_object_unref (tmp_layer); + + GST_DEBUG ("Add the layer to the timeline"); + fail_unless (ges_timeline_add_layer (timeline, layer)); + /* The timeline steals our reference to the layer */ + ASSERT_OBJECT_REFCOUNT (layer, "layer", 1); + fail_unless (layer->timeline == timeline); + + layers = ges_timeline_get_layers (timeline); + fail_unless (g_list_find (layers, layer) != NULL); + g_list_foreach (layers, (GFunc) g_object_unref, NULL); + g_list_free (layers); + + /* Make sure the associated TrackObjects are in the Track */ + trackobjects = + ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s1)); + fail_unless (trackobjects != NULL); + t1 = GES_TRACK_OBJECT ((trackobjects)->data); + for (tmp = trackobjects; tmp; tmp = tmp->next) { + /* There are 4 references held: + * 1 by the timelineobject + * 1 by the track + * 1 by the timeline + * 1 added by the call to _get_track_objects() above */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 4); + fail_unless (ges_track_object_get_track (tmp->data) == track1); + g_object_unref (GES_TRACK_OBJECT (tmp->data)); + } + g_object_ref (t1); + g_list_free (trackobjects); + /* There are 4 references held: + * 1 by the timelinobject + * 1 by the track + * 1 by the timeline + * 1 added by ourselves above (g_object_ref (t1)) */ + ASSERT_OBJECT_REFCOUNT (t1, "trackobject", 4); + + trackobjects = + ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s2)); + fail_unless (trackobjects != NULL); + t2 = GES_TRACK_OBJECT (trackobjects->data); + for (tmp = trackobjects; tmp; tmp = tmp->next) { + /* There are 4 references held: + * 1 by the timelineobject + * 1 by the track + * 1 by the timeline + * 1 added by the call to _get_track_objects() above */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 4); + fail_unless (ges_track_object_get_track (tmp->data) == track2); + g_object_unref (GES_TRACK_OBJECT (tmp->data)); + } + g_object_ref (t2); + g_list_free (trackobjects); + /* There are 4 references held: + * 1 by the timelinobject + * 1 by the track + * 1 by the timeline + * 1 added by ourselves above (g_object_ref (t1)) */ + ASSERT_OBJECT_REFCOUNT (t2, "t2", 4); + + trackobjects = + ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (s3)); + fail_unless (trackobjects != NULL); + t3 = GES_TRACK_OBJECT (trackobjects->data); + for (tmp = trackobjects; tmp; tmp = tmp->next) { + /* There are 4 references held: + * 1 by the timelineobject + * 1 by the track + * 1 by the timeline + * 1 added by the call to _get_track_objects() above */ + ASSERT_OBJECT_REFCOUNT (GES_TRACK_OBJECT (tmp->data), "trackobject", 4); + fail_unless (ges_track_object_get_track (tmp->data) == track1); + g_object_unref (GES_TRACK_OBJECT (tmp->data)); + } + g_object_ref (t3); + g_list_free (trackobjects); + /* There are 4 references held: + * 1 by the timelinobject + * 1 by the track + * 1 by the timeline + * 1 added by ourselves above (g_object_ref (t1)) */ + ASSERT_OBJECT_REFCOUNT (t3, "t3", 4); + + g_object_unref (t1); + g_object_unref (t2); + g_object_unref (t3); + + g_object_unref (timeline); +} + +GST_END_TEST; + static Suite * ges_suite (void) { @@ -581,6 +764,7 @@ ges_suite (void) tcase_add_test (tc_chain, test_ges_timeline_add_layer); tcase_add_test (tc_chain, test_ges_timeline_add_layer_first); tcase_add_test (tc_chain, test_ges_timeline_remove_track); + tcase_add_test (tc_chain, test_ges_timeline_multiple_tracks); return s; } diff --git a/tests/check/ges/effects.c b/tests/check/ges/effects.c index 17ea2144fa..06dec15c85 100644 --- a/tests/check/ges/effects.c +++ b/tests/check/ges/effects.c @@ -205,7 +205,7 @@ GST_START_TEST (test_tl_effect) GES_TRACK_OBJECT (tck_effect))); g_object_get (tl_effect, "height", &tl_object_height, NULL); - fail_unless (tl_object_height == 3); + assert_equals_int (tl_object_height, 3); tck_effect1 = ges_track_parse_launch_effect_new ("identity"); fail_unless (ges_timeline_object_add_track_object (GES_TIMELINE_OBJECT @@ -214,7 +214,7 @@ GST_START_TEST (test_tl_effect) GES_TRACK_OBJECT (tck_effect1))); g_object_get (tl_effect, "height", &tl_object_height, NULL); - fail_unless (tl_object_height == 4); + assert_equals_int (tl_object_height, 4); effects = ges_timeline_object_get_top_effects (GES_TIMELINE_OBJECT (tl_effect)); diff --git a/tests/check/ges/filesource.c b/tests/check/ges/filesource.c index 4d290b75ba..06abb65098 100644 --- a/tests/check/ges/filesource.c +++ b/tests/check/ges/filesource.c @@ -134,7 +134,7 @@ GST_START_TEST (test_filesource_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); @@ -199,7 +199,7 @@ GST_START_TEST (test_filesource_images) g_object_set (G_OBJECT (tfs), "is-image", TRUE, NULL); /* the returned track object should be an image source */ - trobj = ges_timeline_object_create_track_object (tlobj, v); + trobj = ges_timeline_object_create_track_object (tlobj, v->type); ges_timeline_object_add_track_object (tlobj, trobj); fail_unless (GES_IS_TRACK_IMAGE_SOURCE (trobj)); @@ -211,7 +211,7 @@ GST_START_TEST (test_filesource_images) ges_timeline_object_release_track_object (tlobj, trobj); /* the timeline object should not create any TrackObject in the audio track */ - trobj = ges_timeline_object_create_track_object (tlobj, a); + trobj = ges_timeline_object_create_track_object (tlobj, a->type); fail_unless (trobj == NULL); g_object_unref (a); diff --git a/tests/check/ges/overlays.c b/tests/check/ges/overlays.c index 9fb3bf62fc..001e1bf749 100644 --- a/tests/check/ges/overlays.c +++ b/tests/check/ges/overlays.c @@ -57,7 +57,7 @@ GST_START_TEST (test_overlay_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); diff --git a/tests/check/ges/timelineedition.c b/tests/check/ges/timelineedition.c index c755c5a19c..58cd9d3b2c 100644 --- a/tests/check/ges/timelineedition.c +++ b/tests/check/ges/timelineedition.c @@ -91,19 +91,19 @@ GST_START_TEST (test_basic_timeline_edition) g_object_set (obj2, "start", (guint64) 50, "duration", (guint64) 60, "in-point", (guint64) 0, NULL); - tckobj = ges_timeline_object_create_track_object (obj, track); + tckobj = ges_timeline_object_create_track_object (obj, track->type); fail_unless (tckobj != NULL); fail_unless (ges_timeline_object_add_track_object (obj, tckobj)); fail_unless (ges_track_add_object (track, tckobj)); assert_equals_uint64 (ges_track_object_get_duration (tckobj), 10); - tckobj1 = ges_timeline_object_create_track_object (obj1, track); + tckobj1 = ges_timeline_object_create_track_object (obj1, track->type); fail_unless (tckobj1 != NULL); fail_unless (ges_timeline_object_add_track_object (obj1, tckobj1)); fail_unless (ges_track_add_object (track, tckobj1)); assert_equals_uint64 (ges_track_object_get_duration (tckobj1), 10); - tckobj2 = ges_timeline_object_create_track_object (obj2, track); + tckobj2 = ges_timeline_object_create_track_object (obj2, track->type); fail_unless (ges_timeline_object_add_track_object (obj2, tckobj2)); fail_unless (tckobj2 != NULL); fail_unless (ges_track_add_object (track, tckobj2)); diff --git a/tests/check/ges/timelineobject.c b/tests/check/ges/timelineobject.c index 1e00f472b2..909c134d9b 100644 --- a/tests/check/ges/timelineobject.c +++ b/tests/check/ges/timelineobject.c @@ -62,7 +62,7 @@ GST_START_TEST (test_object_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); @@ -130,7 +130,7 @@ GST_START_TEST (test_object_properties_unlocked) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); @@ -204,7 +204,7 @@ GST_START_TEST (test_split_object) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 50); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); diff --git a/tests/check/ges/titles.c b/tests/check/ges/titles.c index 0f976a95f7..49204535cd 100644 --- a/tests/check/ges/titles.c +++ b/tests/check/ges/titles.c @@ -57,7 +57,7 @@ GST_START_TEST (test_title_source_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); diff --git a/tests/check/ges/transition.c b/tests/check/ges/transition.c index 84f91530be..df0a920f66 100644 --- a/tests/check/ges/transition.c +++ b/tests/check/ges/transition.c @@ -49,7 +49,7 @@ GST_START_TEST (test_transition_basic) /* Make sure track object is created and vtype is set */ trackobject = ges_timeline_object_create_track_object (GES_TIMELINE_OBJECT (tr2), - track); + track->type); ges_timeline_object_add_track_object (GES_TIMELINE_OBJECT (tr2), trackobject); fail_unless (trackobject != NULL); @@ -89,7 +89,7 @@ GST_START_TEST (test_transition_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_DURATION (object), 51); assert_equals_uint64 (GES_TIMELINE_OBJECT_INPOINT (object), 12); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track)); @@ -142,7 +142,7 @@ GST_START_TEST (test_transition_properties) g_object_set (object, "vtype", 1, NULL); GST_DEBUG ("creating track object"); - trackobject = ges_timeline_object_create_track_object (object, track); + trackobject = ges_timeline_object_create_track_object (object, track->type); ges_timeline_object_add_track_object (object, trackobject); fail_unless (trackobject != NULL); fail_unless (ges_track_object_set_track (trackobject, track));