mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
trackelement: Add a lookup_child vmethod
This method can be used for subclass to override the default behaviour for child lookup. This vmethod can be used for example in the case where you want the name of a child property to be 'overridden'. As an example in the GESTitleSource where we have a videotestsrc which has a 'foreground-color' property that is used in the TitleSource to set the background color of the title, this vmethod is now used to tweak the name passed as parameter to rename "background" to "foreground-backend" making our API understandable. API: GESTrackElement::lookup_child https://bugzilla.gnome.org/show_bug.cgi?id=727880
This commit is contained in:
parent
190643508f
commit
20f76fe86f
4 changed files with 86 additions and 36 deletions
|
@ -60,19 +60,41 @@ static void ges_title_source_set_property (GObject * object, guint
|
|||
|
||||
static GstElement *ges_title_source_create_source (GESTrackElement * self);
|
||||
|
||||
static gboolean
|
||||
_lookup_child (GESTrackElement * object,
|
||||
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
||||
{
|
||||
gboolean res;
|
||||
GESTitleSourceClass *c = GES_TITLE_SOURCE_GET_CLASS (object);
|
||||
gchar *clean_name = g_regex_replace (c->cleanup_children_prop_names,
|
||||
prop_name, -1, 0, "foreground-color", 0, NULL);
|
||||
|
||||
res =
|
||||
GES_TRACK_ELEMENT_CLASS (ges_title_source_parent_class)->lookup_child
|
||||
(object, clean_name, element, pspec);
|
||||
|
||||
g_free (clean_name);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
ges_title_source_class_init (GESTitleSourceClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GESVideoSourceClass *source_class = GES_VIDEO_SOURCE_CLASS (klass);
|
||||
GESTrackElementClass *track_element_class = GES_TRACK_ELEMENT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GESTitleSourcePrivate));
|
||||
|
||||
object_class->get_property = ges_title_source_get_property;
|
||||
object_class->set_property = ges_title_source_set_property;
|
||||
object_class->dispose = ges_title_source_dispose;
|
||||
track_element_class->lookup_child = _lookup_child;
|
||||
|
||||
source_class->create_source = ges_title_source_create_source;
|
||||
klass->cleanup_children_prop_names = g_regex_new ("background",
|
||||
G_REGEX_EXTENDED, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -69,9 +69,10 @@ struct _GESTitleSourceClass {
|
|||
GESVideoSourceClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
GRegex * cleanup_children_prop_names;
|
||||
|
||||
/* Padding for API extension */
|
||||
gpointer _ges_reserved[GES_PADDING];
|
||||
gpointer _ges_reserved[GES_PADDING - 1];
|
||||
};
|
||||
|
||||
GType ges_title_source_get_type (void);
|
||||
|
|
|
@ -121,6 +121,46 @@ static void
|
|||
_update_control_bindings (GESTimelineElement * element, GstClockTime inpoint,
|
||||
GstClockTime duration);
|
||||
|
||||
static gboolean
|
||||
_lookup_child (GESTrackElement * object,
|
||||
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gchar **names, *name, *classename;
|
||||
gboolean res;
|
||||
|
||||
classename = NULL;
|
||||
res = FALSE;
|
||||
|
||||
names = g_strsplit (prop_name, "::", 2);
|
||||
if (names[1] != NULL) {
|
||||
classename = names[0];
|
||||
name = names[1];
|
||||
} else
|
||||
name = names[0];
|
||||
|
||||
g_hash_table_iter_init (&iter, object->priv->children_props);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
if (g_strcmp0 (G_PARAM_SPEC (key)->name, name) == 0) {
|
||||
if (classename == NULL ||
|
||||
g_strcmp0 (G_OBJECT_TYPE_NAME (G_OBJECT (value)), classename) == 0) {
|
||||
GST_DEBUG ("The %s property from %s has been found", name, classename);
|
||||
if (element)
|
||||
*element = gst_object_ref (value);
|
||||
|
||||
*pspec = g_param_spec_ref (key);
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_strfreev (names);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ges_track_element_get_property (GObject * object, guint property_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
|
@ -273,6 +313,7 @@ ges_track_element_class_init (GESTrackElementClass * klass)
|
|||
|
||||
klass->create_nle_object = ges_track_element_create_nle_object_func;
|
||||
klass->list_children_properties = default_list_children_properties;
|
||||
klass->lookup_child = _lookup_child;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1044,41 +1085,13 @@ gboolean
|
|||
ges_track_element_lookup_child (GESTrackElement * object,
|
||||
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gchar **names, *name, *classename;
|
||||
gboolean res;
|
||||
GESTrackElementClass *class;
|
||||
|
||||
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
|
||||
class = GES_TRACK_ELEMENT_GET_CLASS (object);
|
||||
g_return_val_if_fail (class->lookup_child, FALSE);
|
||||
|
||||
classename = NULL;
|
||||
res = FALSE;
|
||||
|
||||
names = g_strsplit (prop_name, "::", 2);
|
||||
if (names[1] != NULL) {
|
||||
classename = names[0];
|
||||
name = names[1];
|
||||
} else
|
||||
name = names[0];
|
||||
|
||||
g_hash_table_iter_init (&iter, object->priv->children_props);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
if (g_strcmp0 (G_PARAM_SPEC (key)->name, name) == 0) {
|
||||
if (classename == NULL ||
|
||||
g_strcmp0 (G_OBJECT_TYPE_NAME (G_OBJECT (value)), classename) == 0) {
|
||||
GST_DEBUG ("The %s property from %s has been found", name, classename);
|
||||
if (element)
|
||||
*element = gst_object_ref (value);
|
||||
|
||||
*pspec = g_param_spec_ref (key);
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_strfreev (names);
|
||||
|
||||
return res;
|
||||
return class->lookup_child (object, prop_name, element, pspec);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1096,9 +1109,7 @@ ges_track_element_set_child_property_by_pspec (GESTrackElement * object,
|
|||
GstElement *element;
|
||||
g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
|
||||
|
||||
|
||||
element = g_hash_table_lookup (object->priv->children_props, pspec);
|
||||
if (!element)
|
||||
if (!ges_track_element_lookup_child (object, pspec->name, &element, &pspec))
|
||||
goto not_found;
|
||||
|
||||
g_object_set_property (G_OBJECT (element), pspec->name, value);
|
||||
|
|
|
@ -80,6 +80,16 @@ struct _GESTrackElement {
|
|||
* The default implementation will create an object
|
||||
* of type @nleobject_factorytype and call
|
||||
* @create_element.
|
||||
* @lookup_child: method letting subclasses look for a child, overriding the
|
||||
* simple standard behaviour. This vmethod can be used for example
|
||||
* in the case where you want the name of a child property to be
|
||||
* 'overriden'. A good example of where it is usefull is the
|
||||
* GESTitleSource where we have a videotestsrc which has a
|
||||
* 'foreground-color' property that is used in the TitleSource to
|
||||
* set the background color of the title, in that case, this method
|
||||
* has been overriden so that we tweak the name passed has parametter
|
||||
* to rename "background" to "foreground-backend" making our API
|
||||
* understandable.
|
||||
*
|
||||
* Subclasses can override the @create_nle_object method to override what type
|
||||
* of GNonLin object will be created.
|
||||
|
@ -104,6 +114,12 @@ struct _GESTrackElementClass {
|
|||
/* virtual methods for subclasses */
|
||||
GParamSpec** (*list_children_properties) (GESTrackElement * object,
|
||||
guint *n_properties);
|
||||
|
||||
|
||||
gboolean (*lookup_child) (GESTrackElement *object,
|
||||
const gchar *prop_name,
|
||||
GstElement **element,
|
||||
GParamSpec **pspec);
|
||||
/*< private >*/
|
||||
/* Padding for API extension */
|
||||
gpointer _ges_reserved[GES_PADDING_LARGE];
|
||||
|
|
Loading…
Reference in a new issue