Commit db5c62ad authored by Thibault Saunier's avatar Thibault Saunier 🌵 Committed by Henry Wilkes

formatter: Fix saving/loading project with clip speed rate control

We need to ensure that clips duration is set after time effects are
added and we now need to serialize effects inpoints and max duration.

Part-of: <!177>
parent e142f491
Pipeline #151280 waiting for manual action with stages
in 18 seconds
......@@ -94,6 +94,7 @@ struct _GESBaseXmlFormatterPrivate
GESTrackElement *current_track_element;
GESClip *current_clip;
GstClockTime current_clip_duration;
gboolean timeline_auto_transition;
......@@ -416,6 +417,7 @@ ges_base_xml_formatter_init (GESBaseXmlFormatter * self)
g_direct_equal, NULL, (GDestroyNotify) _free_layer_entry);
priv->current_track_element = NULL;
priv->current_clip = NULL;
priv->current_clip_duration = GST_CLOCK_TIME_NONE;
priv->timeline_auto_transition = FALSE;
}
......@@ -636,8 +638,16 @@ _add_track_element (GESFormatter * self, GESClip * clip,
(GstStructureForeachFunc) _set_child_property, trackelement);
if (properties) {
gboolean has_internal_source;
/* We do not serialize the priority anymore, and we should never have. */
gst_structure_remove_field (properties, "priority");
/* Ensure that has-internal-source is set before inpoint as otherwise
* the inpoint will be ignored */
if (gst_structure_get_boolean (properties, "has-internal-source",
&has_internal_source) && has_internal_source)
g_object_set (trackelement, "has-internal-source", has_internal_source,
NULL);
gst_structure_foreach (properties,
(GstStructureForeachFunc) set_property_foreach, trackelement);
}
......@@ -915,6 +925,7 @@ ges_base_xml_formatter_add_clip (GESBaseXmlFormatter * self,
if (!nclip)
return;
priv->current_clip_duration = duration;
priv->current_clip = nclip;
}
......@@ -1335,3 +1346,24 @@ ges_base_xml_formatter_last_group_add_child (GESBaseXmlFormatter * self,
GST_DEBUG_OBJECT (self, "Adding %s to %s", child_id,
GES_TIMELINE_ELEMENT_NAME (((PendingGroup *) priv->groups->data)->group));
}
void
ges_base_xml_formatter_end_current_clip (GESBaseXmlFormatter * self)
{
GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);
if (priv->state != STATE_LOADING_CLIPS) {
GST_DEBUG_OBJECT (self, "Not ending clip in %s state.",
loading_state_name (priv->state));
return;
}
g_return_if_fail (priv->current_clip);
if (_DURATION (priv->current_clip) != priv->current_clip_duration)
_set_duration0 (GES_TIMELINE_ELEMENT (priv->current_clip),
priv->current_clip_duration);
priv->current_clip = NULL;
priv->current_clip_duration = GST_CLOCK_TIME_NONE;
}
......@@ -377,7 +377,10 @@ G_GNUC_INTERNAL void ges_base_xml_formatter_set_timeline_properties(GESBaseXmlFo
GESTimeline *timeline,
const gchar *properties,
const gchar *metadatas);
G_GNUC_INTERNAL void ges_xml_formatter_deinit (void);
G_GNUC_INTERNAL void ges_base_xml_formatter_end_current_clip (GESBaseXmlFormatter *self);
G_GNUC_INTERNAL void ges_xml_formatter_deinit (void);
G_GNUC_INTERNAL gboolean set_property_foreach (GQuark field_id,
const GValue * value,
......
......@@ -1021,6 +1021,9 @@ _parse_element_end (GMarkupParseContext * context,
if (!priv->subproject_depth) {
g_clear_pointer (&priv->subproject, g_free);
}
} else if (!g_strcmp0 (element_name, "clip")) {
if (!priv->subproject)
ges_base_xml_formatter_end_current_clip (GES_BASE_XML_FORMATTER (self));
}
}
......@@ -1553,8 +1556,7 @@ _save_effect (GString * str, guint clip_id, GESTrackElement * trackelement,
g_list_free_full (tracks, gst_object_unref);
properties = _serialize_properties (G_OBJECT (trackelement), NULL, "start",
"in-point", "duration", "locked", "max-duration", "name", "priority",
NULL);
"duration", "locked", "name", "priority", NULL);
metas =
ges_meta_container_metas_to_string (GES_META_CONTAINER (trackelement));
extractable_id = ges_extractable_get_id (GES_EXTRACTABLE (trackelement));
......
......@@ -213,11 +213,11 @@ class GESSimpleTimelineTest(GESTest):
return clip
def append_clip(self, layer=0, asset_type=GES.TestClip):
def append_clip(self, layer=0, asset_type=GES.TestClip, asset_id=None):
while len(self.timeline.get_layers()) < layer + 1:
self.timeline.append_layer()
layer = self.timeline.get_layers()[layer]
clip = GES.Asset.request(asset_type, None).extract()
clip = GES.Asset.request(asset_type, asset_id).extract()
clip.props.start = layer.get_duration()
clip.props.duration = 10
self.assertTrue(layer.add_clip(clip))
......@@ -231,16 +231,16 @@ class GESSimpleTimelineTest(GESTest):
and not GObject.type_is_a(p.value_type, GObject.Object)]
for p in props:
pname = p.name
v0 = GObject.Value()
v0.init(p.value_type)
v0.set_value(ref.get_property(pname))
refval = GObject.Value()
refval.init(p.value_type)
refval.set_value(ref.get_property(pname))
v1 = GObject.Value()
v1.init(p.value_type)
v1.set_value(element.get_property(pname))
value = GObject.Value()
value.init(p.value_type)
value.set_value(element.get_property(pname))
self.assertTrue(Gst.value_compare(v0, v1) == Gst.VALUE_EQUAL,
"%s are not equal: %s != %s" % (pname, v0, v1))
self.assertTrue(Gst.value_compare(refval, value) == Gst.VALUE_EQUAL,
"%s are not equal: %s != %s\n %s != %s" % (pname, value, refval, element, ref))
if isinstance(ref, GES.TrackElement):
self.assertElementAreEqual(ref.get_nleobject(), element.get_nleobject())
......@@ -275,7 +275,7 @@ class GESSimpleTimelineTest(GESTest):
if not isinstance(ref_child, GES.Effect):
child = tmpchild
break
elif ref_child.props.bin_description == child.props.bin_description:
elif ref_child.props.bin_description == tmpchild.props.bin_description:
child = tmpchild
break
......
......@@ -613,9 +613,8 @@ class TestEditing(common.GESSimpleTimelineTest):
def test_trim_time_effects(self):
self.track_types = [GES.TrackType.VIDEO]
super().setUp()
clip = self.append_clip()
clip = self.append_clip(asset_id="max-duration=30")
self.assertTrue(clip.set_inpoint(12))
self.assertTrue(clip.set_max_duration(30))
self.assertEqual(clip.get_duration_limit(), 18)
children = clip.get_children(False)
......@@ -646,6 +645,7 @@ class TestEditing(common.GESSimpleTimelineTest):
self.assertEqual(clip.get_duration_limit(), 36)
self.assertTrue(clip.set_start(40))
self.assertTrue(clip.set_duration(10))
self.check_reload_timeline()
# cannot trim to a 16 because overlay would have a negative in-point
error = None
......@@ -662,6 +662,8 @@ class TestEditing(common.GESSimpleTimelineTest):
self.assertEqual(overlay.get_inpoint(), 5)
self.assertEqual(overlay.get_max_duration(), 16)
self.check_reload_timeline()
# trim backwards to 20
self.assertTrue(
clip.edit_full(-1, GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_START, 20))
......@@ -686,6 +688,7 @@ class TestEditing(common.GESSimpleTimelineTest):
# increased by 2
self.assertEqual(overlay.get_inpoint(), 2)
self.assertEqual(overlay.get_max_duration(), 16)
self.check_reload_timeline()
def test_ripple_end(self):
clip = self.append_clip()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment