diff --git a/bindings/python/ges.defs b/bindings/python/ges.defs index 9828e93a5a..7c5d1d0f79 100644 --- a/bindings/python/ges.defs +++ b/bindings/python/ges.defs @@ -992,6 +992,21 @@ ) ) +(define-method set_max_duration + (of-object "GESTimelineObject") + (c-name "ges_timeline_object_set_max_duration") + (return-type "none") + (parameters + '("guint64" "duration") + ) +) + +(define-method get_max_duration + (of-object "GESTimelineObject") + (c-name "ges_timeline_object_get_max_duration") + (return-type "guint64") +) + (define-method set_priority (of-object "GESTimelineObject") (c-name "ges_timeline_object_set_priority") @@ -1887,6 +1902,21 @@ (return-type "guint64") ) +(define-method get_max_duration + (of-object "GESTrackObject") + (c-name "ges_track_object_get_max_duration") + (return-type "guint64") +) + +(define-method set_max_duration + (of-object "GESTrackObject") + (c-name "ges_track_object_set_max_duration") + (return-type "none") + (parameters + '("guint64" "duration") + ) +) + (define-method get_duration (of-object "GESTrackObject") (c-name "ges_track_object_get_duration") diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 647c99fab7..7a0cc4315e 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -79,6 +79,7 @@ GES_TYPE_TRACK GESTrackObject GESTrackObjectClass ges_track_object_set_duration +ges_track_object_set_max_duration ges_track_object_set_inpoint ges_track_object_set_priority ges_track_object_set_start @@ -92,6 +93,7 @@ ges_track_object_get_element ges_track_object_get_start ges_track_object_get_inpoint ges_track_object_get_duration +ges_track_object_get_max_duration ges_track_object_get_priority ges_track_object_is_active ges_track_object_lookup_child diff --git a/ges/ges-timeline-file-source.c b/ges/ges-timeline-file-source.c index d2e2da9950..8df045691f 100644 --- a/ges/ges-timeline-file-source.c +++ b/ges/ges-timeline-file-source.c @@ -42,15 +42,12 @@ struct _GESTimelineFileSourcePrivate gboolean mute; gboolean is_image; - - guint64 maxduration; }; enum { PROP_0, PROP_URI, - PROP_MAX_DURATION, PROP_MUTE, PROP_IS_IMAGE, }; @@ -62,6 +59,9 @@ static GESTrackObject void ges_timeline_filesource_set_uri (GESTimelineFileSource * self, gchar * uri); +static void +filesource_set_max_duration (GESTimelineObject * object, guint64 maxduration); + static void ges_timeline_filesource_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) @@ -75,9 +75,6 @@ ges_timeline_filesource_get_property (GObject * object, guint property_id, case PROP_MUTE: g_value_set_boolean (value, priv->mute); break; - case PROP_MAX_DURATION: - g_value_set_uint64 (value, priv->maxduration); - break; case PROP_IS_IMAGE: g_value_set_boolean (value, priv->is_image); break; @@ -99,10 +96,6 @@ ges_timeline_filesource_set_property (GObject * object, guint property_id, case PROP_MUTE: ges_timeline_filesource_set_mute (tfs, g_value_get_boolean (value)); break; - case PROP_MAX_DURATION: - ges_timeline_filesource_set_max_duration (tfs, - g_value_get_uint64 (value)); - break; case PROP_IS_IMAGE: ges_timeline_filesource_set_is_image (tfs, g_value_get_boolean (value)); break; @@ -143,19 +136,6 @@ ges_timeline_filesource_class_init (GESTimelineFileSourceClass * klass) g_param_spec_string ("uri", "URI", "uri of the resource", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** - * GESTimelineFileSource:max-duration: - * - * The maximum duration (in nanoseconds) of the file. - * - * If not set before adding the object to a layer, it will be discovered - * asynchronously. Connect to 'notify::max-duration' to be notified of it. - */ - g_object_class_install_property (object_class, PROP_MAX_DURATION, - g_param_spec_uint64 ("max-duration", "Maximum duration", - "The duration of the file", 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** * GESTimelineFileSource:mute: * @@ -178,6 +158,7 @@ ges_timeline_filesource_class_init (GESTimelineFileSourceClass * klass) timobj_class->create_track_object = ges_timeline_filesource_create_track_object; + timobj_class->set_max_duration = filesource_set_max_duration; timobj_class->need_fill_track = FALSE; } @@ -234,24 +215,26 @@ void ges_timeline_filesource_set_max_duration (GESTimelineFileSource * self, guint64 maxduration) { - GESTimelineObject *object = GES_TIMELINE_OBJECT (self); + ges_timeline_object_set_max_duration (GES_TIMELINE_OBJECT (self), + maxduration); +} + +void +filesource_set_max_duration (GESTimelineObject * object, guint64 maxduration) +{ GList *tmp, *tckobjs; - self->priv->maxduration = maxduration; if (object->duration == GST_CLOCK_TIME_NONE || object->duration == 0) { /* If we don't have a valid duration, use the max duration */ - g_object_set (self, "duration", self->priv->maxduration - object->inpoint, - NULL); + g_object_set (object, "duration", maxduration - object->inpoint, NULL); } - tckobjs = ges_timeline_object_get_track_objects (GES_TIMELINE_OBJECT (self)); + tckobjs = ges_timeline_object_get_track_objects (object); for (tmp = tckobjs; tmp; tmp = g_list_next (tmp)) { g_object_set (tmp->data, "max-duration", maxduration, NULL); - - /* We free the list in the same loop */ - g_object_unref (tmp->data); - g_list_free_1 (tmp); } + + g_list_free_full (tckobjs, g_object_unref); } /** @@ -309,7 +292,7 @@ ges_timeline_filesource_is_muted (GESTimelineFileSource * self) guint64 ges_timeline_filesource_get_max_duration (GESTimelineFileSource * self) { - return self->priv->maxduration; + return ges_timeline_object_get_max_duration (GES_TIMELINE_OBJECT (self)); } /** diff --git a/ges/ges-timeline-object.c b/ges/ges-timeline-object.c index eb3b74911d..949c8891bd 100644 --- a/ges/ges-timeline-object.c +++ b/ges/ges-timeline-object.c @@ -42,6 +42,8 @@ gboolean ges_timeline_object_create_track_objects_func (GESTimelineObject * object, GESTrack * track); +void default_set_max_duration (GESTimelineObject * object, guint64 maxduration); + static void track_object_start_changed_cb (GESTrackObject * child, GParamSpec * arg G_GNUC_UNUSED, GESTimelineObject * object); @@ -130,6 +132,8 @@ struct _GESTimelineObjectPrivate gboolean ignore_notifies; gboolean is_moving; + guint64 maxduration; + GList *mappings; guint nb_effects; @@ -150,6 +154,7 @@ enum PROP_HEIGHT, PROP_LAYER, PROP_SUPPORTED_FORMATS, + PROP_MAX_DURATION, PROP_LAST }; @@ -183,6 +188,9 @@ ges_timeline_object_get_property (GObject * object, guint property_id, case PROP_SUPPORTED_FORMATS: g_value_set_flags (value, tobj->priv->supportedformats); break; + case PROP_MAX_DURATION: + g_value_set_uint64 (value, tobj->priv->maxduration); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -214,6 +222,9 @@ ges_timeline_object_set_property (GObject * object, guint property_id, ges_timeline_object_set_supported_formats (tobj, g_value_get_flags (value)); break; + case PROP_MAX_DURATION: + ges_timeline_object_set_max_duration (tobj, g_value_get_uint64 (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -229,6 +240,7 @@ ges_timeline_object_class_init (GESTimelineObjectClass * klass) object_class->get_property = ges_timeline_object_get_property; 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->track_object_added = NULL; klass->track_object_released = NULL; @@ -372,6 +384,18 @@ ges_timeline_object_class_init (GESTimelineObjectClass * klass) G_SIGNAL_RUN_FIRST, 0, NULL, NULL, ges_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GES_TYPE_TRACK_OBJECT); + /** + * GESTimelineObject:max-duration: + * + * The maximum duration (in nanoseconds) of the #GESTimelineObject. + * + * Since: 0.10.XX + */ + g_object_class_install_property (object_class, PROP_MAX_DURATION, + g_param_spec_uint64 ("max-duration", "Maximum duration", + "The duration of the object", 0, G_MAXUINT64, G_MAXUINT64, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + klass->need_fill_track = TRUE; } @@ -386,6 +410,7 @@ ges_timeline_object_init (GESTimelineObject * self) self->priv->layer = NULL; self->priv->nb_effects = 0; self->priv->is_moving = FALSE; + self->priv->maxduration = G_MAXUINT64; } /** @@ -455,6 +480,15 @@ ges_timeline_object_create_track_objects (GESTimelineObject * object, return klass->create_track_objects (object, track); } +/* Default implementation of default_set_max_duration */ +void +default_set_max_duration (GESTimelineObject * object, guint64 maxduration) +{ + GList *tmp; + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) + g_object_set (tmp->data, "max-duration", maxduration, NULL); +} + /* * default implementation of GESTimelineObjectClass::create_track_objects */ @@ -557,6 +591,7 @@ ges_timeline_object_add_track_object (GESTimelineObject * object, GESTrackObject ges_track_object_set_start (trobj, object->start); ges_track_object_set_duration (trobj, object->duration); ges_track_object_set_inpoint (trobj, object->inpoint); + ges_track_object_set_max_duration (trobj, object->priv->maxduration); if (klass->track_object_added) { GST_DEBUG ("Calling track_object_added subclass method"); @@ -1454,6 +1489,45 @@ ges_timeline_object_objects_set_locked (GESTimelineObject * object, } } +/** + * ges_timeline_object_get_max_duration: + * @object: The #GESTimelineObject to retrieve max duration from + * + * Get the max duration of @object. + * + * Returns: The max duration of @object + * + * Since: 0.10.XX + */ +guint64 +ges_timeline_object_get_max_duration (GESTimelineObject * object) +{ + g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), 0); + + return object->priv->maxduration; +} + +/** + * ges_timeline_object_set_max_duration: + * @object: The #GESTimelineObject to retrieve max duration from + * @maxduration: The maximum duration of @object + * + * Returns: Set the max duration of @object + * + * Since: 0.10.XX + */ +void +ges_timeline_object_set_max_duration (GESTimelineObject * object, + guint64 maxduration) +{ + GESTimelineObjectClass *klass = GES_TIMELINE_OBJECT_GET_CLASS (object); + + g_return_if_fail (GES_IS_TIMELINE_OBJECT (object)); + + object->priv->maxduration = maxduration; + klass->set_max_duration (object, maxduration); +} + static void update_height (GESTimelineObject * object) { diff --git a/ges/ges-timeline-object.h b/ges/ges-timeline-object.h index 2809dc8920..c116e39a9a 100644 --- a/ges/ges-timeline-object.h +++ b/ges/ges-timeline-object.h @@ -184,8 +184,10 @@ struct _GESTimelineObject { * @need_fill_track: Set to TRUE if @fill_track_object needs to be called. * @track_object_added: Should be overridden by subclasses if they need to perform an * operation when a #GESTrackObject is added. Since: 0.10.2 - * @track_object_released: Should be overridden by subclassed if they need to perform + * @track_object_released: Should be overridden by subclasses if they need to perform * action when a #GESTrackObject is released. Since: 0.10.2 + * @set_max_duration: Should be overridden by subclasses if they need to perform + * action when a changing the maximum duration. Since: 0.10.XX * * Subclasses can override the @create_track_object and @fill_track_object methods. */ @@ -205,10 +207,12 @@ struct _GESTimelineObjectClass { GESTrackObject *tck_object); void (*track_object_released) (GESTimelineObject *object, GESTrackObject *tck_object); + void (*set_max_duration ) (GESTimelineObject *object, + guint64 maxduration); /*< private >*/ /* Padding for API extension */ - gpointer _ges_reserved[GES_PADDING - 2]; + gpointer _ges_reserved[GES_PADDING - 3]; }; GType ges_timeline_object_get_type (void); @@ -220,9 +224,13 @@ void ges_timeline_object_set_inpoint (GESTimelineObject * object, guint64 inpoint); void ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration); +void ges_timeline_object_set_max_duration (GESTimelineObject * object, + guint64 maxduration); void ges_timeline_object_set_priority (GESTimelineObject * object, guint priority); +guint64 ges_timeline_object_get_max_duration (GESTimelineObject * object); + void ges_timeline_object_set_layer (GESTimelineObject * object, GESTimelineLayer * layer); diff --git a/ges/ges-track-filesource.c b/ges/ges-track-filesource.c index 91b6c39db6..d4f3d27332 100644 --- a/ges/ges-track-filesource.c +++ b/ges/ges-track-filesource.c @@ -34,14 +34,13 @@ G_DEFINE_TYPE (GESTrackFileSource, ges_track_filesource, GES_TYPE_TRACK_SOURCE); struct _GESTrackFileSourcePrivate { - guint64 maxduration; + void *dummy; }; enum { PROP_0, - PROP_URI, - PROP_MAX_DURATION + PROP_URI }; static void @@ -54,9 +53,6 @@ ges_track_filesource_get_property (GObject * object, guint property_id, case PROP_URI: g_value_set_string (value, tfs->uri); break; - case PROP_MAX_DURATION: - g_value_set_uint64 (value, tfs->priv->maxduration); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -72,9 +68,6 @@ ges_track_filesource_set_property (GObject * object, guint property_id, case PROP_URI: tfs->uri = g_value_dup_string (value); break; - case PROP_MAX_DURATION: - tfs->priv->maxduration = g_value_get_uint64 (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -114,19 +107,6 @@ ges_track_filesource_class_init (GESTrackFileSourceClass * klass) object_class->set_property = ges_track_filesource_set_property; object_class->dispose = ges_track_filesource_dispose; - /** - * GESTrackFileSource:max-duration: - * - * The maximum duration (in nanoseconds) of the file. - * - * If not set before adding the object to a layer, it will be discovered - * asynchronously. Connect to 'notify::max-duration' to be notified of it. - */ - g_object_class_install_property (object_class, PROP_MAX_DURATION, - g_param_spec_uint64 ("max-duration", "Maximum duration", - "The duration of the file", 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** * GESTrackFileSource:uri * diff --git a/ges/ges-track-object.c b/ges/ges-track-object.c index ec76d1fd45..ec8dc2c24a 100644 --- a/ges/ges-track-object.c +++ b/ges/ges-track-object.c @@ -61,6 +61,8 @@ struct _GESTrackObjectPrivate gboolean valid; + guint64 maxduration; + gboolean locked; /* If TRUE, then moves in sync with its controlling * GESTimelineObject */ }; @@ -74,6 +76,7 @@ enum PROP_PRIORITY, PROP_ACTIVE, PROP_LOCKED, + PROP_MAX_DURATION, PROP_LAST }; @@ -150,6 +153,9 @@ ges_track_object_get_property (GObject * object, guint property_id, case PROP_LOCKED: g_value_set_boolean (value, ges_track_object_is_locked (tobj)); break; + case PROP_MAX_DURATION: + g_value_set_uint64 (value, tobj->priv->maxduration); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -180,6 +186,9 @@ ges_track_object_set_property (GObject * object, guint property_id, case PROP_LOCKED: ges_track_object_set_locked_internal (tobj, g_value_get_boolean (value)); break; + case PROP_MAX_DURATION: + ges_track_object_set_max_duration (tobj, g_value_get_uint64 (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -291,6 +300,18 @@ ges_track_object_class_init (GESTrackObjectClass * klass) g_object_class_install_property (object_class, PROP_LOCKED, properties[PROP_LOCKED]); + /** + * GESTrackObject:max-duration: + * + * The maximum duration (in nanoseconds) of the #GESTrackObject. + * + * Since: 0.10.XX + */ + g_object_class_install_property (object_class, PROP_MAX_DURATION, + g_param_spec_uint64 ("max-duration", "Maximum duration", + "The duration of the object", 0, G_MAXUINT64, G_MAXUINT64, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** * GESTrackObject::deep-notify: * @track_object: a #GESTrackObject @@ -844,7 +865,6 @@ ges_track_object_get_track (GESTrackObject * object) return object->priv->track; } - void ges_track_object_set_timeline_object (GESTrackObject * object, GESTimelineObject * tlobj) @@ -1424,3 +1444,38 @@ prop_hash_not_set: return NULL; } } + +/** + * ges_track_object_get_max_duration: + * @object: The #GESTrackObject to retrieve max duration from + * + * Get the max duration of @object. + * + * Returns: The max duration of @object + * + * Since: 0.10.XX + */ +guint64 +ges_track_object_get_max_duration (GESTrackObject * object) +{ + g_return_val_if_fail (GES_IS_TRACK_OBJECT (object), 0); + + return object->priv->maxduration; +} + +/** + * ges_track_object_set_max_duration: + * @object: The #GESTrackObject to retrieve max duration from + * @maxduration: The maximum duration of @object + * + * Returns: Set the max duration of @object + * + * Since: 0.10.XX + */ +void +ges_track_object_set_max_duration (GESTrackObject * object, guint64 maxduration) +{ + g_return_if_fail (GES_IS_TRACK_OBJECT (object)); + + object->priv->maxduration = maxduration; +} diff --git a/ges/ges-track-object.h b/ges/ges-track-object.h index fdd18f3e98..b7efa93aa3 100644 --- a/ges/ges-track-object.h +++ b/ges/ges-track-object.h @@ -173,6 +173,9 @@ void ges_track_object_set_inpoint (GESTrackObject * object, void ges_track_object_set_duration (GESTrackObject * object, guint64 duration); +void ges_track_object_set_max_duration (GESTrackObject * object, + guint64 maxduration); + void ges_track_object_set_priority (GESTrackObject * object, guint32 priority); @@ -182,6 +185,7 @@ gboolean ges_track_object_set_active (GESTrackObject * object, guint64 ges_track_object_get_start (GESTrackObject * object); guint64 ges_track_object_get_inpoint (GESTrackObject * object); guint64 ges_track_object_get_duration (GESTrackObject * object); +guint64 ges_track_object_get_max_duration (GESTrackObject * object); guint32 ges_track_object_get_priority (GESTrackObject * object); gboolean ges_track_object_is_active (GESTrackObject * object); diff --git a/tests/check/ges/save_and_load.c b/tests/check/ges/save_and_load.c index a53549c4e6..417aa7d0a6 100644 --- a/tests/check/ges/save_and_load.c +++ b/tests/check/ges/save_and_load.c @@ -122,6 +122,7 @@ GST_START_TEST (test_keyfile_save) KEY ("Object0", "duration", "2000000000"); KEY ("Object0", "priority", "2"); KEY ("Object0", "supported-formats", "GES_TRACK_TYPE_UNKNOWN"); + KEY ("Object0", "max-duration", "18446744073709551615"); KEY ("Object0", "mute", "false"); KEY ("Object0", "vpattern", "100% Black"); KEY ("Object0", "freq", "440"); @@ -142,6 +143,7 @@ GST_START_TEST (test_keyfile_save) KEY ("Object1", "duration", "500000000"); KEY ("Object1", "priority", "1"); KEY ("Object1", "supported-formats", "GES_TRACK_TYPE_UNKNOWN"); + KEY ("Object1", "max-duration", "18446744073709551615"); KEY ("Object1", "vtype", "A bar moves from left to right"); COMPARE; @@ -157,6 +159,7 @@ GST_START_TEST (test_keyfile_save) KEY ("Object2", "duration", "2000000000"); KEY ("Object2", "priority", "3"); KEY ("Object2", "supported-formats", "GES_TRACK_TYPE_UNKNOWN"); + KEY ("Object2", "max-duration", "18446744073709551615"); KEY ("Object2", "mute", "false"); KEY ("Object2", "vpattern", "100% Black"); KEY ("Object2", "freq", "440"); @@ -188,6 +191,7 @@ GST_START_TEST (test_keyfile_save) KEY ("Object3", "duration", "1000000000"); KEY ("Object3", "priority", "0"); KEY ("Object3", "supported-formats", "GES_TRACK_TYPE_UNKNOWN"); + KEY ("Object3", "max-duration", "18446744073709551615"); KEY ("Object3", "mute", "false"); KEY ("Object3", "text", "\"the\\\\ quick\\\\ brown\\\\ fox\""); KEY ("Object3", "font-desc", "\"Serif\\\\ 36\"");