ges: Do not add a final gap at the end of track while rendering

It is not correct to force a black frame at the end of the rendered
video and it also leads to rendering issue with vpX encoders.

https://bugzilla.gnome.org/show_bug.cgi?id=751510
This commit is contained in:
Thibault Saunier 2015-07-01 17:28:52 +02:00
parent 8b821511ad
commit 938aaaef24
3 changed files with 39 additions and 11 deletions

View file

@ -111,6 +111,10 @@ G_GNUC_INTERNAL
void void
track_resort_and_fill_gaps (GESTrack *track); track_resort_and_fill_gaps (GESTrack *track);
G_GNUC_INTERNAL
void
track_disable_last_gap (GESTrack *track, gboolean disabled);
G_GNUC_INTERNAL void G_GNUC_INTERNAL void
ges_asset_cache_init (void); ges_asset_cache_init (void);

View file

@ -124,8 +124,8 @@ _overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x,
{ {
GESPipeline *pipeline = GES_PIPELINE (overlay); GESPipeline *pipeline = GES_PIPELINE (overlay);
gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (pipeline-> gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (pipeline->priv->
priv->playsink), x, y, width, height); playsink), x, y, width, height);
} }
static void static void
@ -133,8 +133,8 @@ _overlay_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
{ {
GESPipeline *pipeline = GES_PIPELINE (overlay); GESPipeline *pipeline = GES_PIPELINE (overlay);
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (pipeline->priv-> gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (pipeline->
playsink), handle); priv->playsink), handle);
} }
static void static void
@ -225,6 +225,9 @@ static void
_timeline_track_added_cb (GESTimeline * timeline, GESTrack * track, _timeline_track_added_cb (GESTimeline * timeline, GESTrack * track,
GESPipeline * pipeline) GESPipeline * pipeline)
{ {
track_disable_last_gap (track,
! !(pipeline->priv->mode & (GES_PIPELINE_MODE_RENDER |
GES_PIPELINE_MODE_SMART_RENDER)));
_link_track (pipeline, track); _link_track (pipeline, track);
} }
@ -807,8 +810,9 @@ _link_track (GESPipeline * self, GESTrack * track)
} }
/* Connect to encodebin */ /* Connect to encodebin */
if (self->priv-> if (self->
mode & (GES_PIPELINE_MODE_RENDER | GES_PIPELINE_MODE_SMART_RENDER)) { priv->mode & (GES_PIPELINE_MODE_RENDER | GES_PIPELINE_MODE_SMART_RENDER))
{
GstPad *tmppad; GstPad *tmppad;
GST_DEBUG_OBJECT (self, "Connecting to encodebin"); GST_DEBUG_OBJECT (self, "Connecting to encodebin");
@ -1071,9 +1075,11 @@ ges_pipeline_get_mode (GESPipeline * pipeline)
gboolean gboolean
ges_pipeline_set_mode (GESPipeline * pipeline, GESPipelineFlags mode) ges_pipeline_set_mode (GESPipeline * pipeline, GESPipelineFlags mode)
{ {
GList *tmp;
g_return_val_if_fail (GES_IS_PIPELINE (pipeline), FALSE); g_return_val_if_fail (GES_IS_PIPELINE (pipeline), FALSE);
GST_DEBUG_OBJECT (pipeline, "current mode : %d, mode : %d", GST_ERROR_OBJECT (pipeline, "current mode : %d, mode : %d",
pipeline->priv->mode, mode); pipeline->priv->mode, mode);
/* fast-path, nothing to change */ /* fast-path, nothing to change */
@ -1087,6 +1093,15 @@ ges_pipeline_set_mode (GESPipeline * pipeline, GESPipelineFlags mode)
/* Switch pipeline to NULL since we're changing the configuration */ /* Switch pipeline to NULL since we're changing the configuration */
gst_element_set_state (GST_ELEMENT_CAST (pipeline), GST_STATE_NULL); gst_element_set_state (GST_ELEMENT_CAST (pipeline), GST_STATE_NULL);
if (pipeline->priv->timeline) {
gboolean disabled =
! !(mode & (GES_PIPELINE_MODE_RENDER | GES_PIPELINE_MODE_SMART_RENDER));
for (tmp = pipeline->priv->timeline->tracks; tmp; tmp = tmp->next)
track_disable_last_gap (GES_TRACK (tmp->data), disabled);
}
/* remove no-longer needed components */ /* remove no-longer needed components */
if (pipeline->priv->mode & GES_PIPELINE_MODE_PREVIEW && if (pipeline->priv->mode & GES_PIPELINE_MODE_PREVIEW &&
!(mode & GES_PIPELINE_MODE_PREVIEW)) { !(mode & GES_PIPELINE_MODE_PREVIEW)) {
@ -1128,7 +1143,6 @@ ges_pipeline_set_mode (GESPipeline * pipeline, GESPipelineFlags mode)
(mode & GES_PIPELINE_MODE_PREVIEW)) { (mode & GES_PIPELINE_MODE_PREVIEW)) {
/* Add playsink */ /* Add playsink */
GST_DEBUG ("Adding playsink"); GST_DEBUG ("Adding playsink");
if (!gst_bin_add (GST_BIN_CAST (pipeline), pipeline->priv->playsink)) { if (!gst_bin_add (GST_BIN_CAST (pipeline), pipeline->priv->playsink)) {
GST_ERROR_OBJECT (pipeline, "Couldn't add playsink"); GST_ERROR_OBJECT (pipeline, "Couldn't add playsink");
return FALSE; return FALSE;

View file

@ -62,6 +62,7 @@ struct _GESTrackPrivate
GSequence *trackelements_by_start; GSequence *trackelements_by_start;
GHashTable *trackelements_iter; GHashTable *trackelements_iter;
GList *gaps; GList *gaps;
gboolean last_gap_disabled;
guint64 duration; guint64 duration;
@ -234,14 +235,23 @@ update_gaps (GESTrack * track)
} }
} }
GST_DEBUG_OBJECT (track, "Adding a one second gap at the end"); if (!track->priv->last_gap_disabled) {
gap = gap_new (track, timeline_duration, 1); GST_DEBUG_OBJECT (track, "Adding a one second gap at the end");
priv->gaps = g_list_prepend (priv->gaps, gap); gap = gap_new (track, timeline_duration, 1);
priv->gaps = g_list_prepend (priv->gaps, gap);
}
/* 4- Remove old gaps */ /* 4- Remove old gaps */
g_list_free_full (gaps, (GDestroyNotify) free_gap); g_list_free_full (gaps, (GDestroyNotify) free_gap);
} }
void
track_disable_last_gap (GESTrack * track, gboolean disabled)
{
track->priv->last_gap_disabled = disabled;
update_gaps (track);
}
void void
track_resort_and_fill_gaps (GESTrack * track) track_resort_and_fill_gaps (GESTrack * track)
{ {