diff --git a/docs/scenarios b/docs/scenarios index d54c76fae0..9c808accc0 100644 --- a/docs/scenarios +++ b/docs/scenarios @@ -83,7 +83,7 @@ Methods ges_timeline_layer_add_object (GESTimelineLayer * layer, GESTimelineObject * object); * The TimelineLayer takes a reference on the TimelineObject and stores it - * The TimelineLayer tells the TmielineObject it now belongs to the given Layer + * The TimelineLayer tells the TimelineObject it now belongs to the given Layer => ges_timeline_object_set_layer (GESTimelineObject * object, GESTimelineLayer * layer); Just sets the layer field of the timeline object. * emits 'object-added' diff --git a/ges/ges-simple-timeline-layer.c b/ges/ges-simple-timeline-layer.c index 636e8fa384..c3d70856f0 100644 --- a/ges/ges-simple-timeline-layer.c +++ b/ges/ges-simple-timeline-layer.c @@ -20,19 +20,20 @@ #include "ges-simple-timeline-layer.h" G_DEFINE_TYPE (GESSimpleTimelineLayer, ges_simple_timeline_layer, - GES_TYPE_TIMELINE_LAYER) + GES_TYPE_TIMELINE_LAYER); + #define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_SIMPLE_TIMELINE_LAYER, GESSimpleTimelineLayerPrivate)) - typedef struct _GESSimpleTimelineLayerPrivate - GESSimpleTimelineLayerPrivate; + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_SIMPLE_TIMELINE_LAYER, GESSimpleTimelineLayerPrivate)); - struct _GESSimpleTimelineLayerPrivate - { - int dummy; - }; +typedef struct _GESSimpleTimelineLayerPrivate GESSimpleTimelineLayerPrivate; - static void - ges_simple_timeline_layer_get_property (GObject * object, +struct _GESSimpleTimelineLayerPrivate +{ + int dummy; +}; + +static void +ges_simple_timeline_layer_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { diff --git a/ges/ges-timeline-layer.c b/ges/ges-timeline-layer.c index 6a1e1ad07a..253da475b4 100644 --- a/ges/ges-timeline-layer.c +++ b/ges/ges-timeline-layer.c @@ -17,7 +17,9 @@ * Boston, MA 02111-1307, USA. */ +#include "gesmarshal.h" #include "ges-timeline-layer.h" +#include "ges.h" /** * GESTimelineLayer @@ -25,18 +27,29 @@ * Responsible for the ordering of the various contained TimelineObject(s) */ -G_DEFINE_TYPE (GESTimelineLayer, ges_timeline_layer, G_TYPE_OBJECT) +G_DEFINE_TYPE (GESTimelineLayer, ges_timeline_layer, G_TYPE_OBJECT); + #define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE_LAYER, GESTimelineLayerPrivate)) - typedef struct _GESTimelineLayerPrivate GESTimelineLayerPrivate; + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE_LAYER, GESTimelineLayerPrivate)); - struct _GESTimelineLayerPrivate - { - int dummy; - }; +typedef struct _GESTimelineLayerPrivate GESTimelineLayerPrivate; - static void - ges_timeline_layer_get_property (GObject * object, guint property_id, +struct _GESTimelineLayerPrivate +{ + int dummy; +}; + +enum +{ + OBJECT_ADDED, + OBJECT_REMOVED, + LAST_SIGNAL +}; + +static guint ges_timeline_layer_signals[LAST_SIGNAL] = { 0 }; + +static void +ges_timeline_layer_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { @@ -78,6 +91,19 @@ ges_timeline_layer_class_init (GESTimelineLayerClass * klass) object_class->set_property = ges_timeline_layer_set_property; object_class->dispose = ges_timeline_layer_dispose; object_class->finalize = ges_timeline_layer_finalize; + + ges_timeline_layer_signals[OBJECT_ADDED] = + g_signal_new ("object-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GESTimelineLayerClass, object_added), + NULL, NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, + GES_TYPE_TIMELINE_OBJECT); + + ges_timeline_layer_signals[OBJECT_REMOVED] = + g_signal_new ("object-removed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GESTimelineLayerClass, + object_removed), NULL, NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, + GES_TYPE_TIMELINE_OBJECT); + } static void @@ -90,3 +116,54 @@ ges_timeline_layer_new (void) { return g_object_new (GES_TYPE_TIMELINE_LAYER, NULL); } + +void +ges_timeline_layer_set_timeline (GESTimelineLayer * layer, + GESTimeline * timeline) +{ + GST_DEBUG ("layer:%p, timeline:%p", layer, timeline); + + layer->timeline = timeline; +} + +static gint +objects_start_compare (GESTimelineObject * a, GESTimelineObject * b) +{ + if (a->start == b->start) { + if (a->priority < b->priority) + return -1; + if (a->priority > b->priority) + return 1; + return 0; + } + if (a->start < b->start) + return -1; + if (a->start > b->start) + return 1; + return 0; +} + +gboolean +ges_timeline_layer_add_object (GESTimelineLayer * layer, + GESTimelineObject * object) +{ + GST_DEBUG ("layer:%p, object:%p", layer, object); + + if (G_UNLIKELY (object->layer)) { + GST_WARNING ("TimelineObject %p already belongs to another layer"); + return FALSE; + } + + /* Take a reference to the object and store it stored by start/priority */ + layer->objects_start = + g_slist_insert_sorted (layer->objects_start, g_object_ref (object), + (GCompareFunc) objects_start_compare); + + /* Inform the object it's now in this layer */ + ges_timeline_object_set_layer (object, layer); + + /* emit 'object-added' */ + g_signal_emit (layer, ges_timeline_layer_signals[OBJECT_ADDED], 0, object); + + return TRUE; +} diff --git a/ges/ges-timeline-layer.h b/ges/ges-timeline-layer.h index fda4cc8b5e..bbd8cdd66b 100644 --- a/ges/ges-timeline-layer.h +++ b/ges/ges-timeline-layer.h @@ -44,16 +44,26 @@ G_BEGIN_DECLS struct _GESTimelineLayer { GObject parent; + + GESTimeline *timeline; /* The timeline where this layer is being used */ + + GSList * objects_start; /* The TimelineObjects sorted by start and priority */ }; struct _GESTimelineLayerClass { GObjectClass parent_class; + + void (*object_added) (GESTimelineLayer * layer, GESTimelineObject * object); + void (*object_removed) (GESTimelineLayer * layer, GESTimelineObject * object); }; GType ges_timeline_layer_get_type (void); GESTimelineLayer* ges_timeline_layer_new (void); +void ges_timeline_layer_set_timeline (GESTimelineLayer * layer, GESTimeline * timeline); +gboolean ges_timeline_layer_add_object (GESTimelineLayer * layer, GESTimelineObject * object); + G_END_DECLS #endif /* _GES_TIMELINE_LAYER */ diff --git a/ges/ges-timeline-object.c b/ges/ges-timeline-object.c index 4d29e9cad1..29cb0c7a0c 100644 --- a/ges/ges-timeline-object.c +++ b/ges/ges-timeline-object.c @@ -18,6 +18,7 @@ */ #include "ges-timeline-object.h" +#include "ges.h" /** * GESTimelineObject @@ -111,11 +112,58 @@ GESTrackObject * ges_timeline_object_create_track_object (GESTimelineObject * object, GESTrack * track) { - /* FIXME : IMPLEMENT */ + GESTimelineObjectClass *class; + GESTrackObject *res; - /* implemented by subclasses */ + class = GES_TIMELINE_OBJECT_GET_CLASS (object); - /* Keep track of the created TrackObject(s) */ + if (G_UNLIKELY (class->create_track_object == NULL)) { + GST_ERROR ("No 'create_track_object' implementation available"); + return NULL; + } - return NULL; + res = class->create_track_object (object, track); + + if (res) { + GST_DEBUG + ("Got a TrackObject : %p , setting the timeline object as its creator"); + ges_track_object_set_timeline_object (res, object); + } + + GST_DEBUG ("Returning res:%p", res); + + return res; +} + +void +ges_timeline_object_set_layer (GESTimelineObject * object, + GESTimelineLayer * layer) +{ + GST_DEBUG ("object:%p, layer:%p", object, layer); + + object->layer = layer; +} + +gboolean +ges_timeline_object_fill_track_object (GESTimelineObject * object, + GESTrackObject * trackobj, GstElement * gnlobj) +{ + GESTimelineObjectClass *class; + gboolean res; + + GST_DEBUG ("object:%p, trackobject:%p, gnlobject:%p", + object, trackobj, gnlobj); + + class = GES_TIMELINE_OBJECT_GET_CLASS (object); + + if (G_UNLIKELY (class->fill_track_object == NULL)) { + GST_WARNING ("No 'fill_track_object' implementation available"); + return FALSE; + } + + res = class->fill_track_object (object, trackobj, gnlobj); + + GST_DEBUG ("Returning res:%d", res); + + return res; } diff --git a/ges/ges-timeline-object.h b/ges/ges-timeline-object.h index 773fbb07d6..3229f4056b 100644 --- a/ges/ges-timeline-object.h +++ b/ges/ges-timeline-object.h @@ -21,6 +21,7 @@ #define _GES_TIMELINE_OBJECT #include +#include #include G_BEGIN_DECLS @@ -45,6 +46,8 @@ G_BEGIN_DECLS struct _GESTimelineObject { GObject parent; + GESTimelineLayer * layer; /* The layer where this object is being used */ + /* start, inpoint, duration and fullduration are in nanoseconds */ guint64 start; /* position (in time) of the object in the layer */ guint64 inpoint; /* in-point */ @@ -56,6 +59,12 @@ struct _GESTimelineObject { struct _GESTimelineObjectClass { GObjectClass parent_class; + + GESTrackObject* (*create_track_object) (GESTimelineObject * object, + GESTrack * track); + gboolean (*fill_track_object) (GESTimelineObject * object, + GESTrackObject * trobject, + GstElement * gnlobj); }; GType ges_timeline_object_get_type (void); @@ -63,10 +72,18 @@ GType ges_timeline_object_get_type (void); GESTimelineObject* ges_timeline_object_new (void); +void ges_timeline_object_set_layer (GESTimelineObject * object, + GESTimelineLayer * layer); + GESTrackObject * ges_timeline_object_create_track_object (GESTimelineObject * object, GESTrack * track); +gboolean +ges_timeline_object_fill_track_object (GESTimelineObject * object, + GESTrackObject * trackobj, + GstElement * gnlobj); + G_END_DECLS #endif /* _GES_TIMELINE_OBJECT */ diff --git a/ges/ges-timeline-pipeline.c b/ges/ges-timeline-pipeline.c index cc585ea96e..44bac44016 100644 --- a/ges/ges-timeline-pipeline.c +++ b/ges/ges-timeline-pipeline.c @@ -23,18 +23,20 @@ * */ -G_DEFINE_TYPE (GESTimelinePipeline, ges_timeline_pipeline, GST_TYPE_PIPELINE) +G_DEFINE_TYPE (GESTimelinePipeline, ges_timeline_pipeline, GST_TYPE_PIPELINE); + #define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEST_TYPE_TIMELINE_PIPELINE, GESTimelinePipelinePrivate)) - typedef struct _GESTimelinePipelinePrivate GESTimelinePipelinePrivate; + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEST_TYPE_TIMELINE_PIPELINE, GESTimelinePipelinePrivate)); - struct _GESTimelinePipelinePrivate - { - int dummy; - }; +typedef struct _GESTimelinePipelinePrivate GESTimelinePipelinePrivate; - static void - ges_timeline_pipeline_get_property (GObject * object, +struct _GESTimelinePipelinePrivate +{ + int dummy; +}; + +static void +ges_timeline_pipeline_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { diff --git a/ges/ges-timeline-source.c b/ges/ges-timeline-source.c index 2b6b085ea9..f757631f87 100644 --- a/ges/ges-timeline-source.c +++ b/ges/ges-timeline-source.c @@ -20,18 +20,21 @@ #include "ges-timeline-object.h" #include "ges-timeline-source.h" -G_DEFINE_TYPE (GESTimelineSource, ges_timeline_source, GES_TYPE_TIMELINE_OBJECT) +G_DEFINE_TYPE (GESTimelineSource, ges_timeline_source, + GES_TYPE_TIMELINE_OBJECT); + #define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE_SOURCE, GESTimelineSourcePrivate)) - typedef struct _GESTimelineSourcePrivate GESTimelineSourcePrivate; + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE_SOURCE, GESTimelineSourcePrivate)); - struct _GESTimelineSourcePrivate - { - int dummy; - }; +typedef struct _GESTimelineSourcePrivate GESTimelineSourcePrivate; - static void - ges_timeline_source_get_property (GObject * object, guint property_id, +struct _GESTimelineSourcePrivate +{ + int dummy; +}; + +static void +ges_timeline_source_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { diff --git a/ges/ges-timeline-source.h b/ges/ges-timeline-source.h index d348179f56..b05826fcfa 100644 --- a/ges/ges-timeline-source.h +++ b/ges/ges-timeline-source.h @@ -21,7 +21,7 @@ #define _GES_TIMELINE_SOURCE #include -#include +#include G_BEGIN_DECLS diff --git a/ges/ges-timeline-transition.c b/ges/ges-timeline-transition.c index 4f280b80e4..cf7907b892 100644 --- a/ges/ges-timeline-transition.c +++ b/ges/ges-timeline-transition.c @@ -20,18 +20,20 @@ #include "ges-timeline-transition.h" G_DEFINE_TYPE (GESTimelineTransition, ges_timeline_transition, - GES_TYPE_TIMELINE_OBJECT) + GES_TYPE_TIMELINE_OBJECT); + #define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE_TRANSITION, GESTimelineTransitionPrivate)) - typedef struct _GESTimelineTransitionPrivate GESTimelineTransitionPrivate; + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE_TRANSITION, GESTimelineTransitionPrivate)); - struct _GESTimelineTransitionPrivate - { - int dummy; - }; +typedef struct _GESTimelineTransitionPrivate GESTimelineTransitionPrivate; - static void - ges_timeline_transition_get_property (GObject * object, +struct _GESTimelineTransitionPrivate +{ + int dummy; +}; + +static void +ges_timeline_transition_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index 69d7d89c63..f952491b7c 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -17,7 +17,11 @@ * Boston, MA 02111-1307, USA. */ +#include "gesmarshal.h" #include "ges-timeline.h" +#include "ges-track.h" +#include "ges-timeline-layer.h" +#include "ges.h" /** * GESTimelinePipeline @@ -29,18 +33,31 @@ * */ -G_DEFINE_TYPE (GESTimeline, ges_timeline, GST_TYPE_BIN) +G_DEFINE_TYPE (GESTimeline, ges_timeline, GST_TYPE_BIN); + #define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE, GESTimelinePrivate)) - typedef struct _GESTimelinePrivate GESTimelinePrivate; + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TIMELINE, GESTimelinePrivate)); - struct _GESTimelinePrivate - { - GList *tracks; /* TimelineTracks */ - }; +typedef struct _GESTimelinePrivate GESTimelinePrivate; - static void - ges_timeline_get_property (GObject * object, guint property_id, +struct _GESTimelinePrivate +{ + +}; + +enum +{ + TRACK_ADDED, + TRACK_REMOVED, + LAYER_ADDED, + LAYER_REMOVED, + LAST_SIGNAL +}; + +static guint ges_timeline_signals[LAST_SIGNAL] = { 0 }; + +static void +ges_timeline_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { @@ -82,6 +99,34 @@ ges_timeline_class_init (GESTimelineClass * klass) object_class->set_property = ges_timeline_set_property; object_class->dispose = ges_timeline_dispose; object_class->finalize = ges_timeline_finalize; + + /* Signals + * 'track-added' + * 'track-removed' + * 'layer-added' + * 'layer-removed' + */ + + ges_timeline_signals[TRACK_ADDED] = + g_signal_new ("track-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GESTimelineClass, track_added), NULL, + NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GES_TYPE_TRACK); + + ges_timeline_signals[TRACK_REMOVED] = + g_signal_new ("track-removed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GESTimelineClass, track_removed), + NULL, NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GES_TYPE_TRACK); + + ges_timeline_signals[LAYER_ADDED] = + g_signal_new ("layer-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GESTimelineClass, layer_added), NULL, + NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GES_TYPE_TIMELINE_LAYER); + + ges_timeline_signals[LAYER_REMOVED] = + g_signal_new ("layer-removed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GESTimelineClass, layer_removed), + NULL, NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, + GES_TYPE_TIMELINE_LAYER); } static void @@ -111,16 +156,78 @@ ges_timeline_save (GESTimeline * timeline, gchar * uri) return FALSE; } +static void +layer_object_added_cb (GESTimelineLayer * layer, GESTimelineObject * object, + GESTimeline * timeline) +{ + GList *tmp; + + GST_DEBUG ("New TimelineObject %p added to layer %p", object, layer); + + for (tmp = timeline->tracks; tmp; tmp = g_list_next (tmp)) { + GESTrack *track = (GESTrack *) track; + GESTrackObject *trobj; + + GST_LOG ("Trying with track %p", track); + + if (G_UNLIKELY (!(trobj = + ges_timeline_object_create_track_object (object, track)))) { + GST_WARNING ("Couldn't create TrackObject for TimelineObject"); + continue; + } + + GST_LOG ("Got new TrackObject %p, adding it to track", trobj); + ges_track_add_object (track, trobj); + } + + GST_DEBUG ("done"); +} + + +static void +layer_object_removed_cb (GESTimelineLayer * layer, GESTimelineObject * object, + GESTimeline * timeline) +{ + /* FIXME : IMPLEMENT */ +} + + gboolean ges_timeline_add_layer (GESTimeline * timeline, GESTimelineLayer * layer) { - /* FIXME : IMPLEMENT */ + GST_DEBUG ("timeline:%p, layer:%p", timeline, layer); + + /* We can only add a layer that doesn't already belong to another timeline */ + if (G_UNLIKELY (layer->timeline)) { + GST_WARNING ("Layer belongs to another timeline, can't add it"); + return FALSE; + } /* Add to the list of layers, make sure we don't already control it */ + if (G_UNLIKELY (g_list_find (timeline->layers, (gconstpointer) layer))) { + GST_WARNING ("Layer is already controlled by this timeline"); + return FALSE; + } - /* Assign Tracks to it */ + /* Reference is taken */ + timeline->layers = g_list_append (timeline->layers, g_object_ref (layer)); - return FALSE; + /* Inform the layer that it belongs to a new timeline */ + ges_timeline_layer_set_timeline (layer, timeline); + + /* FIXME : GO OVER THE LIST OF EXISTING TIMELINE OBJECTS IN THAT LAYER + * AND ADD THEM !!! */ + + /* Connect to 'object-added'/'object-removed' signal from the new layer */ + g_signal_connect (layer, "object-added", G_CALLBACK (layer_object_added_cb), + timeline); + g_signal_connect (layer, "object-removed", + G_CALLBACK (layer_object_removed_cb), timeline); + + GST_DEBUG ("Done adding layer, emitting 'layer-added' signal"); + g_signal_emit (timeline, ges_timeline_signals[LAYER_ADDED], 0, layer); + + return TRUE; } gboolean @@ -135,12 +242,33 @@ ges_timeline_remove_layer (GESTimeline * timeline, GESTimelineLayer * layer) gboolean ges_timeline_add_track (GESTimeline * timeline, GESTrack * track) { - /* FIXME : IMPLEMENT */ + GST_DEBUG ("timeline:%p, track:%p", timeline, track); /* Add to the list of tracks, make sure we don't already control it */ + if (G_UNLIKELY (g_list_find (timeline->tracks, (gconstpointer) track))) { + GST_WARNING ("Track is already controlled by this timeline"); + return FALSE; + } + /* Add the track to ourself (as a GstBin) + * Reference is taken ! */ + if (G_UNLIKELY (!gst_bin_add (GST_BIN (timeline), GST_ELEMENT (track)))) { + GST_WARNING ("Couldn't add track to ourself (GST)"); + return FALSE; + } - return FALSE; + /* Add the track to the list of tracks we track */ + timeline->tracks = g_list_append (timeline->tracks, track); + + /* Inform the track that it's currently being used by ourself */ + ges_track_set_timeline (track, timeline); + + GST_DEBUG ("Done adding track, emitting 'track-added' signal"); + + /* emit 'track-added' */ + g_signal_emit (timeline, ges_timeline_signals[TRACK_ADDED], 0, track); + + return TRUE; } gboolean diff --git a/ges/ges-timeline.h b/ges/ges-timeline.h index 89d5546c3c..97b6c63650 100644 --- a/ges/ges-timeline.h +++ b/ges/ges-timeline.h @@ -52,6 +52,11 @@ struct _GESTimeline { struct _GESTimelineClass { GstBinClass parent_class; + + void (*track_added) (GESTimeline *timeline, GESTrack * track); + void (*track_removed) (GESTimeline *timeline, GESTrack * track); + void (*layer_added) (GESTimeline *timeline, GESTimelineLayer *layer); + void (*layer_removed) (GESTimeline *timeline, GESTimelineLayer *layer); }; GType ges_timeline_get_type (void); diff --git a/ges/ges-track-object.c b/ges/ges-track-object.c index a39d3e8654..43e785bd2e 100644 --- a/ges/ges-track-object.c +++ b/ges/ges-track-object.c @@ -18,6 +18,7 @@ */ #include "ges-track-object.h" +#include "ges-timeline-object.h" static GQuark _start_quark; static GQuark _inpoint_quark; @@ -54,6 +55,9 @@ struct _GESTrackObjectPrivate int dummy; }; +static gboolean +ges_track_object_create_gnl_object_func (GESTrackObject * object); + static void ges_track_object_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) @@ -139,6 +143,8 @@ ges_track_object_class_init (GESTrackObjectClass * klass) g_object_class_install_property (object_class, PROP_PRIORITY, g_param_spec_uint ("priority", "Priority", "The priority of the object", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + + klass->create_gnl_object = ges_track_object_create_gnl_object_func; } static void @@ -159,6 +165,8 @@ ges_track_object_new (GESTimelineObject * timelineobj, GESTrack * track) /* Create the associated GnlObject */ ges_track_object_create_gnl_object (obj); + + return obj; } gboolean @@ -217,3 +225,70 @@ ges_track_object_set_priority_internal (GESTrackObject * object, g_object_set (object->gnlobject, "priority", priority, NULL); return TRUE; } + +/* default 'create_gnl_object' virtual method implementation */ +static gboolean +ges_track_object_create_gnl_object_func (GESTrackObject * object) +{ + + return FALSE; +} + +static gboolean +ensure_gnl_object (GESTrackObject * object) +{ + GESTrackObjectClass *class; + gboolean res; + + if (object->gnlobject) + return TRUE; + + class = GES_TRACK_OBJECT_GET_CLASS (object); + + if (G_UNLIKELY (class->create_gnl_object == NULL)) { + GST_ERROR ("No 'create_gnl_object' implementation !"); + return FALSE; + } + + GST_DEBUG ("Calling virtual method"); + + /* call the create_gnl_object virtual method */ + res = class->create_gnl_object (object); + + if (G_UNLIKELY (res && (object->gnlobject == NULL))) { + GST_ERROR + ("'create_gnl_object' implementation returned TRUE but no GnlObject is available"); + return FALSE; + } + + if (res) { + GST_DEBUG ("Got a valid GnlObject, now filling it in"); + + res = + ges_timeline_object_fill_track_object (object->timelineobj, object, + object->gnlobject); + } + + GST_DEBUG ("Returning res:%d", res); + + return res; +} + +void +ges_track_object_set_track (GESTrackObject * object, GESTrack * track) +{ + GST_DEBUG ("object:%p, track:%p", object, track); + + object->track = track; + + ensure_gnl_object (object); +} + +void +ges_track_object_set_timeline_object (GESTrackObject * object, + GESTimelineObject * tlobj) +{ + GST_DEBUG ("object:%p, timeline-object:%p", object, tlobj); + + object->timelineobj = tlobj; +} diff --git a/ges/ges-track-object.h b/ges/ges-track-object.h index 5248efcbf0..5c9bd98b36 100644 --- a/ges/ges-track-object.h +++ b/ges/ges-track-object.h @@ -21,7 +21,8 @@ #define _GES_TRACK_OBJECT #include -#include +#include +#include G_BEGIN_DECLS @@ -73,6 +74,9 @@ GESTrackObject* ges_track_object_new (GESTimelineObject *timelineobj, GESTrack * gboolean ges_track_object_create_gnl_object (GESTrackObject * object); +void ges_track_object_set_track (GESTrackObject * object, GESTrack * track); +void ges_track_object_set_timeline_object (GESTrackObject * object, GESTimelineObject * tlobject); + /* Private methods for GESTimelineObject's usage only */ gboolean ges_track_object_set_start_internal (GESTrackObject * object, guint64 start); gboolean ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint); diff --git a/ges/ges-track.c b/ges/ges-track.c index cc1a3cdd3e..bfcccc1922 100644 --- a/ges/ges-track.c +++ b/ges/ges-track.c @@ -18,6 +18,7 @@ */ #include "ges-track.h" +#include "ges-track-object.h" /** * GESTrack @@ -27,18 +28,20 @@ * Contains the compatible TrackObject(s) */ -G_DEFINE_TYPE (GESTrack, ges_track, GST_TYPE_BIN) -#define GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TRACK, GESTrackPrivate)) - typedef struct _GESTrackPrivate GESTrackPrivate; +G_DEFINE_TYPE (GESTrack, ges_track, GST_TYPE_BIN); - struct _GESTrackPrivate - { - int dummy; - }; +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GES_TYPE_TRACK, GESTrackPrivate)); - static void - ges_track_get_property (GObject * object, guint property_id, +typedef struct _GESTrackPrivate GESTrackPrivate; + +struct _GESTrackPrivate +{ + int dummy; +}; + +static void +ges_track_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { @@ -92,3 +95,40 @@ ges_track_new (void) { return g_object_new (GES_TYPE_TRACK, NULL); } + +void +ges_track_set_timeline (GESTrack * track, GESTimeline * timeline) +{ + GST_DEBUG ("track:%p, timeline:%p", track, timeline); + + track->timeline = timeline; +} + +gboolean +ges_track_add_object (GESTrack * track, GESTrackObject * object) +{ + GST_DEBUG ("track:%p, object:%p", track, object); + + if (G_UNLIKELY (object->track != NULL)) { + GST_WARNING ("Object already belongs to another track"); + return FALSE; + } + + if (G_UNLIKELY (object->gnlobject != NULL)) { + GST_ERROR ("TrackObject doesn't have a gnlobject !"); + return FALSE; + } + + ges_track_object_set_track (object, track); + + GST_DEBUG ("Adding object to ourself"); + + /* make sure the object has a valid gnlobject ! */ + if (G_UNLIKELY (!gst_bin_add (GST_BIN (track->composition), + object->gnlobject))) { + GST_WARNING ("Couldn't add object to the GnlComposition"); + return FALSE; + } + + return TRUE; +} diff --git a/ges/ges-track.h b/ges/ges-track.h index 6046d05fa7..fa8804d8b2 100644 --- a/ges/ges-track.h +++ b/ges/ges-track.h @@ -46,6 +46,8 @@ G_BEGIN_DECLS struct _GESTrack { GstBin parent; + GESTimeline * timeline; + GstElement * composition; /* The composition associated with this track */ }; @@ -57,7 +59,9 @@ GType ges_track_get_type (void); GESTrack* ges_track_new (void); -gboolean ges_track_add_object (GESTrack *track, GESTrackObject * object); +void ges_track_set_timeline (GESTrack * track, GESTimeline *timeline); + +gboolean ges_track_add_object (GESTrack * track, GESTrackObject * object); G_END_DECLS