timeline-element: make in-point and max-duration EXPLICIT_NOTIFY

As such, they only emit a signal if their value changes, either through
their _set_inpoint or _set_max_duration methods, or through
g_object_set, etc.

Also, we now require the ->set_max_duration method to be implemented.
This was added to GESGroup, which will only allow the max-duration to be
set to GST_CLOCK_TIME_NONE.
This commit is contained in:
Henry Wilkes 2020-03-10 11:35:23 +00:00
parent 5f3e8caabc
commit 7725e48a80
3 changed files with 58 additions and 24 deletions

View file

@ -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;

View file

@ -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;
}
/**

View file

@ -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.