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>
This commit is contained in:
Stéphane Cerveau 2021-08-03 11:31:07 +02:00 committed by GStreamer Marge Bot
parent 2bb2ff380e
commit 20c6668f5a
3 changed files with 60 additions and 1 deletions

View file

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

View file

@ -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,
@ -2932,6 +2940,51 @@ ges_timeline_commit_sync (GESTimeline * timeline)
return ret;
}
/**
* 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

View file

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