diff --git a/ges/ges-group.c b/ges/ges-group.c index b2cf37e6ac..f8e13c73e5 100644 --- a/ges/ges-group.c +++ b/ges/ges-group.c @@ -402,7 +402,23 @@ _set_start (GESTimelineElement * element, GstClockTime start) static gboolean _set_inpoint (GESTimelineElement * element, GstClockTime inpoint) { - return FALSE; + if (inpoint != 0) { + GST_WARNING_OBJECT (element, "The in-point of a group has no meaning," + " it can not be set to a non-zero value"); + return FALSE; + } + return TRUE; +} + +static gboolean +_set_max_duration (GESTimelineElement * element, GstClockTime max_duration) +{ + if (GST_CLOCK_TIME_IS_VALID (max_duration)) { + GST_WARNING_OBJECT (element, "The max-duration of a group has no " + "meaning, it can not be set to a valid GstClockTime value"); + return FALSE; + } + return TRUE; } static gboolean @@ -762,6 +778,7 @@ ges_group_class_init (GESGroupClass * klass) element_class->trim = _trim; element_class->set_duration = _set_duration; element_class->set_inpoint = _set_inpoint; + element_class->set_max_duration = _set_max_duration; element_class->set_start = _set_start; element_class->set_priority = _set_priority; element_class->paste = _paste; diff --git a/ges/ges-timeline-element.c b/ges/ges-timeline-element.c index a21c8c0ce1..3cabaef926 100644 --- a/ges/ges-timeline-element.c +++ b/ges/ges-timeline-element.c @@ -430,7 +430,7 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass) */ properties[PROP_INPOINT] = g_param_spec_uint64 ("in-point", "In-point", "The in-point", 0, - G_MAXUINT64, 0, G_PARAM_READWRITE); + G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); /** * GESTimelineElement:duration: @@ -462,7 +462,7 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass) properties[PROP_MAX_DURATION] = g_param_spec_uint64 ("max-duration", "Maximum duration", "The maximum duration of the object", 0, G_MAXUINT64, GST_CLOCK_TIME_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY); /** * GESTimelineElement:priority: @@ -1113,8 +1113,11 @@ ges_timeline_element_set_inpoint (GESTimelineElement * self, g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE); GST_DEBUG_OBJECT (self, "current inpoint: %" GST_TIME_FORMAT - " new inpoint: %" GST_TIME_FORMAT, GST_TIME_ARGS (inpoint), - GST_TIME_ARGS (GES_TIMELINE_ELEMENT_INPOINT (self))); + " new inpoint: %" GST_TIME_FORMAT, GST_TIME_ARGS (self->inpoint), + GST_TIME_ARGS (inpoint)); + + if (G_UNLIKELY (inpoint == self->inpoint)) + return TRUE; klass = GES_TIMELINE_ELEMENT_GET_CLASS (self); @@ -1123,13 +1126,13 @@ ges_timeline_element_set_inpoint (GESTimelineElement * self, * duplicate notify signals? Rather than relying on the return value * being -1 for setting that succeeds but does not want a notify * signal because it will call this method on itself a second time. */ - gint res = klass->set_inpoint (self, inpoint); - if (res == TRUE) { - self->inpoint = inpoint; - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INPOINT]); - } + if (!klass->set_inpoint (self, inpoint)) + return FALSE; - return ! !res; + self->inpoint = inpoint; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INPOINT]); + + return TRUE; } GST_DEBUG_OBJECT (self, "No set_inpoint virtual method implementation" @@ -1156,21 +1159,29 @@ ges_timeline_element_set_max_duration (GESTimelineElement * self, g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE); + GST_DEBUG_OBJECT (self, "current max-duration: %" GST_TIME_FORMAT + " new max-duration: %" GST_TIME_FORMAT, + GST_TIME_ARGS (self->maxduration), GST_TIME_ARGS (maxduration)); + + if (G_UNLIKELY (maxduration == self->maxduration)) + return TRUE; + klass = GES_TIMELINE_ELEMENT_GET_CLASS (self); - GST_DEBUG_OBJECT (self, "current duration: %" GST_TIME_FORMAT - " new duration: %" GST_TIME_FORMAT, - GST_TIME_ARGS (GES_TIMELINE_ELEMENT_MAX_DURATION (self)), - GST_TIME_ARGS (maxduration)); - if (klass->set_max_duration) { - if (klass->set_max_duration (self, maxduration) == FALSE) + if (!klass->set_max_duration (self, maxduration)) return FALSE; + self->maxduration = maxduration; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MAX_DURATION]); + + return TRUE; } - self->maxduration = maxduration; - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MAX_DURATION]); - return TRUE; + GST_DEBUG_OBJECT (self, "No set_max_duration virtual method implementation" + " on class %s. Can not set max-duration %" GST_TIME_FORMAT, + G_OBJECT_CLASS_NAME (klass), GST_TIME_ARGS (maxduration)); + + return FALSE; } /** diff --git a/ges/ges-timeline-element.h b/ges/ges-timeline-element.h index 4ebe1e0b0c..94af06b993 100644 --- a/ges/ges-timeline-element.h +++ b/ges/ges-timeline-element.h @@ -175,11 +175,17 @@ struct _GESTimelineElement * subclass handled emitting the notify signal and the base class should * return %TRUE. * @set_inpoint: Method called just before the - * #GESTimelineElement:in-point is set. A return of -1 means that the - * subclass handled emitting the notify signal and the base class should - * return %TRUE. + * #GESTimelineElement:in-point is set to a new value. This method should + * not set the #GESTimelineElement:in-point itself, but should check + * whether it can be changed to the new value and to otherwise prepare the + * element in response to what the new value will be. A return of %FALSE + * means that the property should not be set. * @set_max_duration: Method called just before the - * #GESTimelineElement:max-duration is set. + * #GESTimelineElement:max-duration is set. This method should + * not set the #GESTimelineElement:max-duration itself, but should check + * whether it can be changed to the new value and to otherwise prepare the + * element in response to what the new value will be. A return of %FALSE + * means that the property should not be set. * @set_priority: Method called just before the * #GESTimelineElement:in-point is set. * @ripple_end: Method to ripple an object on its #GES_EDGE_END edge.