diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index daee536af3..131ac1e812 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -65,6 +65,7 @@ GESTrackObjectClass GES_TRACK_OBJECT_DURATION GES_TRACK_OBJECT_INPOINT GES_TRACK_OBJECT_PRIORITY +GES_TRACK_OBJECT_PRIORITY_OFFSET GES_TRACK_OBJECT_START ges_track_object_set_active diff --git a/ges/ges-track-object.c b/ges/ges-track-object.c index c5dfce9400..fd712526f4 100644 --- a/ges/ges-track-object.c +++ b/ges/ges-track-object.c @@ -78,6 +78,8 @@ void gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg void gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED, GESTrackObject * obj); +static gboolean ges_track_object_update_priority (GESTrackObject * object); + static void ges_track_object_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) @@ -95,7 +97,7 @@ ges_track_object_get_property (GObject * object, guint property_id, g_value_set_uint64 (value, tobj->duration); break; case PROP_PRIORITY: - g_value_set_uint (value, tobj->priority); + g_value_set_uint (value, tobj->base_priority); break; case PROP_ACTIVE: g_value_set_boolean (value, tobj->active); @@ -223,7 +225,7 @@ ges_track_object_init (GESTrackObject * self) self->pending_start = 0; self->pending_inpoint = 0; self->pending_duration = GST_SECOND; - self->pending_priority = 1; + self->pending_gnl_priority = 1; self->pending_active = TRUE; } @@ -279,19 +281,61 @@ ges_track_object_set_duration_internal (GESTrackObject * object, return TRUE; } +/* NOTE: we handle priority differently than other properties! the gnlpriority + * is object->base_priority + object->priority_offset! A change to either one + * will trigger an update to the gnonlin priority and a subsequent property + * notification. + */ + gboolean ges_track_object_set_priority_internal (GESTrackObject * object, guint32 priority) { + guint32 save; + save = object->base_priority; GST_DEBUG ("object:%p, priority:%d", object, priority); + object->base_priority = priority; + if (!ges_track_object_update_priority (object)) { + object->base_priority = save; + return FALSE; + } + return TRUE; +} + +gboolean +ges_track_object_set_priority_offset_internal (GESTrackObject * object, + guint32 priority_offset) +{ + guint32 save; + save = object->priority_offset; + GST_DEBUG ("object:%p, offset:%d", priority_offset); + + object->priority_offset = priority_offset; + if (!ges_track_object_update_priority (object)) { + object->base_priority = save; + return FALSE; + } + return TRUE; +} + +static gboolean +ges_track_object_update_priority (GESTrackObject * object) +{ + guint32 priority, offset, gnl; + priority = object->base_priority; + offset = object->priority_offset; + gnl = priority + offset; + GST_DEBUG ("object:%p, base:%d, offset:%d: gnl:%d", object, priority, offset, + gnl); + if (object->gnlobject != NULL) { - if (G_UNLIKELY (priority == object->priority)) + if (G_UNLIKELY (gnl == object->gnl_priority)) return FALSE; - g_object_set (object->gnlobject, "priority", priority, NULL); + g_object_set (object->gnlobject, "priority", gnl, NULL); } else - object->pending_priority = priority; + object->pending_gnl_priority = gnl; return TRUE; } @@ -367,12 +411,13 @@ gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED, g_object_get (gnlobject, "priority", &priority, NULL); - GST_DEBUG ("gnlobject priority : %d current : %d", priority, obj->priority); + GST_DEBUG ("gnlobject priority : %d current : %d", priority, + obj->gnl_priority); - if (priority != obj->priority) { - obj->priority = priority; - if (klass->priority_changed) - klass->priority_changed (obj, priority); + if (priority != obj->gnl_priority) { + obj->gnl_priority = priority; + if (klass->gnl_priority_changed) + klass->gnl_priority_changed (obj, priority); /* FIXME : emit changed */ } } @@ -486,7 +531,7 @@ ensure_gnl_object (GESTrackObject * object) "media-duration", object->pending_duration, "start", object->pending_start, "media-start", object->pending_inpoint, - "priority", object->pending_priority, + "priority", object->pending_gnl_priority, "active", object->pending_active, NULL); } diff --git a/ges/ges-track-object.h b/ges/ges-track-object.h index cd0dd7cfb9..71cd720d5a 100644 --- a/ges/ges-track-object.h +++ b/ges/ges-track-object.h @@ -76,7 +76,7 @@ G_BEGIN_DECLS * * The priority of the object (in nanoseconds). */ -#define GES_TRACK_OBJECT_PRIORITY(obj) (((GESTrackObject*)obj)->priority) +#define GES_TRACK_OBJECT_PRIORITY(obj) (((GESTrackObject*)obj)->base_priority) /** * GESTrackObject: @@ -86,7 +86,9 @@ G_BEGIN_DECLS * @start: Position (in nanoseconds) of the object the track. * @inpoint: in-point (in nanoseconds) of the object in the track. * @duration: Duration of the object - * @priority: Priority of the object in the track (0:top priority) + * @base_priority: base priority of the object in the track (0:top priority) + * @priority_offset: added to the track object (0:top priority) + * @gnl_priority: the cached gnl priority (base + offset) * @active: Whether the object is to be used or not. * * The GESTrackObject base class. Only sub-classes can access these fields. @@ -104,17 +106,22 @@ struct _GESTrackObject { guint64 start; guint64 inpoint; guint64 duration; - guint32 priority; + guint32 gnl_priority; gboolean active; + /* cache the base priority and offset */ + guint32 base_priority; + guint32 priority_offset; + /*< private >*/ /* These fields are only used before the gnlobject is available */ guint64 pending_start; guint64 pending_inpoint; guint64 pending_duration; - guint32 pending_priority; + guint32 pending_gnl_priority; gboolean pending_active; + GstElement *gnlobject; }; @@ -125,7 +132,7 @@ struct _GESTrackObject { * @start_changed: start property of gnlobject has changed * @media_start_changed: media-start property of gnlobject has changed * @duration_changed: duration property glnobject has changed - * @priority_changed: duration property glnobject has changed + * @gnl_priority_changed: duration property glnobject has changed * @active_changed: active property of gnlobject has changed * * Subclasses can override the @create_gnl_object method to override what type @@ -144,7 +151,7 @@ struct _GESTrackObjectClass { void (*start_changed) (GESTrackObject *object, guint64 start); void (*media_start_changed) (GESTrackObject *object, guint64 media_start); - void (*priority_changed) (GESTrackObject *object, guint priority); + void (*gnl_priority_changed) (GESTrackObject *object, guint priority); void (*duration_changed) (GESTrackObject *object, guint64 duration); void (*active_changed) (GESTrackObject *object, gboolean active); }; @@ -159,6 +166,9 @@ gboolean ges_track_object_set_start_internal (GESTrackObject * object, guint64 s gboolean ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint); gboolean ges_track_object_set_duration_internal (GESTrackObject * object, guint64 duration); gboolean ges_track_object_set_priority_internal (GESTrackObject * object, guint32 priority); +gboolean ges_track_object_set_priority_offset_internal(GESTrackObject * + object, guint32 priority_offset); + gboolean ges_track_object_set_active (GESTrackObject * object, gboolean active); G_END_DECLS