diff --git a/docs/libs/ges-docs.sgml b/docs/libs/ges-docs.sgml index c909155d2a..b64ca85260 100644 --- a/docs/libs/ges-docs.sgml +++ b/docs/libs/ges-docs.sgml @@ -40,6 +40,7 @@ platform as well as Windows. It is released under the GNU Library General Public + @@ -50,12 +51,12 @@ platform as well as Windows. It is released under the GNU Library General Public Timeline objects - + diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 06af3cfb28..82dd6c0ce8 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -434,7 +434,6 @@ GES_TIMELINE_TRANSITION_GET_CLASS ges-timeline-effect GESTimelineEffect GESTimelineEffect -ges_timeline_effect_new_from_bin_desc GESTimelineEffectClass GESTimelineEffectPrivate @@ -447,6 +446,23 @@ GES_IS_TIMELINE_EFFECT_CLASS GES_TIMELINE_EFFECT_GET_CLASS +
+ges-timeline-parse-launch-effect +GESTimelineParseLaunchEffect +GESTimelineParseLaunchEffect +ges_timeline_parse_launch_effect_new + +GESTimelineParseLaunchEffectClass +GESTimelineParseLaunchEffectPrivate +GES_TIMELINE_PARSE_LAUNCH_EFFECT +GES_IS_TIMELINE_PARSE_LAUNCH_EFFECT +GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT +ges_timeline_parse_launch_effect_get_type +GES_TIMELINE_PARSE_LAUNCH_EFFECT_CLASS_ +GES_IS_TIMELINE_PARSE_LAUNCH_EFFECT_CLASS +GES_TIMELINE_PARSE_LAUNCH_EFFECT_GET_CLASS +
+
ges-timeline-standard-transition GESTimelineStandardTransition diff --git a/docs/libs/ges.types b/docs/libs/ges.types index 920719ffca..eca09068d9 100644 --- a/docs/libs/ges.types +++ b/docs/libs/ges.types @@ -18,6 +18,7 @@ ges_timeline_test_source_get_type ges_timeline_transition_get_type ges_timeline_standard_transition_get_type ges_timeline_effect_get_type +ges_timeline_parse_launch_effect_get_type ges_timeline_filesource_get_type ges_timeline_text_overlay_get_type ges_timeline_title_source_get_type diff --git a/ges/Makefile.am b/ges/Makefile.am index 26840f32ea..15e4a9890c 100644 --- a/ges/Makefile.am +++ b/ges/Makefile.am @@ -19,6 +19,7 @@ libges_@GST_MAJORMINOR@_la_SOURCES = \ ges-timeline-pipeline.c \ ges-timeline-source.c \ ges-timeline-effect.c \ + ges-timeline-parse-launch-effect.c \ ges-timeline-file-source.c \ ges-timeline-operation.c \ ges-timeline-transition.c \ @@ -62,6 +63,7 @@ libges_@GST_MAJORMINOR@include_HEADERS = \ ges-timeline-source.h \ ges-timeline-file-source.h \ ges-timeline-effect.h \ + ges-timeline-parse-launch-effect.h \ ges-timeline-operation.h \ ges-timeline-transition.h \ ges-timeline-standard-transition.h \ diff --git a/ges/ges-timeline-effect.c b/ges/ges-timeline-effect.c index 7d1b683085..82622111e9 100644 --- a/ges/ges-timeline-effect.c +++ b/ges/ges-timeline-effect.c @@ -33,92 +33,20 @@ #include "ges-internal.h" #include "ges-types.h" -G_DEFINE_TYPE (GESTimelineEffect, ges_timeline_effect, +G_DEFINE_ABSTRACT_TYPE (GESTimelineEffect, ges_timeline_effect, GES_TYPE_TIMELINE_OPERATION); struct _GESTimelineEffectPrivate { - gchar *video_bin_description; - gchar *audio_bin_description; + void *nothing; }; -enum -{ - PROP_0, - PROP_VIDEO_BIN_DESCRIPTION, - PROP_AUDIO_BIN_DESCRIPTION, -}; - -static GESTrackObject *ges_tl_effect_create_track_object (GESTimelineObject - * self, GESTrack * track); - -static void -ges_timeline_effect_get_property (GObject * object, - guint property_id, GValue * value, GParamSpec * pspec) -{ - switch (property_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -ges_timeline_effect_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec) -{ - GESTimelineEffect *self = GES_TIMELINE_EFFECT (object); - - switch (property_id) { - case PROP_VIDEO_BIN_DESCRIPTION: - self->priv->video_bin_description = g_value_dup_string (value); - break; - case PROP_AUDIO_BIN_DESCRIPTION: - self->priv->audio_bin_description = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} static void ges_timeline_effect_class_init (GESTimelineEffectClass * klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GESTimelineObjectClass *timobj_class = GES_TIMELINE_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (GESTimelineEffectPrivate)); - object_class->get_property = ges_timeline_effect_get_property; - object_class->set_property = ges_timeline_effect_set_property; - - /** - * GESTimelineEffect:video_bin_description: - * - * The description of the video track of the effect bin with a gst-launch-style - * pipeline description. This should be used for test purposes. - * exemple: videobalance saturation=1.5 hue=+0.5 - */ - g_object_class_install_property (object_class, PROP_VIDEO_BIN_DESCRIPTION, - g_param_spec_string ("video-bin-description", - "Video bin description", - "Description of the video track of the effect", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * GESTimelineEffect:audio_bin_description: - * - * The description of the audio track of the effect bin with a gst-launch-style - * pipeline description. This should be used for test purposes. - * exemple: videobalance saturation=1.5 hue=+0.5 - */ - g_object_class_install_property (object_class, PROP_AUDIO_BIN_DESCRIPTION, - g_param_spec_string ("audio-bin-description", - "bin description", - "Bin description of the audio track of the effect", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - timobj_class->create_track_object = ges_tl_effect_create_track_object; - timobj_class->need_fill_track = FALSE; } static void @@ -128,52 +56,3 @@ ges_timeline_effect_init (GESTimelineEffect * self) GES_TYPE_TIMELINE_EFFECT, GESTimelineEffectPrivate); } - -static GESTrackObject * -ges_tl_effect_create_track_object (GESTimelineObject * self, GESTrack * track) -{ - GESTimelineEffect *effect = GES_TIMELINE_EFFECT (self); - - - if (track->type == GES_TRACK_TYPE_VIDEO) { - if (effect->priv->video_bin_description != NULL) { - GST_DEBUG ("Creating a GESTrackEffect for the video track"); - return GES_TRACK_OBJECT (ges_track_parse_launch_effect_new_from_bin_desc - (effect->priv->video_bin_description)); - } - GST_DEBUG ("Can't create the track Object, the\ - video_bin_description is not set"); - } - if (track->type == GES_TRACK_TYPE_AUDIO) { - if (effect->priv->audio_bin_description != NULL) { - GST_DEBUG ("Creating a GESTrackEffect for the audio track"); - return GES_TRACK_OBJECT (ges_track_parse_launch_effect_new_from_bin_desc - (effect->priv->audio_bin_description)); - } - GST_DEBUG ("Can't create the track Object, the\ - audio_bin_description is not set"); - } - - GST_WARNING ("Effect doesn't handle this track type"); - return NULL; -} - -/** -* ges_timeline_effect_new_from_bin_desc: -* @video_bin_description: The gst-launch like bin description of the effect -* @audio_bin_description: The gst-launch like bin description of the effect -* -* Creates a new #GESTimelineEffect from the description of the bin. This is -* a convenience method for testing puposes. -* -* Returns: a newly created #GESTimelineEffect, or %NULL if something went -* wrong. -*/ -GESTimelineEffect * -ges_timeline_effect_new_from_bin_desc (const gchar * video_bin_description, - const gchar * audio_bin_description) -{ - return g_object_new (GES_TYPE_TIMELINE_EFFECT, - "video-bin-description", video_bin_description, - "audio-bin-description", audio_bin_description, NULL); -} diff --git a/ges/ges-timeline-effect.h b/ges/ges-timeline-effect.h index 4cea048208..33eaa82121 100644 --- a/ges/ges-timeline-effect.h +++ b/ges/ges-timeline-effect.h @@ -73,8 +73,5 @@ struct _GESTimelineEffectClass { GType ges_timeline_effect_get_type (void); -GESTimelineEffect *ges_timeline_effect_new_from_bin_desc (const gchar * - video_bin_description, const gchar * audio_bin_description); - G_END_DECLS #endif /* _GES_TIMELINE_EFFECT */ diff --git a/ges/ges-timeline-parse-launch-effect.c b/ges/ges-timeline-parse-launch-effect.c new file mode 100644 index 0000000000..f19064aff8 --- /dev/null +++ b/ges/ges-timeline-parse-launch-effect.c @@ -0,0 +1,198 @@ +/* GStreamer Editing Services + * Copyright (C) 2011 Thibault Saunier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION: ges-timeline-parse-launch-effect + * @short_description: An effect created by parse-launch style bin descriptions + * in a #GESTimelineLayer + * + * Should be used mainly for testing purposes. + * + * The effect will be applied on the sources that have lower priorities + * (higher number) between the inpoint and the end of it. + * + * In a #GESSimpleTimelineLayer, the priorities will be set for you but if + * you use another type of #GESTimelineLayer, you will have to handle it + * yourself. + */ + +#include +#include "ges-internal.h" +#include "ges-types.h" + +G_DEFINE_TYPE (GESTimelineParseLaunchEffect, ges_timeline_parse_launch_effect, + GES_TYPE_TIMELINE_EFFECT); + +struct _GESTimelineParseLaunchEffectPrivate +{ + gchar *video_bin_description; + gchar *audio_bin_description; +}; + +enum +{ + PROP_0, + PROP_VIDEO_BIN_DESCRIPTION, + PROP_AUDIO_BIN_DESCRIPTION, +}; + +static GESTrackObject + * ges_tl_parse_launch_effect_create_track_obj (GESTimelineObject * self, + GESTrack * track); + +static void +ges_timeline_parse_launch_effect_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec) +{ + GESTimelineParseLaunchEffectPrivate *priv = + GES_TIMELINE_PARSE_LAUNCH_EFFECT (object)->priv; + + switch (property_id) { + case PROP_VIDEO_BIN_DESCRIPTION: + g_value_set_string (value, priv->video_bin_description); + break; + case PROP_AUDIO_BIN_DESCRIPTION: + g_value_set_string (value, priv->audio_bin_description); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +ges_timeline_parse_launch_effect_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec) +{ + GESTimelineParseLaunchEffect *self = + GES_TIMELINE_PARSE_LAUNCH_EFFECT (object); + + switch (property_id) { + case PROP_VIDEO_BIN_DESCRIPTION: + self->priv->video_bin_description = g_value_dup_string (value); + break; + case PROP_AUDIO_BIN_DESCRIPTION: + self->priv->audio_bin_description = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +ges_timeline_parse_launch_effect_class_init (GESTimelineParseLaunchEffectClass * + klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GESTimelineObjectClass *timobj_class = GES_TIMELINE_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, + sizeof (GESTimelineParseLaunchEffectPrivate)); + + object_class->get_property = ges_timeline_parse_launch_effect_get_property; + object_class->set_property = ges_timeline_parse_launch_effect_set_property; + + /** + * GESTimelineParseLaunchEffect:video_bin_description: + * + * The description of the video track of the effect bin with a gst-launch-style + * pipeline description. This should be used for test purposes. + * exemple: videobalance saturation=1.5 hue=+0.5 + */ + g_object_class_install_property (object_class, PROP_VIDEO_BIN_DESCRIPTION, + g_param_spec_string ("video-bin-description", + "Video bin description", + "Description of the video track of the effect", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /** + * GESTimelineParseLaunchEffect:audio_bin_description: + * + * The description of the audio track of the effect bin with a gst-launch-style + * pipeline description. This should be used for test purposes. + * exemple: videobalance saturation=1.5 hue=+0.5 + */ + g_object_class_install_property (object_class, PROP_AUDIO_BIN_DESCRIPTION, + g_param_spec_string ("audio-bin-description", + "bin description", + "Bin description of the audio track of the effect", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + timobj_class->create_track_object = + ges_tl_parse_launch_effect_create_track_obj; + timobj_class->need_fill_track = FALSE; +} + +static void +ges_timeline_parse_launch_effect_init (GESTimelineParseLaunchEffect * self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT, + GESTimelineParseLaunchEffectPrivate); + +} + +static GESTrackObject * +ges_tl_parse_launch_effect_create_track_obj (GESTimelineObject * self, + GESTrack * track) +{ + GESTimelineParseLaunchEffect *effect = + GES_TIMELINE_PARSE_LAUNCH_EFFECT (self); + + + if (track->type == GES_TRACK_TYPE_VIDEO) { + if (effect->priv->video_bin_description != NULL) { + GST_DEBUG ("Creating a GESTrackEffect for the video track"); + return GES_TRACK_OBJECT (ges_track_parse_launch_effect_new_from_bin_desc + (effect->priv->video_bin_description)); + } + GST_DEBUG ("Can't create the track Object, the\ + video_bin_description is not set"); + } + if (track->type == GES_TRACK_TYPE_AUDIO) { + if (effect->priv->audio_bin_description != NULL) { + GST_DEBUG ("Creating a GESTrackEffect for the audio track"); + return GES_TRACK_OBJECT (ges_track_parse_launch_effect_new_from_bin_desc + (effect->priv->audio_bin_description)); + } + GST_DEBUG ("Can't create the track Object, the\ + audio_bin_description is not set"); + } + + GST_WARNING ("Effect doesn't handle this track type"); + return NULL; +} + +/** +* ges_timeline_parse_launch_effect_new_from_bin_desc: +* @video_bin_description: The gst-launch like bin description of the effect +* @audio_bin_description: The gst-launch like bin description of the effect +* +* Creates a new #GESTimelineParseLaunchEffect from the description of the bin. +* +* Returns: a newly created #GESTimelineParseLaunchEffect, or %NULL if something went +* wrong. +*/ +GESTimelineParseLaunchEffect * +ges_timeline_parse_launch_effect_new (const gchar * video_bin_description, + const gchar * audio_bin_description) +{ + return g_object_new (GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT, + "video-bin-description", video_bin_description, + "audio-bin-description", audio_bin_description, NULL); +} diff --git a/ges/ges-timeline-parse-launch-effect.h b/ges/ges-timeline-parse-launch-effect.h new file mode 100644 index 0000000000..9ae102c826 --- /dev/null +++ b/ges/ges-timeline-parse-launch-effect.h @@ -0,0 +1,80 @@ +/* GStreamer Editing Services + * Copyright (C) 2011 Thibault Saunier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GES_TIMELINE_PARSE_LAUNCH_EFFECT +#define _GES_TIMELINE_PARSE_LAUNCH_EFFECT + +#include +#include +#include + +G_BEGIN_DECLS + +#define GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT ges_timeline_parse_launch_effect_get_type() + +#define GES_TIMELINE_PARSE_LAUNCH_EFFECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT, GESTimelineParseLaunchEffect)) + +#define GES_TIMELINE_PARSE_LAUNCH_EFFECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT, GESTimelineParseLaunchEffectClass)) + +#define GES_IS_TIMELINE_PARSE_LAUNCH_EFFECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT)) + +#define GES_IS_TIMELINE_PARSE_LAUNCH_EFFECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT)) + +#define GES_TIMELINE_PARSE_LAUNCH_EFFECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GES_TYPE_TIMELINE_PARSE_LAUNCH_EFFECT, GESTimelineParseLaunchEffectClass)) + +typedef struct _GESTimelineParseLaunchEffectPrivate GESTimelineParseLaunchEffectPrivate; + +/** + * GESTimelineParseLaunchEffect: + */ +struct _GESTimelineParseLaunchEffect { + /*< private >*/ + GESTimelineEffect parent; + + GESTimelineParseLaunchEffectPrivate *priv; + + /* Padding for API extension */ + gpointer _ges_reserved[GES_PADDING]; +}; + +/** + * GESTimelineParseLaunchEffectClass: + * + */ + +struct _GESTimelineParseLaunchEffectClass { + /*< private >*/ + GESTimelineEffectClass parent_class; + + /* Padding for API extension */ + gpointer _ges_reserved[GES_PADDING]; +}; + +GType ges_timeline_parse_launch_effect_get_type (void); + +GESTimelineParseLaunchEffect *ges_timeline_parse_launch_effect_new (const gchar * + video_bin_description, const gchar * audio_bin_description); + +G_END_DECLS +#endif /* _GES_TIMELINE_PARSE_LAUNCH_EFFECT */ diff --git a/ges/ges-types.h b/ges/ges-types.h index 248b0adbe7..b16f215843 100644 --- a/ges/ges-types.h +++ b/ges/ges-types.h @@ -74,6 +74,9 @@ typedef struct _GESTimelineOverlayClass GESTimelineOverlayClass; typedef struct _GESTimelineTextOverlay GESTimelineTextOverlay; typedef struct _GESTimelineTextOverlayClass GESTimelineTextOverlayClass; +typedef struct _GESTimelineParseLaunchEffect GESTimelineParseLaunchEffect; +typedef struct _GESTimelineParseLaunchEffectClass GESTimelineParseLaunchEffectClass; + typedef struct _GESTrack GESTrack; typedef struct _GESTrackClass GESTrackClass; diff --git a/ges/ges.h b/ges/ges.h index 1526e46a1f..9915022676 100644 --- a/ges/ges.h +++ b/ges/ges.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/check/ges/effects.c b/tests/check/ges/effects.c index 998ae0b0ff..d524ed8f4f 100644 --- a/tests/check/ges/effects.c +++ b/tests/check/ges/effects.c @@ -169,7 +169,7 @@ GST_START_TEST (test_tl_effect) GESTimeline *timeline; GESTimelineLayer *layer; GESTrack *track_audio, *track_video; - GESTimelineEffect *tl_effect; + GESTimelineParseLaunchEffect *tl_effect; GESTrackParseLaunchEffect *tck_effect, *tck_effect1; GList *effects, *tmp; gint i, tl_object_height; @@ -192,7 +192,7 @@ GST_START_TEST (test_tl_effect) ges_timeline_add_layer (timeline, layer); GST_DEBUG ("Create effect"); - tl_effect = ges_timeline_effect_new_from_bin_desc ("identity", "identity"); + tl_effect = ges_timeline_parse_launch_effect_new ("identity", "identity"); g_object_set (tl_effect, "duration", 25 * GST_SECOND, NULL); @@ -245,7 +245,7 @@ GST_START_TEST (test_priorities_tl_object) GESTimeline *timeline; GESTimelineLayer *layer; GESTrack *track_audio, *track_video; - GESTimelineEffect *tl_effect; + GESTimelineParseLaunchEffect *tl_effect; GESTrackParseLaunchEffect *tck_effect, *tck_effect1; GList *effects, *tmp; gint i, tl_object_height; @@ -263,7 +263,7 @@ GST_START_TEST (test_priorities_tl_object) ges_timeline_add_layer (timeline, layer); GST_DEBUG ("Create effect"); - tl_effect = ges_timeline_effect_new_from_bin_desc ("identity", "identity"); + tl_effect = ges_timeline_parse_launch_effect_new ("identity", "identity"); g_object_set (tl_effect, "duration", 25 * GST_SECOND, NULL); @@ -325,7 +325,7 @@ GST_START_TEST (test_track_effect_set_properties) GESTimeline *timeline; GESTimelineLayer *layer; GESTrack *track_video; - GESTimelineEffect *tl_effect; + GESTimelineParseLaunchEffect *tl_effect; GESTrackParseLaunchEffect *tck_effect; GValue value = { 0 }; guint val; @@ -340,7 +340,7 @@ GST_START_TEST (test_track_effect_set_properties) ges_timeline_add_layer (timeline, layer); GST_DEBUG ("Create effect"); - tl_effect = ges_timeline_effect_new_from_bin_desc ("agingtv", NULL); + tl_effect = ges_timeline_parse_launch_effect_new ("agingtv", NULL); g_object_set (tl_effect, "duration", 25 * GST_SECOND, NULL); @@ -391,7 +391,7 @@ GST_START_TEST (test_tl_obj_signals) GESTimeline *timeline; GESTimelineLayer *layer; GESTrack *track_video; - GESTimelineEffect *tl_effect; + GESTimelineParseLaunchEffect *tl_effect; GESTrackParseLaunchEffect *tck_effect; GValue value = { 0 }; guint val; @@ -406,7 +406,7 @@ GST_START_TEST (test_tl_obj_signals) ges_timeline_add_layer (timeline, layer); GST_DEBUG ("Create effect"); - tl_effect = ges_timeline_effect_new_from_bin_desc ("agingtv", NULL); + tl_effect = ges_timeline_parse_launch_effect_new ("agingtv", NULL); g_signal_connect (tl_effect, "effect-added", (GCallback) effect_added_cb, tl_effect);