mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
clip: use time translation for split
The new in-point should be the media position corresponding to the media position. media_duration_factor is no longer needed. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/177>
This commit is contained in:
parent
e36e99e1ce
commit
364c112d66
4 changed files with 33 additions and 55 deletions
|
@ -2957,8 +2957,9 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
|||
{
|
||||
GList *tmp, *transitions = NULL;
|
||||
GESClip *new_object;
|
||||
GstClockTime start, inpoint, duration, old_duration, new_duration;
|
||||
gdouble media_duration_factor;
|
||||
gboolean no_core = FALSE;
|
||||
GstClockTime start, inpoint, duration, old_duration, new_duration,
|
||||
new_inpoint;
|
||||
GESTimelineElement *element;
|
||||
GESTimeline *timeline;
|
||||
GHashTable *track_for_copy;
|
||||
|
@ -2985,6 +2986,18 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
|||
layer_prio = ges_timeline_element_get_layer_priority (element);
|
||||
|
||||
old_duration = position - start;
|
||||
new_duration = duration + start - position;
|
||||
/* convert the split position into an internal core time */
|
||||
new_inpoint = _convert_core_time (clip, position, FALSE, &no_core, error);
|
||||
|
||||
/* if the split clip does not contain any active core elements with
|
||||
* an internal source, just set the in-point to 0 for the new_object */
|
||||
if (no_core)
|
||||
new_inpoint = 0;
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (new_inpoint))
|
||||
return NULL;
|
||||
|
||||
if (timeline
|
||||
&& !timeline_tree_can_move_element (timeline_get_tree (timeline), element,
|
||||
layer_prio, start, old_duration, error)) {
|
||||
|
@ -2995,7 +3008,6 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
new_duration = duration + start - position;
|
||||
if (timeline
|
||||
&& !timeline_tree_can_move_element (timeline_get_tree (timeline), element,
|
||||
layer_prio, position, new_duration, error)) {
|
||||
|
@ -3011,16 +3023,27 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
|||
|
||||
/* Create the new Clip */
|
||||
new_object = GES_CLIP (ges_timeline_element_copy (element, FALSE));
|
||||
new_object->priv->prevent_duration_limit_update = TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (new_object, "New 'splitted' clip");
|
||||
/* Set new timing properties on the Clip */
|
||||
media_duration_factor =
|
||||
ges_timeline_element_get_media_duration_factor (element);
|
||||
_set_start0 (GES_TIMELINE_ELEMENT (new_object), position);
|
||||
_set_inpoint0 (GES_TIMELINE_ELEMENT (new_object),
|
||||
inpoint + old_duration * media_duration_factor);
|
||||
_set_inpoint0 (GES_TIMELINE_ELEMENT (new_object), new_inpoint);
|
||||
_set_duration0 (GES_TIMELINE_ELEMENT (new_object), new_duration);
|
||||
|
||||
/* NOTE: it is technically possible that the new_object may shrink
|
||||
* later on in this method if the clip contains any non-linear time
|
||||
* effects, which cause the duration-limit to drop. However, this
|
||||
* should be safe since we have already checked with timeline-tree
|
||||
* that the split position is not in the middle of an overlap. This
|
||||
* means that the new_object should only be overlapping another
|
||||
* element on its end, which makes shrinking safe.
|
||||
*
|
||||
* The original clip, however, should not shrink if the time effects
|
||||
* obey the property that they do not depend on how much data they
|
||||
* receive, which should be true for the time effects supported by GES.
|
||||
*/
|
||||
|
||||
/* split binding before duration changes since shrinking can destroy
|
||||
* binding values */
|
||||
track_for_copy = g_hash_table_new_full (NULL, NULL,
|
||||
|
@ -3088,6 +3111,9 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
|||
g_hash_table_unref (track_for_copy);
|
||||
g_list_free_full (transitions, gst_object_unref);
|
||||
|
||||
new_object->priv->prevent_duration_limit_update = FALSE;
|
||||
_update_duration_limit (new_object);
|
||||
|
||||
return new_object;
|
||||
}
|
||||
|
||||
|
|
|
@ -491,7 +491,6 @@ typedef enum
|
|||
} GESTimelineElementFlags;
|
||||
|
||||
G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_peak_toplevel (GESTimelineElement * self);
|
||||
G_GNUC_INTERNAL gdouble ges_timeline_element_get_media_duration_factor(GESTimelineElement *self);
|
||||
G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_get_copied_from (GESTimelineElement *self);
|
||||
G_GNUC_INTERNAL GESTimelineElementFlags ges_timeline_element_flags (GESTimelineElement *self);
|
||||
G_GNUC_INTERNAL void ges_timeline_element_set_flags (GESTimelineElement *self, GESTimelineElementFlags flags);
|
||||
|
|
|
@ -726,49 +726,6 @@ ges_timeline_element_peak_toplevel (GESTimelineElement * self)
|
|||
return toplevel;
|
||||
}
|
||||
|
||||
gdouble
|
||||
ges_timeline_element_get_media_duration_factor (GESTimelineElement * self)
|
||||
{
|
||||
gdouble media_duration_factor;
|
||||
GESEffectClass *class;
|
||||
GList *props;
|
||||
|
||||
media_duration_factor = 1.0;
|
||||
|
||||
class = GES_EFFECT_CLASS (g_type_class_ref (GES_TYPE_EFFECT));
|
||||
|
||||
for (props = class->rate_properties; props != NULL; props = props->next) {
|
||||
GObject *child;
|
||||
GParamSpec *pspec;
|
||||
if (ges_timeline_element_lookup_child (self, props->data, &child, &pspec)) {
|
||||
if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_FLOAT) {
|
||||
gfloat rate_change;
|
||||
g_object_get (child, pspec->name, &rate_change, NULL);
|
||||
media_duration_factor *= rate_change;
|
||||
} else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_DOUBLE) {
|
||||
gdouble rate_change;
|
||||
g_object_get (child, pspec->name, &rate_change, NULL);
|
||||
media_duration_factor *= rate_change;
|
||||
} else {
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Rate property %s in child %" GST_PTR_FORMAT
|
||||
" is of unsupported type %s", pspec->name, child,
|
||||
G_VALUE_TYPE_NAME (pspec->value_type));
|
||||
}
|
||||
|
||||
gst_object_unref (child);
|
||||
g_param_spec_unref (pspec);
|
||||
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"Added rate changing property %s, set to value %lf",
|
||||
(const char *) props->data, media_duration_factor);
|
||||
}
|
||||
}
|
||||
|
||||
g_type_class_unref (class);
|
||||
return media_duration_factor;
|
||||
}
|
||||
|
||||
GESTimelineElement *
|
||||
ges_timeline_element_get_copied_from (GESTimelineElement * self)
|
||||
{
|
||||
|
|
|
@ -76,10 +76,6 @@ GST_START_TEST (test_tempochange)
|
|||
fail_unless_equals_int64 (_INPOINT (clip3), 7.5 * GST_SECOND);
|
||||
fail_unless_equals_int64 (_DURATION (clip3), 3 * GST_SECOND);
|
||||
|
||||
ges_layer_remove_clip (layer, (GESClip *) clip);
|
||||
ges_layer_remove_clip (layer, clip2);
|
||||
ges_layer_remove_clip (layer, clip3);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
|
||||
ges_deinit ();
|
||||
|
|
Loading…
Reference in a new issue