GESTrackObject: Add create_element vmethod

API: GESTrackObjectClass::gnlobject_factorytype
API: GESTrackObjectClass::create_element

Most track objects are only specific by the contents of the gnlobject,
therefore move the 'create_element' vmethod which was already present
in some subclasses to the top-level class.

Also make the code more robust
This commit is contained in:
Edward Hervey 2010-12-10 12:15:54 +01:00
parent 8389feb971
commit 3912245f87
15 changed files with 116 additions and 172 deletions

View file

@ -51,20 +51,17 @@ static void ges_track_audio_test_source_get_property (GObject * object, guint
static void ges_track_audio_test_source_set_property (GObject * object, guint
property_id, const GValue * value, GParamSpec * pspec);
static GstElement *ges_track_audio_test_source_create_element (GESTrackSource *
static GstElement *ges_track_audio_test_source_create_element (GESTrackObject *
self);
static void
ges_track_audio_test_source_class_init (GESTrackAudioTestSourceClass * klass)
{
GObjectClass *object_class;
GESTrackSourceClass *bg_class;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GESTrackObjectClass *bg_class = GES_TRACK_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTrackAudioTestSourcePrivate));
object_class = G_OBJECT_CLASS (klass);
bg_class = GES_TRACK_SOURCE_CLASS (klass);
object_class->get_property = ges_track_audio_test_source_get_property;
object_class->set_property = ges_track_audio_test_source_set_property;
@ -102,7 +99,7 @@ ges_track_audio_test_source_set_property (GObject * object,
}
static GstElement *
ges_track_audio_test_source_create_element (GESTrackSource * trksrc)
ges_track_audio_test_source_create_element (GESTrackObject * trksrc)
{
GESTrackAudioTestSource *self;
GstElement *ret;
@ -122,7 +119,7 @@ ges_track_audio_test_source_set_freq (GESTrackAudioTestSource * self,
GstElement *element;
self->freq = freq;
element = ((GESTrackSource *) self)->element;
element = ((GESTrackObject *) self)->element;
if (element)
g_object_set (element, "freq", (gdouble) freq, NULL);
}
@ -134,7 +131,7 @@ ges_track_audio_test_source_set_volume (GESTrackAudioTestSource * self,
GstElement *element;
self->volume = volume;
element = ((GESTrackSource *) self)->element;
element = ((GESTrackObject *) self)->element;
if (element)
g_object_set (element, "volume", (gdouble) volume, NULL);
}

View file

@ -47,7 +47,7 @@ enum
static void
ges_track_audio_transition_duration_changed (GESTrackObject * self, guint64);
static GstElement *ges_track_audio_transition_create_element (GESTrackTransition
static GstElement *ges_track_audio_transition_create_element (GESTrackObject
* self);
static void ges_track_audio_transition_dispose (GObject * object);
@ -65,13 +65,11 @@ ges_track_audio_transition_class_init (GESTrackAudioTransitionClass * klass)
{
GObjectClass *object_class;
GESTrackObjectClass *toclass;
GESTrackTransitionClass *pclass;
g_type_class_add_private (klass, sizeof (GESTrackAudioTransitionPrivate));
object_class = G_OBJECT_CLASS (klass);
toclass = GES_TRACK_OBJECT_CLASS (klass);
pclass = GES_TRACK_TRANSITION_CLASS (klass);
object_class->get_property = ges_track_audio_transition_get_property;
object_class->set_property = ges_track_audio_transition_set_property;
@ -80,7 +78,7 @@ ges_track_audio_transition_class_init (GESTrackAudioTransitionClass * klass)
toclass->duration_changed = ges_track_audio_transition_duration_changed;
pclass->create_element = ges_track_audio_transition_create_element;
toclass->create_element = ges_track_audio_transition_create_element;
}
@ -166,7 +164,7 @@ link_element_to_mixer_with_volume (GstBin * bin, GstElement * element,
}
static GstElement *
ges_track_audio_transition_create_element (GESTrackTransition * object)
ges_track_audio_transition_create_element (GESTrackObject * object)
{
GESTrackAudioTransition *self;
GstElement *topbin, *iconva, *iconvb, *oconv;

View file

@ -111,7 +111,7 @@ pad_added_cb (GstElement * timeline, GstPad * pad, GstElement * scale)
}
static GstElement *
ges_track_image_source_create_element (GESTrackSource * object)
ges_track_image_source_create_element (GESTrackObject * object)
{
GstElement *bin, *source, *scale, *freeze, *iconv;
GstPad *src, *target;
@ -151,7 +151,7 @@ static void
ges_track_image_source_class_init (GESTrackImageSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GESTrackSourceClass *source_class = GES_TRACK_SOURCE_CLASS (klass);
GESTrackObjectClass *gesobj_class = GES_TRACK_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTrackImageSourcePrivate));
@ -167,7 +167,7 @@ ges_track_image_source_class_init (GESTrackImageSourceClass * klass)
g_object_class_install_property (object_class, PROP_URI,
g_param_spec_string ("uri", "URI", "uri of the resource",
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
source_class->create_element = ges_track_image_source_create_element;
gesobj_class->create_element = ges_track_image_source_create_element;
}
static void

View file

@ -497,10 +497,84 @@ gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
/* default 'create_gnl_object' virtual method implementation */
static gboolean
ges_track_object_create_gnl_object_func (GESTrackObject * object)
ges_track_object_create_gnl_object_func (GESTrackObject * self)
{
GESTrackObjectClass *klass = NULL;
GstElement *child = NULL;
GstElement *gnlobject;
klass = GES_TRACK_OBJECT_GET_CLASS (self);
if (G_UNLIKELY (self->gnlobject != NULL))
goto already_have_gnlobject;
if (G_UNLIKELY (klass->gnlobject_factorytype == NULL))
goto no_gnlfactory;
GST_DEBUG ("Creating a supporting gnlobject of type '%s'",
klass->gnlobject_factorytype);
gnlobject = gst_element_factory_make (klass->gnlobject_factorytype, NULL);
if (G_UNLIKELY (gnlobject == NULL))
goto no_gnlobject;
if (klass->create_element) {
GST_DEBUG ("Calling subclass 'create_element' vmethod");
child = klass->create_element (self);
if (G_UNLIKELY (!child))
goto child_failure;
if (!gst_bin_add (GST_BIN (gnlobject), child))
goto add_failure;
GST_DEBUG ("Succesfully got the element to put in the gnlobject");
self->element = child;
}
self->gnlobject = gnlobject;
GST_DEBUG ("done");
return TRUE;
/* ERROR CASES */
already_have_gnlobject:
{
GST_ERROR ("Already controlling a GnlObject %s",
GST_ELEMENT_NAME (self->gnlobject));
return FALSE;
}
no_gnlfactory:
{
GST_ERROR ("No GESTrackObject::gnlobject_factorytype implementation!");
return FALSE;
}
no_gnlobject:
{
GST_ERROR ("Error creating a gnlobject of type '%s'",
klass->gnlobject_factorytype);
return FALSE;
}
child_failure:
{
GST_ERROR ("create_element returned NULL");
gst_object_unref (gnlobject);
return FALSE;
}
add_failure:
{
GST_ERROR ("Error adding the contents to the gnlobject");
gst_object_unref (child);
gst_object_unref (gnlobject);
return FALSE;
}
}
static gboolean

View file

@ -132,7 +132,8 @@ struct _GESTrackObject {
guint32 pending_gnl_priority;
gboolean pending_active;
GstElement *gnlobject;
GstElement *gnlobject; /* The GnlObject */
GstElement *element; /* The element contained in the gnlobject (can be NULL) */
GESTrackObjectPrivate *priv;
@ -142,7 +143,12 @@ struct _GESTrackObject {
/**
* GESTrackObjectClass:
* @gnlobject_factorytype: name of the GNonLin GStElementFactory type to use.
* @create_gnl_object: method to create the GNonLin container object.
* Create and fill the gnlobject and set it to GESTrackObject->gnlobject.
* The default implementation will create an object of type @gnlobject_factorytype
* and call @create_element.
* @create_element: method to return the GstElement to put in the gnlobject.
* @start_changed: start property of gnlobject has changed
* @media_start_changed: media-start property of gnlobject has changed
* @duration_changed: duration property glnobject has changed
@ -158,7 +164,9 @@ struct _GESTrackObjectClass {
/*< public >*/
/* virtual methods for subclasses */
const gchar *gnlobject_factorytype;
gboolean (*create_gnl_object) (GESTrackObject * object);
GstElement* (*create_element) (GESTrackObject * object);
void (*start_changed) (GESTrackObject *object, guint64 start);
void (*media_start_changed) (GESTrackObject *object, guint64 media_start);

View file

@ -36,36 +36,6 @@ struct _GESTrackOperationPrivate
void *nothing;
};
static gboolean
ges_track_operation_create_gnl_object (GESTrackObject * object)
{
GESTrackOperationClass *klass = NULL;
GESTrackOperation *self = NULL;
GstElement *child = NULL;
GstElement *gnlobject;
self = GES_TRACK_OPERATION (object);
klass = GES_TRACK_OPERATION_GET_CLASS (self);
gnlobject = gst_element_factory_make ("gnloperation", NULL);
if (klass->create_element) {
child = klass->create_element (self);
if (G_UNLIKELY (!child)) {
GST_ERROR ("create_element returned NULL");
return TRUE;
}
gst_bin_add (GST_BIN (gnlobject), child);
self->element = child;
}
object->gnlobject = gnlobject;
return TRUE;
}
static void
ges_track_operation_class_init (GESTrackOperationClass * klass)
{
@ -73,8 +43,7 @@ ges_track_operation_class_init (GESTrackOperationClass * klass)
g_type_class_add_private (klass, sizeof (GESTrackOperationPrivate));
track_class->create_gnl_object = ges_track_operation_create_gnl_object;
klass->create_element = NULL;
track_class->gnlobject_factorytype = "gnloperation";
}
static void

View file

@ -57,8 +57,6 @@ struct _GESTrackOperation {
/*< private >*/
GESTrackObject parent;
GstElement *element;
GESTrackOperationPrivate *priv;
/* Padding for API extension */
@ -67,17 +65,12 @@ struct _GESTrackOperation {
/**
* GESTrackOperationClass:
* @create_element: virtual method which creates the GStreamer element for
* this object
*/
struct _GESTrackOperationClass {
/*< private >*/
GESTrackObjectClass parent_class;
/*< public >*/
GstElement *(*create_element) (GESTrackOperation *);
/*< private >*/
/* Padding for API extension */
gpointer _ges_reserved[GES_PADDING];

View file

@ -35,36 +35,6 @@ struct _GESTrackSourcePrivate
void *nothing;
};
static gboolean
ges_track_source_create_gnl_object (GESTrackObject * object)
{
GESTrackSourceClass *klass = NULL;
GESTrackSource *self = NULL;
GstElement *child = NULL;
GstElement *gnlobject;
self = GES_TRACK_SOURCE (object);
klass = GES_TRACK_SOURCE_GET_CLASS (self);
gnlobject = gst_element_factory_make ("gnlsource", NULL);
if (klass->create_element) {
child = klass->create_element (self);
if (G_UNLIKELY (!child)) {
GST_ERROR ("create_element returned NULL");
return TRUE;
}
gst_bin_add (GST_BIN (gnlobject), child);
self->element = child;
}
object->gnlobject = gnlobject;
return TRUE;
}
static void
ges_track_source_class_init (GESTrackSourceClass * klass)
{
@ -72,8 +42,8 @@ ges_track_source_class_init (GESTrackSourceClass * klass)
g_type_class_add_private (klass, sizeof (GESTrackSourcePrivate));
track_class->create_gnl_object = ges_track_source_create_gnl_object;
klass->create_element = NULL;
track_class->gnlobject_factorytype = "gnlsource";
track_class->create_element = NULL;
}
static void

View file

@ -57,8 +57,6 @@ struct _GESTrackSource {
/*< private >*/
GESTrackObject parent;
GstElement *element;
GESTrackSourcePrivate *priv;
/* Padding for API extension */
@ -67,18 +65,12 @@ struct _GESTrackSource {
/**
* GESTrackSourceClass:
* @create_element: virtual method which creates the GStreamer element for
* this object
*
*/
struct _GESTrackSourceClass {
/*< private >*/
GESTrackObjectClass parent_class;
/*< public >*/
GstElement *(*create_element) (GESTrackSource *);
/*< private >*/
/* Padding for API extension */
gpointer _ges_reserved[GES_PADDING];

View file

@ -54,20 +54,17 @@ static void ges_track_text_overlay_get_property (GObject * object, guint
static void ges_track_text_overlay_set_property (GObject * object, guint
property_id, const GValue * value, GParamSpec * pspec);
static GstElement *ges_track_text_overlay_create_element (GESTrackOperation
static GstElement *ges_track_text_overlay_create_element (GESTrackObject
* self);
static void
ges_track_text_overlay_class_init (GESTrackTextOverlayClass * klass)
{
GObjectClass *object_class;
GESTrackOperationClass *bg_class;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GESTrackObjectClass *bg_class = GES_TRACK_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTrackTextOverlayPrivate));
object_class = G_OBJECT_CLASS (klass);
bg_class = GES_TRACK_OPERATION_CLASS (klass);
object_class->get_property = ges_track_text_overlay_get_property;
object_class->set_property = ges_track_text_overlay_set_property;
object_class->dispose = ges_track_text_overlay_dispose;
@ -136,7 +133,7 @@ ges_track_text_overlay_set_property (GObject * object,
}
static GstElement *
ges_track_text_overlay_create_element (GESTrackOperation * object)
ges_track_text_overlay_create_element (GESTrackObject * object)
{
GstElement *ret, *text, *iconv, *oconv;
GstPad *src_target, *sink_target;

View file

@ -50,19 +50,16 @@ static void ges_track_title_src_get_property (GObject * object, guint
static void ges_track_title_src_set_property (GObject * object, guint
property_id, const GValue * value, GParamSpec * pspec);
static GstElement *ges_track_title_src_create_element (GESTrackSource * self);
static GstElement *ges_track_title_src_create_element (GESTrackObject * self);
static void
ges_track_title_src_class_init (GESTrackTitleSourceClass * klass)
{
GObjectClass *object_class;
GESTrackSourceClass *bg_class;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GESTrackObjectClass *bg_class = GES_TRACK_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTrackTitleSourcePrivate));
object_class = G_OBJECT_CLASS (klass);
bg_class = GES_TRACK_SOURCE_CLASS (klass);
object_class->get_property = ges_track_title_src_get_property;
object_class->set_property = ges_track_title_src_set_property;
object_class->dispose = ges_track_title_src_dispose;
@ -130,7 +127,7 @@ ges_track_title_src_set_property (GObject * object,
}
static GstElement *
ges_track_title_src_create_element (GESTrackSource * object)
ges_track_title_src_create_element (GESTrackObject * object)
{
GESTrackTitleSource *self = GES_TRACK_TITLE_SOURCE (object);
GstElement *topbin, *background, *text;

View file

@ -36,52 +36,11 @@ struct _GESTrackTransitionPrivate
void *nothing;
};
GstElement *ges_track_transition_create_element (GESTrackTransition * self);
static gboolean
ges_track_transition_create_gnl_object (GESTrackObject * object)
{
GESTrackTransition *self;
GESTrackTransitionClass *klass;
GstElement *element;
gchar *name;
static gint tnum = 0;
self = GES_TRACK_TRANSITION (object);
klass = GES_TRACK_TRANSITION_GET_CLASS (object);
name = g_strdup_printf ("transition-operation%d", tnum++);
object->gnlobject = gst_element_factory_make ("gnloperation", name);
g_free (name);
g_object_set (object->gnlobject, "priority", 0, NULL);
element = klass->create_element (self);
if (!GST_IS_ELEMENT (element))
return FALSE;
gst_bin_add (GST_BIN (object->gnlobject), element);
return TRUE;
}
GstElement *
ges_track_transition_create_element (GESTrackTransition * self)
{
GST_WARNING ("transitions don't handle this track type!");
return NULL;
}
static void
ges_track_transition_class_init (GESTrackTransitionClass * klass)
{
GESTrackObjectClass *track_class = GES_TRACK_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTrackTransitionPrivate));
track_class->create_gnl_object = ges_track_transition_create_gnl_object;
klass->create_element = ges_track_transition_create_element;
}
static void
@ -89,5 +48,4 @@ ges_track_transition_init (GESTrackTransition * self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_TRACK_TRANSITION, GESTrackTransitionPrivate);
}

View file

@ -71,16 +71,12 @@ struct _GESTrackTransition
/**
* GESTrackTransitionClass:
* @create_element: return the element that should be controlled by the transition
*/
struct _GESTrackTransitionClass {
/*< private >*/
GESTrackOperationClass parent_class;
/*< public >*/
GstElement* (*create_element) (GESTrackTransition *self);
/*< private >*/
/* Padding for API extension */
gpointer _ges_reserved[GES_PADDING];

View file

@ -36,19 +36,17 @@ struct _GESTrackVideoTestSourcePrivate
void *nothing;
};
static GstElement *ges_track_video_test_source_create_element (GESTrackSource *
static GstElement *ges_track_video_test_source_create_element (GESTrackObject *
self);
static void
ges_track_video_test_source_class_init (GESTrackVideoTestSourceClass * klass)
{
GESTrackSourceClass *track_source_class;
GESTrackObjectClass *track_object_class = GES_TRACK_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTrackVideoTestSourcePrivate));
track_source_class = GES_TRACK_SOURCE_CLASS (klass);
track_source_class->create_element =
track_object_class->create_element =
ges_track_video_test_source_create_element;
}
@ -62,7 +60,7 @@ ges_track_video_test_source_init (GESTrackVideoTestSource * self)
}
static GstElement *
ges_track_video_test_source_create_element (GESTrackSource * self)
ges_track_video_test_source_create_element (GESTrackObject * self)
{
GstElement *ret;
gint pattern;
@ -81,7 +79,7 @@ ges_track_video_test_source_set_pattern (GESTrackVideoTestSource
{
GstElement *element;
element = GES_TRACK_SOURCE (self)->element;
element = GES_TRACK_OBJECT (self)->element;
self->pattern = pattern;
if (element)

View file

@ -53,7 +53,7 @@ static void
ges_track_video_transition_duration_changed (GESTrackObject * self,
guint64 duration);
static GstElement *ges_track_video_transition_create_element (GESTrackTransition
static GstElement *ges_track_video_transition_create_element (GESTrackObject
* self);
static void ges_track_video_transition_dispose (GObject * object);
@ -71,13 +71,11 @@ ges_track_video_transition_class_init (GESTrackVideoTransitionClass * klass)
{
GObjectClass *object_class;
GESTrackObjectClass *toclass;
GESTrackTransitionClass *pclass;
g_type_class_add_private (klass, sizeof (GESTrackVideoTransitionPrivate));
object_class = G_OBJECT_CLASS (klass);
toclass = GES_TRACK_OBJECT_CLASS (klass);
pclass = GES_TRACK_TRANSITION_CLASS (klass);
object_class->get_property = ges_track_video_transition_get_property;
object_class->set_property = ges_track_video_transition_set_property;
@ -85,8 +83,7 @@ ges_track_video_transition_class_init (GESTrackVideoTransitionClass * klass)
object_class->finalize = ges_track_video_transition_finalize;
toclass->duration_changed = ges_track_video_transition_duration_changed;
pclass->create_element = ges_track_video_transition_create_element;
toclass->create_element = ges_track_video_transition_create_element;
}
static void
@ -169,7 +166,7 @@ ges_track_video_transition_set_property (GObject * object,
}
static GstElement *
ges_track_video_transition_create_element (GESTrackTransition * object)
ges_track_video_transition_create_element (GESTrackObject * object)
{
GstElement *topbin, *iconva, *iconvb, *oconv;
GObject *target = NULL;