mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01: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;
|
GList *tmp, *transitions = NULL;
|
||||||
GESClip *new_object;
|
GESClip *new_object;
|
||||||
GstClockTime start, inpoint, duration, old_duration, new_duration;
|
gboolean no_core = FALSE;
|
||||||
gdouble media_duration_factor;
|
GstClockTime start, inpoint, duration, old_duration, new_duration,
|
||||||
|
new_inpoint;
|
||||||
GESTimelineElement *element;
|
GESTimelineElement *element;
|
||||||
GESTimeline *timeline;
|
GESTimeline *timeline;
|
||||||
GHashTable *track_for_copy;
|
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);
|
layer_prio = ges_timeline_element_get_layer_priority (element);
|
||||||
|
|
||||||
old_duration = position - start;
|
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
|
if (timeline
|
||||||
&& !timeline_tree_can_move_element (timeline_get_tree (timeline), element,
|
&& !timeline_tree_can_move_element (timeline_get_tree (timeline), element,
|
||||||
layer_prio, start, old_duration, error)) {
|
layer_prio, start, old_duration, error)) {
|
||||||
|
@ -2995,7 +3008,6 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_duration = duration + start - position;
|
|
||||||
if (timeline
|
if (timeline
|
||||||
&& !timeline_tree_can_move_element (timeline_get_tree (timeline), element,
|
&& !timeline_tree_can_move_element (timeline_get_tree (timeline), element,
|
||||||
layer_prio, position, new_duration, error)) {
|
layer_prio, position, new_duration, error)) {
|
||||||
|
@ -3011,16 +3023,27 @@ ges_clip_split_full (GESClip * clip, guint64 position, GError ** error)
|
||||||
|
|
||||||
/* Create the new Clip */
|
/* Create the new Clip */
|
||||||
new_object = GES_CLIP (ges_timeline_element_copy (element, FALSE));
|
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");
|
GST_DEBUG_OBJECT (new_object, "New 'splitted' clip");
|
||||||
/* Set new timing properties on the 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_start0 (GES_TIMELINE_ELEMENT (new_object), position);
|
||||||
_set_inpoint0 (GES_TIMELINE_ELEMENT (new_object),
|
_set_inpoint0 (GES_TIMELINE_ELEMENT (new_object), new_inpoint);
|
||||||
inpoint + old_duration * media_duration_factor);
|
|
||||||
_set_duration0 (GES_TIMELINE_ELEMENT (new_object), new_duration);
|
_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
|
/* split binding before duration changes since shrinking can destroy
|
||||||
* binding values */
|
* binding values */
|
||||||
track_for_copy = g_hash_table_new_full (NULL, NULL,
|
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_hash_table_unref (track_for_copy);
|
||||||
g_list_free_full (transitions, gst_object_unref);
|
g_list_free_full (transitions, gst_object_unref);
|
||||||
|
|
||||||
|
new_object->priv->prevent_duration_limit_update = FALSE;
|
||||||
|
_update_duration_limit (new_object);
|
||||||
|
|
||||||
return new_object;
|
return new_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -491,7 +491,6 @@ typedef enum
|
||||||
} GESTimelineElementFlags;
|
} GESTimelineElementFlags;
|
||||||
|
|
||||||
G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_peak_toplevel (GESTimelineElement * self);
|
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 GESTimelineElement * ges_timeline_element_get_copied_from (GESTimelineElement *self);
|
||||||
G_GNUC_INTERNAL GESTimelineElementFlags ges_timeline_element_flags (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);
|
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;
|
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 *
|
GESTimelineElement *
|
||||||
ges_timeline_element_get_copied_from (GESTimelineElement * self)
|
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 (_INPOINT (clip3), 7.5 * GST_SECOND);
|
||||||
fail_unless_equals_int64 (_DURATION (clip3), 3 * 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);
|
gst_object_unref (timeline);
|
||||||
|
|
||||||
ges_deinit ();
|
ges_deinit ();
|
||||||
|
|
Loading…
Reference in a new issue