mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:26:14 +00:00
Revert "ges: Move the notion of children properties to GESTimelineElement"
I got some trouble with
arc land
and I wanted to push the 3 commit coming after this revert as 3
different commits but they ended up being all squash into one single
commit, which is clearly not cool for later bisecting and blaming.
Reverting that commit and re pushing those 3 commits as they were
supposed to be.
This reverts commit 9fe15ef435
.
This commit is contained in:
parent
9fe15ef435
commit
f470222f3d
12 changed files with 364 additions and 835 deletions
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"phabricator.uri" : "http://phabricator.freedesktop.org/"
|
|
||||||
}
|
|
|
@ -366,7 +366,6 @@ ges_timeline_enable_update
|
||||||
ges_timeline_is_updating
|
ges_timeline_is_updating
|
||||||
<SUBSECTION usage>
|
<SUBSECTION usage>
|
||||||
ges_timeline_get_tracks
|
ges_timeline_get_tracks
|
||||||
ges_timeline_get_layer
|
|
||||||
ges_timeline_get_layers
|
ges_timeline_get_layers
|
||||||
ges_timeline_get_track_for_pad
|
ges_timeline_get_track_for_pad
|
||||||
ges_timeline_get_pad_for_track
|
ges_timeline_get_pad_for_track
|
||||||
|
@ -452,18 +451,6 @@ ges_timeline_element_get_toplevel_parent
|
||||||
ges_timeline_element_copy
|
ges_timeline_element_copy
|
||||||
ges_timeline_element_get_name
|
ges_timeline_element_get_name
|
||||||
ges_timeline_element_set_name
|
ges_timeline_element_set_name
|
||||||
ges_timeline_element_list_children_properties
|
|
||||||
ges_timeline_element_lookup_child
|
|
||||||
ges_timeline_element_get_child_property_by_pspec
|
|
||||||
ges_timeline_element_get_child_property_valist
|
|
||||||
ges_timeline_element_get_child_properties
|
|
||||||
ges_timeline_element_set_child_property_valist
|
|
||||||
ges_timeline_element_set_child_property_by_pspec
|
|
||||||
ges_timeline_element_set_child_properties
|
|
||||||
ges_timeline_element_set_child_property
|
|
||||||
ges_timeline_element_get_child_property
|
|
||||||
ges_timeline_element_add_child_property
|
|
||||||
ges_timeline_element_remove_child_property
|
|
||||||
GES_TIMELINE_ELEMENT_PARENT
|
GES_TIMELINE_ELEMENT_PARENT
|
||||||
GES_TIMELINE_ELEMENT_TIMELINE
|
GES_TIMELINE_ELEMENT_TIMELINE
|
||||||
GES_TIMELINE_ELEMENT_START
|
GES_TIMELINE_ELEMENT_START
|
||||||
|
|
|
@ -185,86 +185,6 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_ges_container_add_child_properties (GESContainer * container,
|
|
||||||
GESTimelineElement * child)
|
|
||||||
{
|
|
||||||
guint n_props, i;
|
|
||||||
|
|
||||||
GParamSpec **child_props =
|
|
||||||
ges_timeline_element_list_children_properties (child,
|
|
||||||
&n_props);
|
|
||||||
|
|
||||||
for (i = 0; i < n_props; i++) {
|
|
||||||
GObject *prop_child;
|
|
||||||
|
|
||||||
if (ges_timeline_element_lookup_child (child, child_props[i]->name,
|
|
||||||
&prop_child, NULL)) {
|
|
||||||
ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT (container),
|
|
||||||
child_props[i], prop_child);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
g_param_spec_unref (child_props[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (child_props);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_ges_container_remove_child_properties (GESContainer * container,
|
|
||||||
GESTimelineElement * child)
|
|
||||||
{
|
|
||||||
guint n_props, i;
|
|
||||||
|
|
||||||
GParamSpec **child_props =
|
|
||||||
ges_timeline_element_list_children_properties (child,
|
|
||||||
&n_props);
|
|
||||||
|
|
||||||
for (i = 0; i < n_props; i++) {
|
|
||||||
GObject *prop_child;
|
|
||||||
|
|
||||||
if (ges_timeline_element_lookup_child (child, child_props[i]->name,
|
|
||||||
&prop_child, NULL)) {
|
|
||||||
ges_timeline_element_remove_child_property (GES_TIMELINE_ELEMENT
|
|
||||||
(container), child_props[i]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
g_param_spec_unref (child_props[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (child_props);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GParamSpec **
|
|
||||||
_list_children_properties (GESTimelineElement * self, guint * n_properties)
|
|
||||||
{
|
|
||||||
GList *tmp;
|
|
||||||
|
|
||||||
for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next)
|
|
||||||
_ges_container_add_child_properties (GES_CONTAINER (self), tmp->data);
|
|
||||||
|
|
||||||
return
|
|
||||||
GES_TIMELINE_ELEMENT_CLASS
|
|
||||||
(ges_container_parent_class)->list_children_properties (self,
|
|
||||||
n_properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_lookup_child (GESTimelineElement * self, const gchar * prop_name,
|
|
||||||
GObject ** child, GParamSpec ** pspec)
|
|
||||||
{
|
|
||||||
GList *tmp;
|
|
||||||
|
|
||||||
for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next)
|
|
||||||
_ges_container_add_child_properties (GES_CONTAINER (self), tmp->data);
|
|
||||||
|
|
||||||
return
|
|
||||||
GES_TIMELINE_ELEMENT_CLASS (ges_container_parent_class)->lookup_child
|
|
||||||
(self, prop_name, child, pspec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
* *
|
* *
|
||||||
* GObject virtual methods implementation *
|
* GObject virtual methods implementation *
|
||||||
|
@ -361,8 +281,6 @@ ges_container_class_init (GESContainerClass * klass)
|
||||||
element_class->set_start = _set_start;
|
element_class->set_start = _set_start;
|
||||||
element_class->set_duration = _set_duration;
|
element_class->set_duration = _set_duration;
|
||||||
element_class->set_inpoint = _set_inpoint;
|
element_class->set_inpoint = _set_inpoint;
|
||||||
element_class->list_children_properties = _list_children_properties;
|
|
||||||
element_class->lookup_child = _lookup_child;
|
|
||||||
|
|
||||||
/* No default implementations */
|
/* No default implementations */
|
||||||
klass->remove_child = NULL;
|
klass->remove_child = NULL;
|
||||||
|
@ -640,8 +558,6 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ges_container_add_child_properties (container, child);
|
|
||||||
|
|
||||||
g_signal_emit (container, ges_container_signals[CHILD_ADDED_SIGNAL], 0,
|
g_signal_emit (container, ges_container_signals[CHILD_ADDED_SIGNAL], 0,
|
||||||
child);
|
child);
|
||||||
|
|
||||||
|
@ -686,8 +602,6 @@ ges_container_remove (GESContainer * container, GESTimelineElement * child)
|
||||||
/* Let it live removing from our mappings */
|
/* Let it live removing from our mappings */
|
||||||
g_hash_table_remove (priv->mappings, child);
|
g_hash_table_remove (priv->mappings, child);
|
||||||
|
|
||||||
_ges_container_remove_child_properties (container, child);
|
|
||||||
|
|
||||||
g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0,
|
g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0,
|
||||||
child);
|
child);
|
||||||
gst_object_unref (child);
|
gst_object_unref (child);
|
||||||
|
|
|
@ -26,14 +26,11 @@
|
||||||
* responsible for controlling its timing properties.
|
* responsible for controlling its timing properties.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ges-utils.h"
|
|
||||||
#include "ges-timeline-element.h"
|
#include "ges-timeline-element.h"
|
||||||
#include "ges-extractable.h"
|
#include "ges-extractable.h"
|
||||||
#include "ges-meta-container.h"
|
#include "ges-meta-container.h"
|
||||||
#include "ges-internal.h"
|
#include "ges-internal.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gobject/gvaluecollector.h>
|
|
||||||
|
|
||||||
/* maps type name quark => count */
|
/* maps type name quark => count */
|
||||||
static GData *object_name_counts = NULL;
|
static GData *object_name_counts = NULL;
|
||||||
|
@ -70,90 +67,13 @@ enum
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DEEP_NOTIFY,
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint ges_timeline_element_signals[LAST_SIGNAL] = { 0 };
|
|
||||||
|
|
||||||
static GParamSpec *properties[PROP_LAST] = { NULL, };
|
static GParamSpec *properties[PROP_LAST] = { NULL, };
|
||||||
|
|
||||||
struct _GESTimelineElementPrivate
|
struct _GESTimelineElementPrivate
|
||||||
{
|
{
|
||||||
gboolean serialize;
|
gboolean serialize;
|
||||||
|
|
||||||
/* We keep a link between properties name and elements internally
|
|
||||||
* The hashtable should look like
|
|
||||||
* {GParamaSpec ---> child}*/
|
|
||||||
GHashTable *children_props;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_lookup_child (GESTimelineElement * self, const gchar * prop_name,
|
|
||||||
GObject ** child, 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, self->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_OBJECT (self, "The %s property from %s has been found", name,
|
|
||||||
classename);
|
|
||||||
if (child)
|
|
||||||
*child = gst_object_ref (value);
|
|
||||||
|
|
||||||
if (pspec)
|
|
||||||
*pspec = g_param_spec_ref (key);
|
|
||||||
res = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_strfreev (names);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GParamSpec **
|
|
||||||
default_list_children_properties (GESTimelineElement * self,
|
|
||||||
guint * n_properties)
|
|
||||||
{
|
|
||||||
GParamSpec **pspec, *spec;
|
|
||||||
GHashTableIter iter;
|
|
||||||
gpointer key, value;
|
|
||||||
|
|
||||||
guint i = 0;
|
|
||||||
|
|
||||||
*n_properties = g_hash_table_size (self->priv->children_props);
|
|
||||||
pspec = g_new (GParamSpec *, *n_properties);
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->priv->children_props);
|
|
||||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
||||||
spec = G_PARAM_SPEC (key);
|
|
||||||
pspec[i] = g_param_spec_ref (spec);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pspec;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_get_property (GObject * object, guint property_id,
|
_get_property (GObject * object, guint property_id,
|
||||||
GValue * value, GParamSpec * pspec)
|
GValue * value, GParamSpec * pspec)
|
||||||
|
@ -249,10 +169,6 @@ ges_timeline_element_init (GESTimelineElement * self)
|
||||||
GES_TYPE_TIMELINE_ELEMENT, GESTimelineElementPrivate);
|
GES_TYPE_TIMELINE_ELEMENT, GESTimelineElementPrivate);
|
||||||
|
|
||||||
self->priv->serialize = TRUE;
|
self->priv->serialize = TRUE;
|
||||||
|
|
||||||
self->priv->children_props =
|
|
||||||
g_hash_table_new_full ((GHashFunc) ges_pspec_hash, ges_pspec_equal,
|
|
||||||
(GDestroyNotify) g_param_spec_unref, gst_object_unref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -352,21 +268,6 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass)
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, PROP_LAST, properties);
|
g_object_class_install_properties (object_class, PROP_LAST, properties);
|
||||||
|
|
||||||
/**
|
|
||||||
* GESTimelineElement::deep-notify:
|
|
||||||
* @timeline_element: a #GESTtimelineElement
|
|
||||||
* @prop_object: the object that originated the signal
|
|
||||||
* @prop: the property that changed
|
|
||||||
*
|
|
||||||
* The deep notify signal is used to be notified of property changes of all
|
|
||||||
* the childs of @timeline_element
|
|
||||||
*/
|
|
||||||
ges_timeline_element_signals[DEEP_NOTIFY] =
|
|
||||||
g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
|
|
||||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
|
|
||||||
G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_generic,
|
|
||||||
G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_PARAM);
|
|
||||||
|
|
||||||
object_class->finalize = ges_timeline_element_finalize;
|
object_class->finalize = ges_timeline_element_finalize;
|
||||||
|
|
||||||
klass->set_parent = NULL;
|
klass->set_parent = NULL;
|
||||||
|
@ -381,9 +282,6 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass)
|
||||||
klass->roll_start = NULL;
|
klass->roll_start = NULL;
|
||||||
klass->roll_end = NULL;
|
klass->roll_end = NULL;
|
||||||
klass->trim = NULL;
|
klass->trim = NULL;
|
||||||
|
|
||||||
klass->list_children_properties = default_list_children_properties;
|
|
||||||
klass->lookup_child = _lookup_child;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1184,440 +1082,3 @@ had_timeline:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
child_prop_changed_cb (GObject * child, GParamSpec * arg
|
|
||||||
G_GNUC_UNUSED, GESTimelineElement * self)
|
|
||||||
{
|
|
||||||
g_signal_emit (self, ges_timeline_element_signals[DEEP_NOTIFY], 0,
|
|
||||||
child, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
ges_timeline_element_add_child_property (GESTimelineElement * self,
|
|
||||||
GParamSpec * pspec, GObject * child)
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (self, "Adding child property: %" GST_PTR_FORMAT "::%s",
|
|
||||||
child, pspec->name);
|
|
||||||
|
|
||||||
if (g_hash_table_insert (self->priv->children_props,
|
|
||||||
g_param_spec_ref (pspec), gst_object_ref (child))) {
|
|
||||||
gchar *signame = g_strconcat ("notify::", pspec->name, NULL);
|
|
||||||
|
|
||||||
g_signal_connect (child, signame, G_CALLBACK (child_prop_changed_cb), self);
|
|
||||||
|
|
||||||
g_free (signame);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_track_element_get_child_property_by_pspec:
|
|
||||||
* @self: a #GESTrackElement
|
|
||||||
* @pspec: The #GParamSpec that specifies the property you want to get
|
|
||||||
* @value: (out): return location for the value
|
|
||||||
*
|
|
||||||
* Gets a property of a child of @self.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ges_timeline_element_get_child_property_by_pspec (GESTimelineElement * self,
|
|
||||||
GParamSpec * pspec, GValue * value)
|
|
||||||
{
|
|
||||||
GstElement *element;
|
|
||||||
|
|
||||||
g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
|
|
||||||
|
|
||||||
element = g_hash_table_lookup (self->priv->children_props, pspec);
|
|
||||||
if (!element)
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
g_object_get_property (G_OBJECT (element), pspec->name, value);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (self, "The %s property doesn't exist", pspec->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_set_child_property_by_pspec:
|
|
||||||
* @self: a #GESTimelineElement
|
|
||||||
* @pspec: The #GParamSpec that specifies the property you want to set
|
|
||||||
* @value: the value
|
|
||||||
*
|
|
||||||
* Sets a property of a child of @self.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ges_timeline_element_set_child_property_by_pspec (GESTimelineElement * self,
|
|
||||||
GParamSpec * pspec, GValue * value)
|
|
||||||
{
|
|
||||||
GObject *child;
|
|
||||||
|
|
||||||
g_return_if_fail (GES_IS_TRACK_ELEMENT (self));
|
|
||||||
|
|
||||||
if (!ges_timeline_element_lookup_child (self, pspec->name, &child, &pspec))
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
g_object_set_property (child, pspec->name, value);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
{
|
|
||||||
GST_ERROR ("The %s property doesn't exist", pspec->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_set_child_property:
|
|
||||||
* @self: The origin #GESTimelineElement
|
|
||||||
* @property_name: The name of the property
|
|
||||||
* @value: the value
|
|
||||||
*
|
|
||||||
* Sets a property of a child of @self
|
|
||||||
*
|
|
||||||
* Note that #ges_timeline_element_set_child_property is really
|
|
||||||
* intended for language bindings, #ges_timeline_element_set_child_properties
|
|
||||||
* is much more convenient for C programming.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the property was set, %FALSE otherwize
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
ges_timeline_element_set_child_property (GESTimelineElement * self,
|
|
||||||
const gchar * property_name, GValue * value)
|
|
||||||
{
|
|
||||||
GParamSpec *pspec;
|
|
||||||
GObject *child;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
|
|
||||||
|
|
||||||
if (!ges_timeline_element_lookup_child (self, property_name, &child, &pspec))
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
g_object_set_property (child, pspec->name, value);
|
|
||||||
|
|
||||||
gst_object_unref (child);
|
|
||||||
g_param_spec_unref (pspec);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (self, "The %s property doesn't exist", property_name);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_get_child_property:
|
|
||||||
* @object: The origin #GESTimelineElement
|
|
||||||
* @property_name: The name of the property
|
|
||||||
* @value: (out): return location for the property value, it will
|
|
||||||
* be initialized if it is initialized with 0
|
|
||||||
*
|
|
||||||
* In general, a copy is made of the property contents and
|
|
||||||
* the caller is responsible for freeing the memory by calling
|
|
||||||
* g_value_unset().
|
|
||||||
*
|
|
||||||
* Gets a property of a GstElement contained in @object.
|
|
||||||
*
|
|
||||||
* Note that #ges_timeline_element_get_child_property is really
|
|
||||||
* intended for language bindings, #ges_timeline_element_get_child_properties
|
|
||||||
* is much more convenient for C programming.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the property was found, %FALSE otherwize
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
ges_timeline_element_get_child_property (GESTimelineElement * self,
|
|
||||||
const gchar * property_name, GValue * value)
|
|
||||||
{
|
|
||||||
GParamSpec *pspec;
|
|
||||||
GObject *child;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
|
|
||||||
|
|
||||||
if (!ges_timeline_element_lookup_child (self, property_name, &child, &pspec))
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
|
|
||||||
g_value_init (value, pspec->value_type);
|
|
||||||
|
|
||||||
g_object_get_property (child, pspec->name, value);
|
|
||||||
|
|
||||||
gst_object_unref (child);
|
|
||||||
g_param_spec_unref (pspec);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (self, "The %s property doesn't exist", property_name);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_lookup_child:
|
|
||||||
* @self: object to lookup the property in
|
|
||||||
* @prop_name: name of the property to look up. You can specify the name of the
|
|
||||||
* class as such: "ClassName::property-name", to guarantee that you get the
|
|
||||||
* proper GParamSpec in case various GstElement-s contain the same property
|
|
||||||
* name. If you don't do so, you will get the first element found, having
|
|
||||||
* this property and the and the corresponding GParamSpec.
|
|
||||||
* @element: (out) (allow-none) (transfer full): pointer to a #GstElement that
|
|
||||||
* takes the real object to set property on
|
|
||||||
* @pspec: (out) (allow-none) (transfer full): pointer to take the #GParamSpec
|
|
||||||
* describing the property
|
|
||||||
*
|
|
||||||
* Looks up which @element and @pspec would be effected by the given @name. If various
|
|
||||||
* contained elements have this property name you will get the first one, unless you
|
|
||||||
* specify the class name in @name.
|
|
||||||
*
|
|
||||||
* Returns: TRUE if @element and @pspec could be found. FALSE otherwise. In that
|
|
||||||
* case the values for @pspec and @element are not modified. Unref @element after
|
|
||||||
* usage.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
ges_timeline_element_lookup_child (GESTimelineElement * self,
|
|
||||||
const gchar * prop_name, GObject ** child, GParamSpec ** pspec)
|
|
||||||
{
|
|
||||||
GESTimelineElementClass *class;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
|
|
||||||
class = GES_TIMELINE_ELEMENT_GET_CLASS (self);
|
|
||||||
g_return_val_if_fail (class->lookup_child, FALSE);
|
|
||||||
|
|
||||||
return class->lookup_child (self, prop_name, child, pspec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_set_child_property_valist:
|
|
||||||
* @self: The #GESTimelineElement parent object
|
|
||||||
* @first_property_name: The name of the first property to set
|
|
||||||
* @var_args: value for the first property, followed optionally by more
|
|
||||||
* name/return location pairs, followed by NULL
|
|
||||||
*
|
|
||||||
* Sets a property of a child of @self. If there are various child elements
|
|
||||||
* that have the same property name, you can distinguish them using the following
|
|
||||||
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
|
||||||
* corresponding property of the first element found will be set.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ges_timeline_element_set_child_property_valist (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name, va_list var_args)
|
|
||||||
{
|
|
||||||
const gchar *name;
|
|
||||||
GParamSpec *pspec;
|
|
||||||
GObject *child;
|
|
||||||
|
|
||||||
gchar *error = NULL;
|
|
||||||
GValue value = { 0, };
|
|
||||||
|
|
||||||
g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
|
|
||||||
|
|
||||||
name = first_property_name;
|
|
||||||
|
|
||||||
/* Note: This part is in big part copied from the gst_child_object_set_valist
|
|
||||||
* method. */
|
|
||||||
|
|
||||||
/* iterate over pairs */
|
|
||||||
while (name) {
|
|
||||||
if (!ges_timeline_element_lookup_child (self, name, &child, &pspec))
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args,
|
|
||||||
G_VALUE_NOCOPY_CONTENTS, &error);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
goto cant_copy;
|
|
||||||
|
|
||||||
g_object_set_property (child, pspec->name, &value);
|
|
||||||
|
|
||||||
gst_object_unref (child);
|
|
||||||
g_value_unset (&value);
|
|
||||||
|
|
||||||
name = va_arg (var_args, gchar *);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (self, "No property %s in OBJECT\n", name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cant_copy:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (self, "error copying value %s in %p: %s", pspec->name,
|
|
||||||
self, error);
|
|
||||||
|
|
||||||
g_value_unset (&value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_set_child_properties:
|
|
||||||
* @self: The #GESTimelineElement parent object
|
|
||||||
* @first_property_name: The name of the first property to set
|
|
||||||
* @...: value for the first property, followed optionally by more
|
|
||||||
* name/return location pairs, followed by NULL
|
|
||||||
*
|
|
||||||
* Sets a property of a child of @self. If there are various child elements
|
|
||||||
* that have the same property name, you can distinguish them using the following
|
|
||||||
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
|
||||||
* corresponding property of the first element found will be set.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ges_timeline_element_set_child_properties (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name, ...)
|
|
||||||
{
|
|
||||||
va_list var_args;
|
|
||||||
|
|
||||||
g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
|
|
||||||
|
|
||||||
va_start (var_args, first_property_name);
|
|
||||||
ges_timeline_element_set_child_property_valist (self, first_property_name,
|
|
||||||
var_args);
|
|
||||||
va_end (var_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_get_child_property_valist:
|
|
||||||
* @self: The #GESTimelineElement parent object
|
|
||||||
* @first_property_name: The name of the first property to get
|
|
||||||
* @var_args: value for the first property, followed optionally by more
|
|
||||||
* name/return location pairs, followed by NULL
|
|
||||||
*
|
|
||||||
* Gets a property of a child of @self. If there are various child elements
|
|
||||||
* that have the same property name, you can distinguish them using the following
|
|
||||||
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
|
||||||
* corresponding property of the first element found will be set.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ges_timeline_element_get_child_property_valist (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name, va_list var_args)
|
|
||||||
{
|
|
||||||
const gchar *name;
|
|
||||||
gchar *error = NULL;
|
|
||||||
GValue value = { 0, };
|
|
||||||
GParamSpec *pspec;
|
|
||||||
GObject *child;
|
|
||||||
|
|
||||||
g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
|
|
||||||
|
|
||||||
name = first_property_name;
|
|
||||||
|
|
||||||
/* This part is in big part copied from the gst_child_object_get_valist method */
|
|
||||||
while (name) {
|
|
||||||
if (!ges_timeline_element_lookup_child (self, name, &child, &pspec))
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
g_value_init (&value, pspec->value_type);
|
|
||||||
g_object_get_property (child, pspec->name, &value);
|
|
||||||
gst_object_unref (child);
|
|
||||||
|
|
||||||
G_VALUE_LCOPY (&value, var_args, 0, &error);
|
|
||||||
if (error)
|
|
||||||
goto cant_copy;
|
|
||||||
g_value_unset (&value);
|
|
||||||
name = va_arg (var_args, gchar *);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (self, "no child property %s", name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cant_copy:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (self, "error copying value %s in %s", pspec->name,
|
|
||||||
error);
|
|
||||||
|
|
||||||
g_value_unset (&value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint
|
|
||||||
compare_gparamspec (GParamSpec ** a, GParamSpec ** b, gpointer udata)
|
|
||||||
{
|
|
||||||
return g_strcmp0 ((*a)->name, (*b)->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_list_children_properties:
|
|
||||||
* @self: The #GESTimelineElement to get the list of children properties from
|
|
||||||
* @n_properties: (out): return location for the length of the returned array
|
|
||||||
*
|
|
||||||
* Gets an array of #GParamSpec* for all configurable properties of the
|
|
||||||
* children of @self.
|
|
||||||
*
|
|
||||||
* Returns: (transfer full) (array length=n_properties): an array of #GParamSpec* which should be freed after use or
|
|
||||||
* %NULL if something went wrong
|
|
||||||
*/
|
|
||||||
GParamSpec **
|
|
||||||
ges_timeline_element_list_children_properties (GESTimelineElement * self,
|
|
||||||
guint * n_properties)
|
|
||||||
{
|
|
||||||
GParamSpec **ret;
|
|
||||||
GESTimelineElementClass *class;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL);
|
|
||||||
|
|
||||||
class = GES_TIMELINE_ELEMENT_GET_CLASS (self);
|
|
||||||
|
|
||||||
if (!class->list_children_properties) {
|
|
||||||
GST_INFO_OBJECT (self, "No %s->list_children_properties implementation",
|
|
||||||
G_OBJECT_TYPE_NAME (self));
|
|
||||||
|
|
||||||
*n_properties = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = class->list_children_properties (self, n_properties);
|
|
||||||
g_qsort_with_data (ret, *n_properties, sizeof (GParamSpec *),
|
|
||||||
(GCompareDataFunc) compare_gparamspec, NULL);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_element_get_child_properties:
|
|
||||||
* @self: The origin #GESTimelineElement
|
|
||||||
* @first_property_name: The name of the first property to get
|
|
||||||
* @...: return location for the first property, followed optionally by more
|
|
||||||
* name/return location pairs, followed by NULL
|
|
||||||
*
|
|
||||||
* Gets properties of a child of @self.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ges_timeline_element_get_child_properties (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name, ...)
|
|
||||||
{
|
|
||||||
va_list var_args;
|
|
||||||
|
|
||||||
g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
|
|
||||||
|
|
||||||
va_start (var_args, first_property_name);
|
|
||||||
ges_timeline_element_get_child_property_valist (self, first_property_name,
|
|
||||||
var_args);
|
|
||||||
va_end (var_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
ges_timeline_element_remove_child_property (GESTimelineElement * self,
|
|
||||||
GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
return g_hash_table_remove (self->priv->children_props, pspec);
|
|
||||||
}
|
|
||||||
|
|
|
@ -185,15 +185,11 @@ struct _GESTimelineElementClass
|
||||||
gboolean (*roll_start) (GESTimelineElement *self, guint64 start);
|
gboolean (*roll_start) (GESTimelineElement *self, guint64 start);
|
||||||
gboolean (*roll_end) (GESTimelineElement *self, guint64 end);
|
gboolean (*roll_end) (GESTimelineElement *self, guint64 end);
|
||||||
gboolean (*trim) (GESTimelineElement *self, guint64 start);
|
gboolean (*trim) (GESTimelineElement *self, guint64 start);
|
||||||
void (*deep_copy) (GESTimelineElement *self, GESTimelineElement *copy);
|
void (*deep_copy) (GESTimelineElement *self, GESTimelineElement *copy);
|
||||||
|
|
||||||
GParamSpec** (*list_children_properties) (GESTimelineElement * self, guint *n_properties);
|
|
||||||
gboolean (*lookup_child) (GESTimelineElement *self, const gchar *prop_name,
|
|
||||||
GObject **child, GParamSpec **pspec);
|
|
||||||
|
|
||||||
/*< private > */
|
/*< private > */
|
||||||
/* Padding for API extension */
|
/* Padding for API extension */
|
||||||
gpointer _ges_reserved[GES_PADDING_LARGE - 2];
|
gpointer _ges_reserved[GES_PADDING_LARGE];
|
||||||
};
|
};
|
||||||
|
|
||||||
GType ges_timeline_element_get_type (void) G_GNUC_CONST;
|
GType ges_timeline_element_get_type (void) G_GNUC_CONST;
|
||||||
|
@ -224,57 +220,6 @@ gboolean ges_timeline_element_trim (GESTimelineElement *self,
|
||||||
GESTimelineElement * ges_timeline_element_copy (GESTimelineElement *self, gboolean deep);
|
GESTimelineElement * ges_timeline_element_copy (GESTimelineElement *self, gboolean deep);
|
||||||
gchar * ges_timeline_element_get_name (GESTimelineElement *self);
|
gchar * ges_timeline_element_get_name (GESTimelineElement *self);
|
||||||
gboolean ges_timeline_element_set_name (GESTimelineElement *self, const gchar *name);
|
gboolean ges_timeline_element_set_name (GESTimelineElement *self, const gchar *name);
|
||||||
GParamSpec **
|
|
||||||
ges_timeline_element_list_children_properties (GESTimelineElement *self,
|
|
||||||
guint *n_properties);
|
|
||||||
|
|
||||||
gboolean ges_timeline_element_lookup_child (GESTimelineElement *self,
|
|
||||||
const gchar *prop_name,
|
|
||||||
GObject **child,
|
|
||||||
GParamSpec **pspec);
|
|
||||||
|
|
||||||
void
|
|
||||||
ges_timeline_element_get_child_property_by_pspec (GESTimelineElement * self,
|
|
||||||
GParamSpec * pspec,
|
|
||||||
GValue * value);
|
|
||||||
|
|
||||||
void
|
|
||||||
ges_timeline_element_get_child_property_valist (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name,
|
|
||||||
va_list var_args);
|
|
||||||
|
|
||||||
void ges_timeline_element_get_child_properties (GESTimelineElement *self,
|
|
||||||
const gchar * first_property_name,
|
|
||||||
...) G_GNUC_NULL_TERMINATED;
|
|
||||||
|
|
||||||
void
|
|
||||||
ges_timeline_element_set_child_property_valist (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name,
|
|
||||||
va_list var_args);
|
|
||||||
|
|
||||||
void
|
|
||||||
ges_timeline_element_set_child_property_by_pspec (GESTimelineElement * self,
|
|
||||||
GParamSpec * pspec,
|
|
||||||
GValue * value);
|
|
||||||
|
|
||||||
void ges_timeline_element_set_child_properties (GESTimelineElement * self,
|
|
||||||
const gchar * first_property_name,
|
|
||||||
...) G_GNUC_NULL_TERMINATED;
|
|
||||||
|
|
||||||
gboolean ges_timeline_element_set_child_property (GESTimelineElement *self,
|
|
||||||
const gchar *property_name,
|
|
||||||
GValue * value);
|
|
||||||
|
|
||||||
gboolean ges_timeline_element_get_child_property (GESTimelineElement *self,
|
|
||||||
const gchar *property_name,
|
|
||||||
GValue * value);
|
|
||||||
|
|
||||||
gboolean ges_timeline_element_add_child_property (GESTimelineElement * self,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
GObject *child);
|
|
||||||
|
|
||||||
gboolean ges_timeline_element_remove_child_property(GESTimelineElement * self,
|
|
||||||
GParamSpec *pspec);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -3214,34 +3214,3 @@ ges_timeline_is_empty (GESTimeline * timeline)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ges_timeline_get_layer:
|
|
||||||
* @timeline: The #GESTimeline to retrive a layer from
|
|
||||||
* @priority: The priority of the layer to find
|
|
||||||
*
|
|
||||||
* Retrieve the layer with @priority as a priority
|
|
||||||
*
|
|
||||||
* Returns: A #GESLayer or %NULL if no layer with @priority was found
|
|
||||||
*
|
|
||||||
* Since 1.6
|
|
||||||
*/
|
|
||||||
GESLayer *
|
|
||||||
ges_timeline_get_layer (GESTimeline * timeline, guint priority)
|
|
||||||
{
|
|
||||||
GList *tmp;
|
|
||||||
GESLayer *layer = NULL;
|
|
||||||
|
|
||||||
for (tmp = timeline->layers; tmp; tmp = tmp->next) {
|
|
||||||
GESLayer *tmp_layer = GES_LAYER (tmp->data);
|
|
||||||
guint tmp_priority;
|
|
||||||
|
|
||||||
g_object_get (tmp_layer, "priority", &tmp_priority, NULL);
|
|
||||||
if (tmp_priority == priority) {
|
|
||||||
layer = gst_object_ref (tmp_layer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
|
@ -109,7 +109,6 @@ gboolean ges_timeline_add_layer (GESTimeline *timeline, GESLayer *layer);
|
||||||
GESLayer * ges_timeline_append_layer (GESTimeline * timeline);
|
GESLayer * ges_timeline_append_layer (GESTimeline * timeline);
|
||||||
gboolean ges_timeline_remove_layer (GESTimeline *timeline, GESLayer *layer);
|
gboolean ges_timeline_remove_layer (GESTimeline *timeline, GESLayer *layer);
|
||||||
GList* ges_timeline_get_layers (GESTimeline *timeline);
|
GList* ges_timeline_get_layers (GESTimeline *timeline);
|
||||||
GESLayer* ges_timeline_get_layer (GESTimeline *timeline, guint priority);
|
|
||||||
|
|
||||||
gboolean ges_timeline_add_track (GESTimeline *timeline, GESTrack *track);
|
gboolean ges_timeline_add_track (GESTimeline *timeline, GESTrack *track);
|
||||||
gboolean ges_timeline_remove_track (GESTimeline *timeline, GESTrack *track);
|
gboolean ges_timeline_remove_track (GESTimeline *timeline, GESTrack *track);
|
||||||
|
|
|
@ -29,11 +29,13 @@
|
||||||
* its container, like the start position, the inpoint, the duration and the
|
* its container, like the start position, the inpoint, the duration and the
|
||||||
* priority.
|
* priority.
|
||||||
*/
|
*/
|
||||||
|
#include "ges-utils.h"
|
||||||
#include "ges-internal.h"
|
#include "ges-internal.h"
|
||||||
#include "ges-extractable.h"
|
#include "ges-extractable.h"
|
||||||
#include "ges-track-element.h"
|
#include "ges-track-element.h"
|
||||||
#include "ges-clip.h"
|
#include "ges-clip.h"
|
||||||
#include "ges-meta-container.h"
|
#include "ges-meta-container.h"
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (GESTrackElement, ges_track_element,
|
G_DEFINE_ABSTRACT_TYPE (GESTrackElement, ges_track_element,
|
||||||
GES_TYPE_TIMELINE_ELEMENT);
|
GES_TYPE_TIMELINE_ELEMENT);
|
||||||
|
@ -52,6 +54,11 @@ struct _GESTrackElementPrivate
|
||||||
GstElement *nleobject; /* The NleObject */
|
GstElement *nleobject; /* The NleObject */
|
||||||
GstElement *element; /* The element contained in the nleobject (can be NULL) */
|
GstElement *element; /* The element contained in the nleobject (can be NULL) */
|
||||||
|
|
||||||
|
/* We keep a link between properties name and elements internally
|
||||||
|
* The hashtable should look like
|
||||||
|
* {GParamaSpec ---> element,}*/
|
||||||
|
GHashTable *children_props;
|
||||||
|
|
||||||
GESTrack *track;
|
GESTrack *track;
|
||||||
|
|
||||||
gboolean valid;
|
gboolean valid;
|
||||||
|
@ -85,6 +92,7 @@ static GParamSpec *properties[PROP_LAST];
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
DEEP_NOTIFY,
|
||||||
CONTROL_BINDING_ADDED,
|
CONTROL_BINDING_ADDED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
@ -94,6 +102,11 @@ static guint ges_track_element_signals[LAST_SIGNAL] = { 0 };
|
||||||
static GstElement *ges_track_element_create_nle_object_func (GESTrackElement *
|
static GstElement *ges_track_element_create_nle_object_func (GESTrackElement *
|
||||||
object);
|
object);
|
||||||
|
|
||||||
|
static void connect_properties_signals (GESTrackElement * object);
|
||||||
|
static void connect_signal (gpointer key, gpointer value, gpointer user_data);
|
||||||
|
static void gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
|
||||||
|
G_GNUC_UNUSED, GESTrackElement * track_element);
|
||||||
|
|
||||||
static gboolean _set_start (GESTimelineElement * element, GstClockTime start);
|
static gboolean _set_start (GESTimelineElement * element, GstClockTime start);
|
||||||
static gboolean _set_inpoint (GESTimelineElement * element,
|
static gboolean _set_inpoint (GESTimelineElement * element,
|
||||||
GstClockTime inpoint);
|
GstClockTime inpoint);
|
||||||
|
@ -112,27 +125,42 @@ static gboolean
|
||||||
_lookup_child (GESTrackElement * object,
|
_lookup_child (GESTrackElement * object,
|
||||||
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
||||||
{
|
{
|
||||||
return
|
GHashTableIter iter;
|
||||||
GES_TIMELINE_ELEMENT_GET_CLASS (object)->lookup_child
|
gpointer key, value;
|
||||||
(GES_TIMELINE_ELEMENT (object), prop_name, (GObject **) element, pspec);
|
gchar **names, *name, *classename;
|
||||||
}
|
gboolean res;
|
||||||
|
|
||||||
static gboolean
|
classename = NULL;
|
||||||
strv_find_str (const gchar ** strv, const char *str)
|
res = FALSE;
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
if (strv == NULL)
|
names = g_strsplit (prop_name, "::", 2);
|
||||||
return FALSE;
|
if (names[1] != NULL) {
|
||||||
|
classename = names[0];
|
||||||
|
name = names[1];
|
||||||
|
} else
|
||||||
|
name = names[0];
|
||||||
|
|
||||||
for (i = 0; strv[i]; i++) {
|
g_hash_table_iter_init (&iter, object->priv->children_props);
|
||||||
if (g_strcmp0 (strv[i], str) == 0)
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
return TRUE;
|
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 FALSE;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ges_track_element_get_property (GObject * object, guint property_id,
|
ges_track_element_get_property (GObject * object, guint property_id,
|
||||||
GValue * value, GParamSpec * pspec)
|
GValue * value, GParamSpec * pspec)
|
||||||
|
@ -178,6 +206,7 @@ ges_track_element_dispose (GObject * object)
|
||||||
GESTrackElement *element = GES_TRACK_ELEMENT (object);
|
GESTrackElement *element = GES_TRACK_ELEMENT (object);
|
||||||
GESTrackElementPrivate *priv = element->priv;
|
GESTrackElementPrivate *priv = element->priv;
|
||||||
|
|
||||||
|
g_hash_table_destroy (priv->children_props);
|
||||||
if (priv->bindings_hashtable)
|
if (priv->bindings_hashtable)
|
||||||
g_hash_table_destroy (priv->bindings_hashtable);
|
g_hash_table_destroy (priv->bindings_hashtable);
|
||||||
|
|
||||||
|
@ -248,6 +277,21 @@ ges_track_element_class_init (GESTrackElementClass * klass)
|
||||||
g_object_class_install_property (object_class, PROP_TRACK,
|
g_object_class_install_property (object_class, PROP_TRACK,
|
||||||
properties[PROP_TRACK]);
|
properties[PROP_TRACK]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GESTrackElement::deep-notify:
|
||||||
|
* @track_element: a #GESTrackElement
|
||||||
|
* @prop_object: the object that originated the signal
|
||||||
|
* @prop: the property that changed
|
||||||
|
*
|
||||||
|
* The deep notify signal is used to be notified of property changes of all
|
||||||
|
* the childs of @track_element
|
||||||
|
*/
|
||||||
|
ges_track_element_signals[DEEP_NOTIFY] =
|
||||||
|
g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
|
||||||
|
G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_generic,
|
||||||
|
G_TYPE_NONE, 2, GST_TYPE_ELEMENT, G_TYPE_PARAM);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GESTrackElement::control-binding-added:
|
* GESTrackElement::control-binding-added:
|
||||||
* @track_element: a #GESTrackElement
|
* @track_element: a #GESTrackElement
|
||||||
|
@ -286,6 +330,16 @@ ges_track_element_init (GESTrackElement * self)
|
||||||
priv->pending_active = TRUE;
|
priv->pending_active = TRUE;
|
||||||
priv->bindings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal,
|
priv->bindings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
g_free, NULL);
|
g_free, NULL);
|
||||||
|
priv->children_props =
|
||||||
|
g_hash_table_new_full ((GHashFunc) ges_pspec_hash, ges_pspec_equal,
|
||||||
|
(GDestroyNotify) g_param_spec_unref, gst_object_unref);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
compare_gparamspec (GParamSpec ** a, GParamSpec ** b, gpointer udata)
|
||||||
|
{
|
||||||
|
return g_strcmp0 ((*a)->name, (*b)->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gfloat
|
static gfloat
|
||||||
|
@ -537,6 +591,33 @@ ges_track_element_get_track_type (GESTrackElement * object)
|
||||||
return object->priv->track_type;
|
return object->priv->track_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
|
||||||
|
G_GNUC_UNUSED, GESTrackElement * track_element)
|
||||||
|
{
|
||||||
|
g_signal_emit (track_element, ges_track_element_signals[DEEP_NOTIFY], 0,
|
||||||
|
GST_ELEMENT (element), arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_signal (gpointer key, gpointer value, gpointer user_data)
|
||||||
|
{
|
||||||
|
gchar *signame = g_strconcat ("notify::", G_PARAM_SPEC (key)->name, NULL);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (value),
|
||||||
|
signame, G_CALLBACK (gst_element_prop_changed_cb),
|
||||||
|
GES_TRACK_ELEMENT (user_data));
|
||||||
|
|
||||||
|
g_free (signame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_properties_signals (GESTrackElement * object)
|
||||||
|
{
|
||||||
|
g_hash_table_foreach (object->priv->children_props,
|
||||||
|
(GHFunc) connect_signal, object);
|
||||||
|
}
|
||||||
|
|
||||||
/* default 'create_nle_object' virtual method implementation */
|
/* default 'create_nle_object' virtual method implementation */
|
||||||
static GstElement *
|
static GstElement *
|
||||||
ges_track_element_create_nle_object_func (GESTrackElement * self)
|
ges_track_element_create_nle_object_func (GESTrackElement * self)
|
||||||
|
@ -687,6 +768,22 @@ done:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
strv_find_str (const gchar ** strv, const char *str)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (strv == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; strv[i]; i++) {
|
||||||
|
if (g_strcmp0 (strv[i], str) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ges_track_element_add_children_props:
|
* ges_track_element_add_children_props:
|
||||||
* @self: The #GESTrackElement to set chidlren props on
|
* @self: The #GESTrackElement to set chidlren props on
|
||||||
|
@ -733,8 +830,8 @@ ges_track_element_add_children_props (GESTrackElement * self,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pspec->flags & G_PARAM_WRITABLE) {
|
if (pspec->flags & G_PARAM_WRITABLE) {
|
||||||
ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT (self),
|
g_hash_table_insert (self->priv->children_props,
|
||||||
pspec, G_OBJECT (element));
|
g_param_spec_ref (pspec), gst_object_ref (element));
|
||||||
GST_LOG_OBJECT (self,
|
GST_LOG_OBJECT (self,
|
||||||
"added property %s to controllable properties successfully !",
|
"added property %s to controllable properties successfully !",
|
||||||
whitelist[i]);
|
whitelist[i]);
|
||||||
|
@ -744,6 +841,8 @@ ges_track_element_add_children_props (GESTrackElement * self,
|
||||||
whitelist[i], gst_element_get_name (element));
|
whitelist[i], gst_element_get_name (element));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect_properties_signals (self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,8 +881,8 @@ ges_track_element_add_children_props (GESTrackElement * self,
|
||||||
for (i = 0; i < nb_specs; i++) {
|
for (i = 0; i < nb_specs; i++) {
|
||||||
if ((parray[i]->flags & G_PARAM_WRITABLE) &&
|
if ((parray[i]->flags & G_PARAM_WRITABLE) &&
|
||||||
(!whitelist || strv_find_str (whitelist, parray[i]->name))) {
|
(!whitelist || strv_find_str (whitelist, parray[i]->name))) {
|
||||||
ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT
|
g_hash_table_insert (self->priv->children_props,
|
||||||
(self), parray[i], G_OBJECT (child));
|
g_param_spec_ref (parray[i]), gst_object_ref (child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_free (parray);
|
g_free (parray);
|
||||||
|
@ -816,6 +915,8 @@ ges_track_element_add_children_props (GESTrackElement * self,
|
||||||
g_value_unset (&item);
|
g_value_unset (&item);
|
||||||
}
|
}
|
||||||
gst_iterator_free (it);
|
gst_iterator_free (it);
|
||||||
|
|
||||||
|
connect_properties_signals (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INTERNAL USAGE */
|
/* INTERNAL USAGE */
|
||||||
|
@ -979,15 +1080,18 @@ ges_track_element_is_active (GESTrackElement * object)
|
||||||
* Returns: TRUE if @element and @pspec could be found. FALSE otherwise. In that
|
* Returns: TRUE if @element and @pspec could be found. FALSE otherwise. In that
|
||||||
* case the values for @pspec and @element are not modified. Unref @element after
|
* case the values for @pspec and @element are not modified. Unref @element after
|
||||||
* usage.
|
* usage.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_lookup_child
|
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
ges_track_element_lookup_child (GESTrackElement * object,
|
ges_track_element_lookup_child (GESTrackElement * object,
|
||||||
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
|
||||||
{
|
{
|
||||||
return ges_timeline_element_lookup_child (GES_TIMELINE_ELEMENT (object),
|
GESTrackElementClass *class;
|
||||||
prop_name, ((GObject **) element), pspec);
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return class->lookup_child (object, prop_name, element, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -997,19 +1101,26 @@ ges_track_element_lookup_child (GESTrackElement * object,
|
||||||
* @value: the value
|
* @value: the value
|
||||||
*
|
*
|
||||||
* Sets a property of a child of @object.
|
* Sets a property of a child of @object.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_set_child_property_by_spec
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ges_track_element_set_child_property_by_pspec (GESTrackElement * object,
|
ges_track_element_set_child_property_by_pspec (GESTrackElement * object,
|
||||||
GParamSpec * pspec, GValue * value)
|
GParamSpec * pspec, GValue * value)
|
||||||
{
|
{
|
||||||
|
GstElement *element;
|
||||||
g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
|
g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
|
||||||
|
|
||||||
ges_timeline_element_set_child_property_by_pspec (GES_TIMELINE_ELEMENT
|
if (!ges_track_element_lookup_child (object, pspec->name, &element, &pspec))
|
||||||
(object), pspec, value);
|
goto not_found;
|
||||||
|
|
||||||
|
g_object_set_property (G_OBJECT (element), pspec->name, value);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
{
|
||||||
|
GST_ERROR ("The %s property doesn't exist", pspec->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1023,15 +1134,62 @@ ges_track_element_set_child_property_by_pspec (GESTrackElement * object,
|
||||||
* that have the same property name, you can distinguish them using the following
|
* that have the same property name, you can distinguish them using the following
|
||||||
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
||||||
* corresponding property of the first element found will be set.
|
* corresponding property of the first element found will be set.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_set_child_property_valist
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ges_track_element_set_child_property_valist (GESTrackElement * object,
|
ges_track_element_set_child_property_valist (GESTrackElement * object,
|
||||||
const gchar * first_property_name, va_list var_args)
|
const gchar * first_property_name, va_list var_args)
|
||||||
{
|
{
|
||||||
ges_timeline_element_set_child_property_valist (GES_TIMELINE_ELEMENT (object),
|
const gchar *name;
|
||||||
first_property_name, var_args);
|
GParamSpec *pspec;
|
||||||
|
GstElement *element;
|
||||||
|
|
||||||
|
gchar *error = NULL;
|
||||||
|
GValue value = { 0, };
|
||||||
|
|
||||||
|
g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
|
||||||
|
|
||||||
|
name = first_property_name;
|
||||||
|
|
||||||
|
/* Note: This part is in big part copied from the gst_child_object_set_valist
|
||||||
|
* method. */
|
||||||
|
|
||||||
|
/* iterate over pairs */
|
||||||
|
while (name) {
|
||||||
|
if (!ges_track_element_lookup_child (object, name, &element, &pspec))
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
|
#if GLIB_CHECK_VERSION(2,23,3)
|
||||||
|
G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args,
|
||||||
|
G_VALUE_NOCOPY_CONTENTS, &error);
|
||||||
|
#else
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
G_VALUE_COLLECT (&value, var_args, G_VALUE_NOCOPY_CONTENTS, &error);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
goto cant_copy;
|
||||||
|
|
||||||
|
g_object_set_property (G_OBJECT (element), pspec->name, &value);
|
||||||
|
|
||||||
|
gst_object_unref (element);
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
name = va_arg (var_args, gchar *);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
{
|
||||||
|
GST_WARNING ("No property %s in OBJECT\n", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cant_copy:
|
||||||
|
{
|
||||||
|
GST_WARNING ("error copying value %s in object %p: %s", pspec->name, object,
|
||||||
|
error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1045,8 +1203,6 @@ ges_track_element_set_child_property_valist (GESTrackElement * object,
|
||||||
* that have the same property name, you can distinguish them using the following
|
* that have the same property name, you can distinguish them using the following
|
||||||
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
||||||
* corresponding property of the first element found will be set.
|
* corresponding property of the first element found will be set.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_set_child_properties
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ges_track_element_set_child_properties (GESTrackElement * object,
|
ges_track_element_set_child_properties (GESTrackElement * object,
|
||||||
|
@ -1073,15 +1229,50 @@ ges_track_element_set_child_properties (GESTrackElement * object,
|
||||||
* that have the same property name, you can distinguish them using the following
|
* that have the same property name, you can distinguish them using the following
|
||||||
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
* syntax: 'ClasseName::property_name' as property name. If you don't, the
|
||||||
* corresponding property of the first element found will be set.
|
* corresponding property of the first element found will be set.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_get_child_property_valist
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ges_track_element_get_child_property_valist (GESTrackElement * object,
|
ges_track_element_get_child_property_valist (GESTrackElement * object,
|
||||||
const gchar * first_property_name, va_list var_args)
|
const gchar * first_property_name, va_list var_args)
|
||||||
{
|
{
|
||||||
ges_timeline_element_get_child_property_valist (GES_TIMELINE_ELEMENT (object),
|
const gchar *name;
|
||||||
first_property_name, var_args);
|
gchar *error = NULL;
|
||||||
|
GValue value = { 0, };
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GstElement *element;
|
||||||
|
|
||||||
|
g_return_if_fail (G_IS_OBJECT (object));
|
||||||
|
|
||||||
|
name = first_property_name;
|
||||||
|
|
||||||
|
/* This part is in big part copied from the gst_child_object_get_valist method */
|
||||||
|
while (name) {
|
||||||
|
if (!ges_track_element_lookup_child (object, name, &element, &pspec))
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
|
g_value_init (&value, pspec->value_type);
|
||||||
|
g_object_get_property (G_OBJECT (element), pspec->name, &value);
|
||||||
|
gst_object_unref (element);
|
||||||
|
|
||||||
|
G_VALUE_LCOPY (&value, var_args, 0, &error);
|
||||||
|
if (error)
|
||||||
|
goto cant_copy;
|
||||||
|
g_value_unset (&value);
|
||||||
|
name = va_arg (var_args, gchar *);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
{
|
||||||
|
GST_WARNING ("no property %s in object", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cant_copy:
|
||||||
|
{
|
||||||
|
GST_WARNING ("error copying value %s in object %p: %s", pspec->name, object,
|
||||||
|
error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1094,16 +1285,23 @@ ges_track_element_get_child_property_valist (GESTrackElement * object,
|
||||||
*
|
*
|
||||||
* Returns: (transfer full) (array length=n_properties): an array of #GParamSpec* which should be freed after use or
|
* Returns: (transfer full) (array length=n_properties): an array of #GParamSpec* which should be freed after use or
|
||||||
* %NULL if something went wrong
|
* %NULL if something went wrong
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_list_children_properties
|
|
||||||
*/
|
*/
|
||||||
GParamSpec **
|
GParamSpec **
|
||||||
ges_track_element_list_children_properties (GESTrackElement * object,
|
ges_track_element_list_children_properties (GESTrackElement * object,
|
||||||
guint * n_properties)
|
guint * n_properties)
|
||||||
{
|
{
|
||||||
return
|
GParamSpec **ret;
|
||||||
ges_timeline_element_list_children_properties (GES_TIMELINE_ELEMENT
|
GESTrackElementClass *class;
|
||||||
(object), n_properties);
|
|
||||||
|
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), NULL);
|
||||||
|
|
||||||
|
class = GES_TRACK_ELEMENT_GET_CLASS (object);
|
||||||
|
|
||||||
|
ret = class->list_children_properties (object, n_properties);
|
||||||
|
g_qsort_with_data (ret, *n_properties, sizeof (GParamSpec *),
|
||||||
|
(GCompareDataFunc) compare_gparamspec, NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1114,8 +1312,6 @@ ges_track_element_list_children_properties (GESTrackElement * object,
|
||||||
* name/return location pairs, followed by NULL
|
* name/return location pairs, followed by NULL
|
||||||
*
|
*
|
||||||
* Gets properties of a child of @object.
|
* Gets properties of a child of @object.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_get_child_properties
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ges_track_element_get_child_properties (GESTrackElement * object,
|
ges_track_element_get_child_properties (GESTrackElement * object,
|
||||||
|
@ -1138,15 +1334,28 @@ ges_track_element_get_child_properties (GESTrackElement * object,
|
||||||
* @value: (out): return location for the value
|
* @value: (out): return location for the value
|
||||||
*
|
*
|
||||||
* Gets a property of a child of @object.
|
* Gets a property of a child of @object.
|
||||||
*
|
|
||||||
* Deprecated: Use #ges_timeline_element_get_child_property_by_pspec
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ges_track_element_get_child_property_by_pspec (GESTrackElement * object,
|
ges_track_element_get_child_property_by_pspec (GESTrackElement * object,
|
||||||
GParamSpec * pspec, GValue * value)
|
GParamSpec * pspec, GValue * value)
|
||||||
{
|
{
|
||||||
ges_timeline_element_get_child_property_by_pspec (GES_TIMELINE_ELEMENT
|
GstElement *element;
|
||||||
(object), pspec, value);
|
|
||||||
|
g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
|
||||||
|
|
||||||
|
element = g_hash_table_lookup (object->priv->children_props, pspec);
|
||||||
|
if (!element)
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
|
g_object_get_property (G_OBJECT (element), pspec->name, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
{
|
||||||
|
GST_ERROR ("The %s property doesn't exist", pspec->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1162,53 +1371,104 @@ ges_track_element_get_child_property_by_pspec (GESTrackElement * object,
|
||||||
* is much more convenient for C programming.
|
* is much more convenient for C programming.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the property was set, %FALSE otherwize
|
* Returns: %TRUE if the property was set, %FALSE otherwize
|
||||||
*
|
|
||||||
* Deprecated: use #ges_timeline_element_set_child_property instead
|
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
ges_track_element_set_child_property (GESTrackElement * object,
|
ges_track_element_set_child_property (GESTrackElement * object,
|
||||||
const gchar * property_name, GValue * value)
|
const gchar * property_name, GValue * value)
|
||||||
{
|
{
|
||||||
return ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (object),
|
GParamSpec *pspec;
|
||||||
property_name, value);
|
GstElement *element;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
|
||||||
|
|
||||||
|
if (!ges_track_element_lookup_child (object, property_name, &element, &pspec))
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
|
g_object_set_property (G_OBJECT (element), pspec->name, value);
|
||||||
|
|
||||||
|
gst_object_unref (element);
|
||||||
|
g_param_spec_unref (pspec);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (object, "The %s property doesn't exist", property_name);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ges_track_element_get_child_property:
|
* ges_track_element_get_child_property:
|
||||||
* @object: The origin #GESTrackElement
|
* @object: The origin #GESTrackElement
|
||||||
* @property_name: The name of the property
|
* @property_name: The name of the property
|
||||||
* @value: (out): return location for the property value, it will
|
* @value: (out): return location for the property value, it will
|
||||||
* be initialized if it is initialized with 0
|
* be initialized if it is initialized with 0
|
||||||
*
|
*
|
||||||
* In general, a copy is made of the property contents and
|
* In general, a copy is made of the property contents and
|
||||||
* the caller is responsible for freeing the memory by calling
|
* the caller is responsible for freeing the memory by calling
|
||||||
* g_value_unset().
|
* g_value_unset().
|
||||||
*
|
*
|
||||||
* Gets a property of a GstElement contained in @object.
|
* Gets a property of a GstElement contained in @object.
|
||||||
*
|
*
|
||||||
* Note that #ges_track_element_get_child_property is really
|
* Note that #ges_track_element_get_child_property is really
|
||||||
* intended for language bindings, #ges_track_element_get_child_properties
|
* intended for language bindings, #ges_track_element_get_child_properties
|
||||||
* is much more convenient for C programming.
|
* is much more convenient for C programming.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the property was found, %FALSE otherwize
|
* Returns: %TRUE if the property was found, %FALSE otherwize
|
||||||
*
|
*/
|
||||||
* Deprecated: Use #ges_timeline_element_get_child_property
|
|
||||||
*/
|
|
||||||
gboolean
|
gboolean
|
||||||
ges_track_element_get_child_property (GESTrackElement * object,
|
ges_track_element_get_child_property (GESTrackElement * object,
|
||||||
const gchar * property_name, GValue * value)
|
const gchar * property_name, GValue * value)
|
||||||
{
|
{
|
||||||
return ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (object),
|
GParamSpec *pspec;
|
||||||
property_name, value);
|
GstElement *element;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
|
||||||
|
|
||||||
|
if (!ges_track_element_lookup_child (object, property_name, &element, &pspec))
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
|
||||||
|
g_value_init (value, pspec->value_type);
|
||||||
|
|
||||||
|
g_object_get_property (G_OBJECT (element), pspec->name, value);
|
||||||
|
|
||||||
|
gst_object_unref (element);
|
||||||
|
g_param_spec_unref (pspec);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (object, "The %s property doesn't exist", property_name);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GParamSpec **
|
static GParamSpec **
|
||||||
default_list_children_properties (GESTrackElement * object,
|
default_list_children_properties (GESTrackElement * object,
|
||||||
guint * n_properties)
|
guint * n_properties)
|
||||||
{
|
{
|
||||||
return
|
GParamSpec **pspec, *spec;
|
||||||
GES_TIMELINE_ELEMENT_GET_CLASS (object)->list_children_properties
|
GHashTableIter iter;
|
||||||
(GES_TIMELINE_ELEMENT (object), n_properties);
|
gpointer key, value;
|
||||||
|
|
||||||
|
guint i = 0;
|
||||||
|
|
||||||
|
*n_properties = g_hash_table_size (object->priv->children_props);
|
||||||
|
pspec = g_new (GParamSpec *, *n_properties);
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, object->priv->children_props);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
|
spec = G_PARAM_SPEC (key);
|
||||||
|
pspec[i] = g_param_spec_ref (spec);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pspec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -80,7 +80,6 @@ struct _GESTrackElement {
|
||||||
* The default implementation will create an object
|
* The default implementation will create an object
|
||||||
* of type @nleobject_factorytype and call
|
* of type @nleobject_factorytype and call
|
||||||
* @create_element.
|
* @create_element.
|
||||||
* DeprecatedUse: GESTimelineElement.list_children_properties instead
|
|
||||||
* @lookup_child: method letting subclasses look for a child, overriding the
|
* @lookup_child: method letting subclasses look for a child, overriding the
|
||||||
* simple standard behaviour. This vmethod can be used for example
|
* simple standard behaviour. This vmethod can be used for example
|
||||||
* in the case where you want the name of a child property to be
|
* in the case where you want the name of a child property to be
|
||||||
|
@ -91,7 +90,6 @@ struct _GESTrackElement {
|
||||||
* has been overriden so that we tweak the name passed has parametter
|
* has been overriden so that we tweak the name passed has parametter
|
||||||
* to rename "background" to "foreground-backend" making our API
|
* to rename "background" to "foreground-backend" making our API
|
||||||
* understandable.
|
* understandable.
|
||||||
* Deprecated: use GESTimelineElement.lookup_child instead
|
|
||||||
*
|
*
|
||||||
* Subclasses can override the @create_nle_object method to override what type
|
* Subclasses can override the @create_nle_object method to override what type
|
||||||
* of GNonLin object will be created.
|
* of GNonLin object will be created.
|
||||||
|
@ -116,6 +114,8 @@ struct _GESTrackElementClass {
|
||||||
/* virtual methods for subclasses */
|
/* virtual methods for subclasses */
|
||||||
GParamSpec** (*list_children_properties) (GESTrackElement * object,
|
GParamSpec** (*list_children_properties) (GESTrackElement * object,
|
||||||
guint *n_properties);
|
guint *n_properties);
|
||||||
|
|
||||||
|
|
||||||
gboolean (*lookup_child) (GESTrackElement *object,
|
gboolean (*lookup_child) (GESTrackElement *object,
|
||||||
const gchar *prop_name,
|
const gchar *prop_name,
|
||||||
GstElement **element,
|
GstElement **element,
|
||||||
|
|
|
@ -354,7 +354,7 @@ GST_START_TEST (test_effect_set_properties)
|
||||||
GESLayer *layer;
|
GESLayer *layer;
|
||||||
GESTrack *track_video;
|
GESTrack *track_video;
|
||||||
GESEffectClip *effect_clip;
|
GESEffectClip *effect_clip;
|
||||||
GESTimelineElement *effect;
|
GESTrackElement *effect;
|
||||||
guint scratch_line, n_props, i;
|
guint scratch_line, n_props, i;
|
||||||
gboolean color_aging;
|
gboolean color_aging;
|
||||||
GParamSpec **pspecs, *spec;
|
GParamSpec **pspecs, *spec;
|
||||||
|
@ -377,21 +377,21 @@ GST_START_TEST (test_effect_set_properties)
|
||||||
|
|
||||||
ges_layer_add_clip (layer, (GESClip *) effect_clip);
|
ges_layer_add_clip (layer, (GESClip *) effect_clip);
|
||||||
|
|
||||||
effect = GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"));
|
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (effect_clip),
|
fail_unless (ges_container_add (GES_CONTAINER (effect_clip),
|
||||||
GES_TIMELINE_ELEMENT (effect)));
|
GES_TIMELINE_ELEMENT (effect)));
|
||||||
fail_unless (ges_track_element_get_track (GES_TRACK_ELEMENT (effect)) ==
|
fail_unless (ges_track_element_get_track (GES_TRACK_ELEMENT (effect)) ==
|
||||||
track_video);
|
track_video);
|
||||||
|
|
||||||
ges_timeline_element_set_child_properties (effect,
|
ges_track_element_set_child_properties (effect,
|
||||||
"GstAgingTV::scratch-lines", 17, "color-aging", FALSE, NULL);
|
"GstAgingTV::scratch-lines", 17, "color-aging", FALSE, NULL);
|
||||||
ges_timeline_element_get_child_properties (effect,
|
ges_track_element_get_child_properties (effect,
|
||||||
"GstAgingTV::scratch-lines", &scratch_line,
|
"GstAgingTV::scratch-lines", &scratch_line,
|
||||||
"color-aging", &color_aging, NULL);
|
"color-aging", &color_aging, NULL);
|
||||||
fail_unless (scratch_line == 17);
|
fail_unless (scratch_line == 17);
|
||||||
fail_unless (color_aging == FALSE);
|
fail_unless (color_aging == FALSE);
|
||||||
|
|
||||||
pspecs = ges_timeline_element_list_children_properties (effect, &n_props);
|
pspecs = ges_track_element_list_children_properties (effect, &n_props);
|
||||||
fail_unless (n_props == 7);
|
fail_unless (n_props == 7);
|
||||||
|
|
||||||
spec = pspecs[0];
|
spec = pspecs[0];
|
||||||
|
@ -404,8 +404,8 @@ GST_START_TEST (test_effect_set_properties)
|
||||||
g_value_init (&nval, G_TYPE_UINT);
|
g_value_init (&nval, G_TYPE_UINT);
|
||||||
g_value_set_uint (&val, 10);
|
g_value_set_uint (&val, 10);
|
||||||
|
|
||||||
ges_timeline_element_set_child_property_by_pspec (effect, spec, &val);
|
ges_track_element_set_child_property_by_pspec (effect, spec, &val);
|
||||||
ges_timeline_element_get_child_property_by_pspec (effect, spec, &nval);
|
ges_track_element_get_child_property_by_pspec (effect, spec, &nval);
|
||||||
fail_unless (g_value_get_uint (&nval) == 10);
|
fail_unless (g_value_get_uint (&nval) == 10);
|
||||||
|
|
||||||
for (i = 0; i < n_props; i++) {
|
for (i = 0; i < n_props; i++) {
|
||||||
|
@ -444,7 +444,7 @@ GST_START_TEST (test_clip_signals)
|
||||||
GESLayer *layer;
|
GESLayer *layer;
|
||||||
GESTrack *track_video;
|
GESTrack *track_video;
|
||||||
GESEffectClip *effect_clip;
|
GESEffectClip *effect_clip;
|
||||||
GESTimelineElement *effect;
|
GESEffect *effect;
|
||||||
GValue val = { 0, };
|
GValue val = { 0, };
|
||||||
gboolean effect_added = FALSE;
|
gboolean effect_added = FALSE;
|
||||||
|
|
||||||
|
@ -466,8 +466,9 @@ GST_START_TEST (test_clip_signals)
|
||||||
|
|
||||||
ges_layer_add_clip (layer, (GESClip *) effect_clip);
|
ges_layer_add_clip (layer, (GESClip *) effect_clip);
|
||||||
|
|
||||||
effect = GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"));
|
effect = ges_effect_new ("agingtv");
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (effect_clip), effect));
|
fail_unless (ges_container_add (GES_CONTAINER (effect_clip),
|
||||||
|
GES_TIMELINE_ELEMENT (effect)));
|
||||||
fail_unless (effect_added);
|
fail_unless (effect_added);
|
||||||
g_signal_handlers_disconnect_by_func (effect_clip, effect_added_cb,
|
g_signal_handlers_disconnect_by_func (effect_clip, effect_added_cb,
|
||||||
&effect_added);
|
&effect_added);
|
||||||
|
@ -476,11 +477,11 @@ GST_START_TEST (test_clip_signals)
|
||||||
g_signal_connect (effect, "deep-notify", (GCallback) deep_prop_changed_cb,
|
g_signal_connect (effect, "deep-notify", (GCallback) deep_prop_changed_cb,
|
||||||
effect);
|
effect);
|
||||||
|
|
||||||
ges_timeline_element_set_child_properties (effect,
|
ges_track_element_set_child_properties (GES_TRACK_ELEMENT (effect),
|
||||||
"GstAgingTV::scratch-lines", 17, NULL);
|
"GstAgingTV::scratch-lines", 17, NULL);
|
||||||
|
|
||||||
g_value_init (&val, G_TYPE_UINT);
|
g_value_init (&val, G_TYPE_UINT);
|
||||||
ges_timeline_element_get_child_property (effect,
|
ges_track_element_get_child_property (GES_TRACK_ELEMENT (effect),
|
||||||
"GstAgingTV::scratch-lines", &val);
|
"GstAgingTV::scratch-lines", &val);
|
||||||
fail_unless (G_VALUE_HOLDS_UINT (&val));
|
fail_unless (G_VALUE_HOLDS_UINT (&val));
|
||||||
g_value_unset (&val);
|
g_value_unset (&val);
|
||||||
|
|
|
@ -249,7 +249,7 @@ _test_project (GESProject * project, GESTimeline * timeline)
|
||||||
if (GES_IS_BASE_EFFECT (trackelement)) {
|
if (GES_IS_BASE_EFFECT (trackelement)) {
|
||||||
guint nb_scratch_lines;
|
guint nb_scratch_lines;
|
||||||
|
|
||||||
ges_timeline_element_get_child_properties (tmptrackelement->data,
|
ges_track_element_get_child_properties (trackelement,
|
||||||
"scratch-lines", &nb_scratch_lines, NULL);
|
"scratch-lines", &nb_scratch_lines, NULL);
|
||||||
assert_equals_int (nb_scratch_lines, 12);
|
assert_equals_int (nb_scratch_lines, 12);
|
||||||
|
|
||||||
|
@ -339,10 +339,10 @@ _add_properties (GESTimeline * timeline)
|
||||||
/* Adding children properties */
|
/* Adding children properties */
|
||||||
else if (GES_IS_VIDEO_SOURCE (element)) {
|
else if (GES_IS_VIDEO_SOURCE (element)) {
|
||||||
gint64 posx = 42;
|
gint64 posx = 42;
|
||||||
ges_timeline_element_set_child_properties (GES_TIMELINE_ELEMENT
|
ges_track_element_set_child_properties (element, "posx", posx,
|
||||||
(element), "posx", posx, NULL);
|
NULL);
|
||||||
ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
|
ges_track_element_get_child_properties (element, "posx", &posx,
|
||||||
(element), "posx", &posx, NULL);
|
NULL);
|
||||||
fail_unless_equals_int64 (posx, 42);
|
fail_unless_equals_int64 (posx, 42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,8 +406,8 @@ _check_properties (GESTimeline * timeline)
|
||||||
else if (GES_IS_VIDEO_SOURCE (element)) {
|
else if (GES_IS_VIDEO_SOURCE (element)) {
|
||||||
/* Init 'posx' with a wrong value */
|
/* Init 'posx' with a wrong value */
|
||||||
gint64 posx = 27;
|
gint64 posx = 27;
|
||||||
ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
|
ges_track_element_get_child_properties (element, "posx", &posx,
|
||||||
(element), "posx", &posx, NULL);
|
NULL);
|
||||||
fail_unless_equals_int64 (posx, 42);
|
fail_unless_equals_int64 (posx, 42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1265,11 +1265,9 @@ _set_track_element_width_height (GESTrackElement * trksrc, gint wvalue,
|
||||||
g_value_set_int (&width, wvalue);
|
g_value_set_int (&width, wvalue);
|
||||||
g_value_set_int (&height, hvalue);
|
g_value_set_int (&height, hvalue);
|
||||||
if (wvalue >= 0)
|
if (wvalue >= 0)
|
||||||
ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (trksrc),
|
ges_track_element_set_child_property (trksrc, "width", &width);
|
||||||
"width", &width);
|
|
||||||
if (hvalue >= 0)
|
if (hvalue >= 0)
|
||||||
ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (trksrc),
|
ges_track_element_set_child_property (trksrc, "height", &height);
|
||||||
"height", &height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1287,10 +1285,8 @@ check_frame_positionner_size (GESClip * clip, gint width, gint height)
|
||||||
g_value_init (&val_width, G_TYPE_INT);
|
g_value_init (&val_width, G_TYPE_INT);
|
||||||
g_value_init (&val_height, G_TYPE_INT);
|
g_value_init (&val_height, G_TYPE_INT);
|
||||||
|
|
||||||
ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (trksrc),
|
ges_track_element_get_child_property (trksrc, "width", &val_width);
|
||||||
"width", &val_width);
|
ges_track_element_get_child_property (trksrc, "height", &val_height);
|
||||||
ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (trksrc),
|
|
||||||
"height", &val_height);
|
|
||||||
|
|
||||||
real_width = g_value_get_int (&val_width);
|
real_width = g_value_get_int (&val_width);
|
||||||
real_height = g_value_get_int (&val_height);
|
real_height = g_value_get_int (&val_height);
|
||||||
|
|
Loading…
Reference in a new issue