ges: transition: Make crossfade fade out at the same time as it fade in

Until now fade out was just fading in the new clip, but this is not
correct and crossfade should at the same time fade out while fading
in.

Fixes https://phabricator.freedesktop.org/T3451

Differential Revision: https://phabricator.freedesktop.org/D1278
This commit is contained in:
Thibault Saunier 2016-08-11 09:53:58 -04:00 committed by Thibault Saunier
parent 564bd8d473
commit eb48faf342

View file

@ -49,7 +49,8 @@ struct _GESVideoTransitionPrivate
GESVideoStandardTransitionType pending_type;
/* these enable video interpolation */
GstTimedValueControlSource *crossfade_control_source;
GstTimedValueControlSource *fade_in_control_source;
GstTimedValueControlSource *fade_out_control_source;
GstTimedValueControlSource *smpte_control_source;
/* so we can support changing between wipes */
@ -188,7 +189,8 @@ ges_video_transition_init (GESVideoTransition * self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_VIDEO_TRANSITION, GESVideoTransitionPrivate);
self->priv->crossfade_control_source = NULL;
self->priv->fade_in_control_source = NULL;
self->priv->fade_out_control_source = NULL;
self->priv->smpte_control_source = NULL;
self->priv->smpte = NULL;
self->priv->mixer_sink = NULL;
@ -226,9 +228,14 @@ ges_video_transition_dispose (GObject * object)
GST_DEBUG ("disposing");
if (priv->crossfade_control_source) {
gst_object_unref (priv->crossfade_control_source);
priv->crossfade_control_source = NULL;
if (priv->fade_in_control_source) {
gst_object_unref (priv->fade_in_control_source);
priv->fade_in_control_source = NULL;
}
if (priv->fade_out_control_source) {
gst_object_unref (priv->fade_out_control_source);
priv->fade_out_control_source = NULL;
}
if (priv->smpte_control_source) {
@ -374,7 +381,9 @@ ges_video_transition_create_element (GESTrackElement * object)
/* set up interpolation */
priv->crossfade_control_source =
priv->fade_out_control_source =
set_interpolation (GST_OBJECT (priv->mixer_sinka), priv, "alpha");
priv->fade_in_control_source =
set_interpolation (GST_OBJECT (priv->mixer_sinkb), priv, "alpha");
priv->smpte_control_source =
set_interpolation (GST_OBJECT (priv->smpte), priv, "position");
@ -434,28 +443,40 @@ ges_video_transition_update_control_source (GstTimedValueControlSource * ts,
gst_timed_value_control_source_set (ts, duration, end_value);
}
static void
ges_video_transition_update_control_sources (GESVideoTransition * self,
GESVideoStandardTransitionType type)
{
GESVideoTransitionPrivate *priv = self->priv;
guint64 duration =
ges_timeline_element_get_duration (GES_TIMELINE_ELEMENT (self));
GST_LOG ("updating controller");
if (type == GES_VIDEO_STANDARD_TRANSITION_TYPE_CROSSFADE) {
ges_video_transition_update_control_source
(priv->fade_in_control_source, duration, 0.0, 1.0);
ges_video_transition_update_control_source
(priv->fade_out_control_source, duration, 1.0, 0.0);
ges_video_transition_update_control_source (priv->smpte_control_source,
duration, 0.0, 0.0);
} else {
ges_video_transition_update_control_source
(priv->fade_in_control_source, duration, 1.0, 1.0);
ges_video_transition_update_control_source
(priv->fade_out_control_source, duration, 1.0, 1.0);
ges_video_transition_update_control_source (priv->smpte_control_source,
duration, 1.0, 0.0);
}
GST_LOG ("done updating controller");
}
static void
ges_video_transition_duration_changed (GESTrackElement * object,
guint64 duration)
{
GESVideoTransition *self = GES_VIDEO_TRANSITION (object);
GESVideoTransitionPrivate *priv = self->priv;
GST_LOG ("updating controller");
if (priv->type == GES_VIDEO_STANDARD_TRANSITION_TYPE_CROSSFADE) {
ges_video_transition_update_control_source (priv->crossfade_control_source,
duration, 0.0, 1.0);
ges_video_transition_update_control_source (priv->smpte_control_source,
duration, 0.0, 0.0);
} else {
ges_video_transition_update_control_source (priv->crossfade_control_source,
duration, 1.0, 1.0);
ges_video_transition_update_control_source (priv->smpte_control_source,
duration, 1.0, 0.0);
}
GST_LOG ("done updating controller");
ges_video_transition_update_control_sources (self, self->priv->type);
}
static inline void
@ -489,8 +510,6 @@ ges_video_transition_set_transition_type_internal (GESVideoTransition
* self, GESVideoStandardTransitionType type)
{
GESVideoTransitionPrivate *priv = self->priv;
guint64 duration =
ges_timeline_element_get_duration (GES_TIMELINE_ELEMENT (self));
GST_DEBUG ("%p %d => %d", self, priv->type, type);
@ -504,17 +523,7 @@ ges_video_transition_set_transition_type_internal (GESVideoTransition
return TRUE;
}
if (type == GES_VIDEO_STANDARD_TRANSITION_TYPE_CROSSFADE) {
ges_video_transition_update_control_source (priv->crossfade_control_source,
duration, 0.0, 1.0);
ges_video_transition_update_control_source (priv->smpte_control_source,
duration, 0.0, 0.0);
} else {
ges_video_transition_update_control_source (priv->crossfade_control_source,
duration, 1.0, 1.0);
ges_video_transition_update_control_source (priv->smpte_control_source,
duration, 1.0, 0.0);
}
ges_video_transition_update_control_sources (self, type);
priv->type = type;