diff options
author | Stéphane Cerveau <scerveau@collabora.com> | 2021-08-03 11:31:07 +0200 |
---|---|---|
committer | GStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2021-08-06 13:42:45 +0000 |
commit | 20c6668f5a7ce50eeae8b71230d0646ffdefedd9 (patch) | |
tree | b9297021a0f1a11caca60533a3d9e11044f5bc57 | |
parent | 2bb2ff380e4bc0fa33db026178e546c267d9292d (diff) |
ges: freeze commit during render
In render mode, do not commit the timeline
as the position can be invalid and lead to
missing frames.
Fixes #136
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/262>
-rw-r--r-- | ges/ges-pipeline.c | 4 | ||||
-rw-r--r-- | ges/ges-timeline.c | 53 | ||||
-rw-r--r-- | ges/ges-timeline.h | 4 |
3 files changed, 60 insertions, 1 deletions
diff --git a/ges/ges-pipeline.c b/ges/ges-pipeline.c index 4988aec0..9934059a 100644 --- a/ges/ges-pipeline.c +++ b/ges/ges-pipeline.c @@ -1228,6 +1228,7 @@ ges_pipeline_set_mode (GESPipeline * pipeline, GESPipelineFlags mode) /* Disable render bin */ GST_DEBUG ("Disabling rendering bin"); + ges_timeline_thaw_commit (pipeline->priv->timeline); gst_object_ref (pipeline->priv->encodebin); gst_object_ref (pipeline->priv->urisink); gst_bin_remove_many (GST_BIN_CAST (pipeline), @@ -1249,7 +1250,8 @@ ges_pipeline_set_mode (GESPipeline * pipeline, GESPipelineFlags mode) (mode & (GES_PIPELINE_MODE_RENDER | GES_PIPELINE_MODE_SMART_RENDER))) { /* Adding render bin */ GST_DEBUG ("Adding render bin"); - + /* in render mode the commit needs to be locked, see #136 */ + ges_timeline_freeze_commit (pipeline->priv->timeline); if (G_UNLIKELY (pipeline->priv->urisink == NULL)) { GST_ERROR_OBJECT (pipeline, "Output URI not set !"); return FALSE; diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index ac60f23e..6fe3f21a 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -225,6 +225,8 @@ struct _GESTimelinePrivate /* For ges_timeline_commit_sync */ GMutex commited_lock; GCond commited_cond; + gboolean commit_frozen; + gboolean commit_delayed; GThread *valid_thread; gboolean disposed; @@ -2784,6 +2786,12 @@ ges_timeline_commit_unlocked (GESTimeline * timeline) GList *tmp; gboolean res = TRUE; + if (timeline->priv->commit_frozen) { + GST_DEBUG_OBJECT (timeline, "commit locked"); + timeline->priv->commit_delayed = TRUE; + return res; + } + GST_DEBUG_OBJECT (timeline, "commiting changes"); timeline_tree_create_transitions (timeline->priv->tree, @@ -2933,6 +2941,51 @@ ges_timeline_commit_sync (GESTimeline * timeline) } /** + * ges_timeline_freeze_commit: + * @timeline: The #GESTimeline + * + * Freezes the timeline from being committed. This is usually needed while the + * timeline is being rendered to ensure that not change to the timeline are + * taken into account during that moment. Once the rendering is done, you + * should call #ges_timeline_thaw_commit so that comiting becomes possible + * again and any call to `commit()` that happened during the rendering is + * actually taken into account. + * + * Since: 1.20 + * + */ +void +ges_timeline_freeze_commit (GESTimeline * timeline) +{ + LOCK_DYN (timeline); + timeline->priv->commit_frozen = TRUE; + UNLOCK_DYN (timeline); +} + +/** + * ges_timeline_thaw_commit: + * @timeline: The #GESTimeline + * + * Thaw the timeline so that comiting becomes possible + * again and any call to `commit()` that happened during the rendering is + * actually taken into account. + * + * Since: 1.20 + * + */ +void +ges_timeline_thaw_commit (GESTimeline * timeline) +{ + LOCK_DYN (timeline); + timeline->priv->commit_frozen = FALSE; + UNLOCK_DYN (timeline); + if (timeline->priv->commit_delayed) { + ges_timeline_commit (timeline); + timeline->priv->commit_delayed = FALSE; + } +} + +/** * ges_timeline_get_duration: * @timeline: The #GESTimeline * diff --git a/ges/ges-timeline.h b/ges/ges-timeline.h index 16a800b2..00947d8b 100644 --- a/ges/ges-timeline.h +++ b/ges/ges-timeline.h @@ -126,6 +126,10 @@ GES_API gboolean ges_timeline_commit (GESTimeline * timeline); GES_API gboolean ges_timeline_commit_sync (GESTimeline * timeline); +GES_API +void ges_timeline_freeze_commit (GESTimeline * timeline); +GES_API +void ges_timeline_thaw_commit (GESTimeline * timeline); GES_API GstClockTime ges_timeline_get_duration (GESTimeline *timeline); |