static void ges_audio_test_source_set_property (GObject * object, guint
property_id, const GValue * value, GParamSpec * pspec);
-static GstElement *ges_audio_test_source_create_element (GESTrackElement *
- self);
+static GstElement *ges_audio_test_source_create_source (GESTrackElement * self);
static void
ges_audio_test_source_class_init (GESAudioTestSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GESTrackElementClass *bg_class = GES_TRACK_ELEMENT_CLASS (klass);
+ GESSourceClass *source_class = GES_SOURCE_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESAudioTestSourcePrivate));
object_class->get_property = ges_audio_test_source_get_property;
object_class->set_property = ges_audio_test_source_set_property;
- bg_class->create_element = ges_audio_test_source_create_element;
+ source_class->create_source = ges_audio_test_source_create_source;
}
static void
}
static GstElement *
-ges_audio_test_source_create_element (GESTrackElement * trksrc)
+ges_audio_test_source_create_source (GESTrackElement * trksrc)
{
GESAudioTestSource *self;
GstElement *ret;
}
static GstElement *
-ges_image_source_create_element (GESTrackElement * track_element)
+ges_image_source_create_source (GESTrackElement * track_element)
{
GstElement *bin, *source, *scale, *freeze, *iconv;
GstPad *src, *target;
ges_image_source_class_init (GESImageSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GESTrackElementClass *gesobj_class = GES_TRACK_ELEMENT_CLASS (klass);
+ GESSourceClass *source_class = GES_SOURCE_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESImageSourcePrivate));
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));
- gesobj_class->create_element = ges_image_source_create_element;
+ source_class->create_source = ges_image_source_create_source;
}
static void
* @short_description: Base Class for single-media sources
*/
-#include "ges-internal.h"
+#include "ges/ges-meta-container.h"
#include "ges-track-element.h"
#include "ges-source.h"
+#include "ges-layer.h"
+#include "gstframepositionner.h"
G_DEFINE_TYPE (GESSource, ges_source, GES_TYPE_TRACK_ELEMENT);
struct _GESSourcePrivate
{
/* Dummy variable */
- void *nothing;
+ GstFramePositionner *positionner;
};
static void
+_pad_added_cb (GstElement * element, GstPad * srcpad, GstPad * sinkpad)
+{
+ gst_element_no_more_pads (element);
+ gst_pad_link (srcpad, sinkpad);
+}
+
+static void
+_ghost_pad_added_cb (GstElement * element, GstPad * srcpad, GstElement * bin)
+{
+ GstPad *ghost;
+
+ ghost = gst_ghost_pad_new ("src", srcpad);
+ gst_pad_set_active (ghost, TRUE);
+ gst_element_add_pad (bin, ghost);
+ gst_element_no_more_pads (element);
+}
+
+static GstElement *
+_create_bin (const gchar * bin_name, GstElement * sub_element, ...)
+{
+ va_list argp;
+
+ GstElement *element;
+ GstElement *prev = NULL;
+ GstElement *first = NULL;
+ GstElement *bin;
+ GstPad *sub_srcpad;
+
+ va_start (argp, sub_element);
+ bin = gst_bin_new (bin_name);
+ gst_bin_add (GST_BIN (bin), sub_element);
+
+ while ((element = va_arg (argp, GstElement *)) != NULL) {
+ gst_bin_add (GST_BIN (bin), element);
+ if (prev)
+ gst_element_link (prev, element);
+ prev = element;
+ if (first == NULL)
+ first = element;
+ }
+
+ va_end (argp);
+
+ sub_srcpad = gst_element_get_static_pad (sub_element, "src");
+
+ if (prev != NULL) {
+ GstPad *srcpad, *sinkpad, *ghost;
+
+ srcpad = gst_element_get_static_pad (prev, "src");
+ ghost = gst_ghost_pad_new ("src", srcpad);
+ gst_pad_set_active (ghost, TRUE);
+ gst_element_add_pad (bin, ghost);
+
+ sinkpad = gst_element_get_static_pad (first, "sink");
+ if (sub_srcpad)
+ gst_pad_link (sub_srcpad, sinkpad);
+ else
+ g_signal_connect (sub_element, "pad-added", G_CALLBACK (_pad_added_cb),
+ sinkpad);
+
+ gst_object_unref (srcpad);
+ gst_object_unref (sinkpad);
+
+ } else if (sub_srcpad) {
+ GstPad *ghost;
+
+ ghost = gst_ghost_pad_new ("src", sub_srcpad);
+ gst_pad_set_active (ghost, TRUE);
+ gst_element_add_pad (bin, ghost);
+ } else {
+ g_signal_connect (sub_element, "pad-added",
+ G_CALLBACK (_ghost_pad_added_cb), bin);
+ }
+
+ return bin;
+}
+
+static void
+_sync_element_to_layer_property_float (GESTrackElement * trksrc,
+ GstElement * element, const gchar * meta, const gchar * propname)
+{
+ GESTimelineElement *parent;
+ GESLayer *layer;
+ gfloat value;
+
+ parent = ges_timeline_element_get_parent (GES_TIMELINE_ELEMENT (trksrc));
+ layer = ges_clip_get_layer (GES_CLIP (parent));
+
+ gst_object_unref (parent);
+
+ if (layer != NULL) {
+
+ ges_meta_container_get_float (GES_META_CONTAINER (layer), meta, &value);
+ g_object_set (element, propname, value, NULL);
+ GST_DEBUG_OBJECT (trksrc, "Setting %s to %f", propname, value);
+
+ } else {
+
+ GST_DEBUG_OBJECT (trksrc, "NOT setting the %s", propname);
+ }
+
+ gst_object_unref (layer);
+}
+
+static void
+update_z_order_cb (GESClip * clip, GParamSpec * arg G_GNUC_UNUSED,
+ GESSource * self)
+{
+ GESLayer *layer = ges_clip_get_layer (clip);
+
+ if (layer == NULL)
+ return;
+
+ /* 10000 is the max value of zorder on videomixerpad, hardcoded */
+
+ g_object_set (self->priv->positionner, "zorder",
+ 10000 - ges_layer_get_priority (layer), NULL);
+
+ gst_object_unref (layer);
+}
+
+static GstElement *
+ges_source_create_element (GESTrackElement * trksrc)
+{
+ GstElement *topbin;
+ GstElement *sub_element;
+ GESSourceClass *source_class = GES_SOURCE_GET_CLASS (trksrc);
+ GESTrack *track;
+ GESSource *self;
+
+ if (!source_class->create_source)
+ return NULL;
+
+ sub_element = source_class->create_source (trksrc);
+
+ track = ges_track_element_get_track (trksrc);
+
+ self = (GESSource *) trksrc;
+
+ switch (track->type) {
+ case GES_TRACK_TYPE_AUDIO:
+ {
+ const gchar *props[] = { "volume", "mute", NULL };
+ GstElement *volume;
+
+ GST_DEBUG_OBJECT (trksrc, "Creating a bin sub_element ! volume");
+
+ volume = gst_element_factory_make ("volume", NULL);
+
+ topbin = _create_bin ("audio-src-bin", sub_element, volume, NULL);
+
+ _sync_element_to_layer_property_float (trksrc, volume, GES_META_VOLUME,
+ "volume");
+ ges_track_element_add_children_props (trksrc, volume, NULL, NULL, props);
+ break;
+ }
+ case GES_TRACK_TYPE_VIDEO:
+ {
+ GstElement *positionner;
+ const gchar *props[] = { "alpha", "posx", "posy", NULL };
+ GESTimelineElement *parent;
+
+ /* That positionner will add metadata to buffers according to its
+ properties, acting like a proxy for our smart-mixer dynamic pads. */
+ positionner =
+ gst_element_factory_make ("framepositionner", "frame_tagger");
+
+ ges_track_element_add_children_props (trksrc, positionner, NULL, NULL,
+ props);
+ topbin = _create_bin ("video-src-bin", sub_element, positionner, NULL);
+ parent = ges_timeline_element_get_parent (GES_TIMELINE_ELEMENT (trksrc));
+ if (parent) {
+ self->priv->positionner = GST_FRAME_POSITIONNER (positionner);
+ g_signal_connect (parent, "notify::layer",
+ (GCallback) update_z_order_cb, trksrc);
+ update_z_order_cb (GES_CLIP (parent), NULL, self);
+ gst_object_unref (parent);
+ } else {
+ GST_WARNING ("No parent timeline element, SHOULD NOT HAPPEN");
+ }
+ break;
+ }
+ default:
+ topbin = _create_bin ("a-questionable-name", sub_element, NULL);
+ break;
+ }
+
+ return topbin;
+}
+
+static void
ges_source_class_init (GESSourceClass * klass)
{
GESTrackElementClass *track_class = GES_TRACK_ELEMENT_CLASS (klass);
+ GESSourceClass *source_class = GES_SOURCE_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESSourcePrivate));
track_class->gnlobject_factorytype = "gnlsource";
- track_class->create_element = NULL;
+ track_class->create_element = ges_source_create_element;
+ source_class->create_source = NULL;
}
static void
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_SOURCE, GESSourcePrivate);
+ self->priv->positionner = NULL;
}
/**
* GESSourceClass:
+ * @create_source: method to return the GstElement to put in the source topbin.
*/
struct _GESSourceClass {
/*< private >*/
/* Padding for API extension */
+ GstElement* (*create_source) (GESTrackElement * object);
gpointer _ges_reserved[GES_PADDING];
};
static void ges_title_source_set_property (GObject * object, guint
property_id, const GValue * value, GParamSpec * pspec);
-static GstElement *ges_title_source_create_element (GESTrackElement * self);
+static GstElement *ges_title_source_create_source (GESTrackElement * self);
static void
ges_title_source_class_init (GESTitleSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GESTrackElementClass *bg_class = GES_TRACK_ELEMENT_CLASS (klass);
+ GESSourceClass *source_class = GES_SOURCE_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESTitleSourcePrivate));
object_class->set_property = ges_title_source_set_property;
object_class->dispose = ges_title_source_dispose;
- bg_class->create_element = ges_title_source_create_element;
+ source_class->create_source = ges_title_source_create_source;
}
static void
}
static GstElement *
-ges_title_source_create_element (GESTrackElement * object)
+ges_title_source_create_source (GESTrackElement * object)
{
GESTitleSource *self = GES_TITLE_SOURCE (object);
GESTitleSourcePrivate *priv = self->priv;
#include "ges-uri-source.h"
#include "ges-uri-asset.h"
#include "ges-extractable.h"
-#include "ges-layer.h"
-#include "gstframepositionner.h"
struct _GESUriSourcePrivate
{
- GstFramePositionner *positionner;
+ void *nothing;
};
enum
PROP_URI
};
-/* Callbacks */
-
-static void
-_pad_added_cb (GstElement * element, GstPad * srcpad, GstPad * sinkpad)
-{
- gst_element_no_more_pads (element);
- gst_pad_link (srcpad, sinkpad);
-}
-
-static void
-_ghost_pad_added_cb (GstElement * element, GstPad * srcpad, GstElement * bin)
-{
- GstPad *ghost;
-
- ghost = gst_ghost_pad_new ("src", srcpad);
- gst_pad_set_active (ghost, TRUE);
- gst_element_add_pad (bin, ghost);
- gst_element_no_more_pads (element);
-}
-
-/* Internal methods */
-
+/* GESSource VMethod */
static GstElement *
-_create_bin (const gchar * bin_name, GstElement * decodebin, ...)
-{
- va_list argp;
-
- GstElement *element;
- GstElement *prev = NULL;
- GstElement *first = NULL;
- GstElement *bin;
-
- va_start (argp, decodebin);
- bin = gst_bin_new (bin_name);
- gst_bin_add (GST_BIN (bin), decodebin);
-
- while ((element = va_arg (argp, GstElement *)) != NULL) {
- gst_bin_add (GST_BIN (bin), element);
- if (prev)
- gst_element_link (prev, element);
- prev = element;
- if (first == NULL)
- first = element;
- }
-
- va_end (argp);
-
- if (prev != NULL) {
- GstPad *srcpad, *sinkpad, *ghost;
-
- srcpad = gst_element_get_static_pad (prev, "src");
- ghost = gst_ghost_pad_new ("src", srcpad);
- gst_pad_set_active (ghost, TRUE);
- gst_element_add_pad (bin, ghost);
-
- sinkpad = gst_element_get_static_pad (first, "sink");
- g_signal_connect (decodebin, "pad-added", G_CALLBACK (_pad_added_cb),
- sinkpad);
-
- gst_object_unref (srcpad);
- gst_object_unref (sinkpad);
-
- } else {
- /* Our decodebin is alone in the bin, we need to ghost its source when it appears */
-
- g_signal_connect (decodebin, "pad-added", G_CALLBACK (_ghost_pad_added_cb),
- bin);
- }
-
- return bin;
-}
-
-static void
-_sync_element_to_layer_property_float (GESTrackElement * trksrc,
- GstElement * element, const gchar * meta, const gchar * propname)
-{
- GESTimelineElement *parent;
- GESLayer *layer;
- gfloat value;
-
- parent = ges_timeline_element_get_parent (GES_TIMELINE_ELEMENT (trksrc));
- layer = ges_clip_get_layer (GES_CLIP (parent));
-
- gst_object_unref (parent);
-
- if (layer != NULL) {
-
- ges_meta_container_get_float (GES_META_CONTAINER (layer), meta, &value);
- g_object_set (element, propname, value, NULL);
- GST_DEBUG_OBJECT (trksrc, "Setting %s to %f", propname, value);
-
- } else {
-
- GST_DEBUG_OBJECT (trksrc, "NOT setting the %s", propname);
- }
-
- gst_object_unref (layer);
-}
-
-/* TrackElement VMethods */
-
-static void
-update_z_order_cb (GESClip * clip, GParamSpec * arg G_GNUC_UNUSED,
- GESUriSource * self)
-{
- GESLayer *layer = ges_clip_get_layer (clip);
-
- if (layer == NULL)
- return;
-
- /* 10000 is the max value of zorder on videomixerpad, hardcoded */
-
- g_object_set (self->priv->positionner, "zorder",
- 10000 - ges_layer_get_priority (layer), NULL);
-
- gst_object_unref (layer);
-}
-
-static GstElement *
-ges_uri_source_create_element (GESTrackElement * trksrc)
+ges_uri_source_create_source (GESTrackElement * trksrc)
{
GESUriSource *self;
GESTrack *track;
GstElement *decodebin;
- GstElement *topbin, *volume;
- GstElement *positionner;
- GESTimelineElement *parent;
self = (GESUriSource *) trksrc;
- track = ges_track_element_get_track (trksrc);
-
- switch (track->type) {
- case GES_TRACK_TYPE_AUDIO:
- {
- const gchar *props[] = { "volume", "mute", NULL };
-
- GST_DEBUG_OBJECT (trksrc, "Creating a bin uridecodebin ! volume");
-
- decodebin = gst_element_factory_make ("uridecodebin", NULL);
- volume = gst_element_factory_make ("volume", NULL);
- topbin = _create_bin ("audio-src-bin", decodebin, volume, NULL);
+ track = ges_track_element_get_track (trksrc);
- _sync_element_to_layer_property_float (trksrc, volume, GES_META_VOLUME,
- "volume");
- ges_track_element_add_children_props (trksrc, volume, NULL, NULL, props);
- break;
- }
- case GES_TRACK_TYPE_VIDEO:
- {
- const gchar *props[] = { "alpha", "posx", "posy", NULL };
-
- decodebin = gst_element_factory_make ("uridecodebin", NULL);
-
- /* That positionner will add metadata to buffers according to its
- properties, acting like a proxy for our smart-mixer dynamic pads. */
- positionner =
- gst_element_factory_make ("framepositionner", "frame_tagger");
-
- ges_track_element_add_children_props (trksrc, positionner, NULL, NULL,
- props);
- topbin = _create_bin ("video-src-bin", decodebin, positionner, NULL);
- parent = ges_timeline_element_get_parent (GES_TIMELINE_ELEMENT (trksrc));
- if (parent) {
- self->priv->positionner = GST_FRAME_POSITIONNER (positionner);
- g_signal_connect (parent, "notify::layer",
- (GCallback) update_z_order_cb, trksrc);
- update_z_order_cb (GES_CLIP (parent), NULL, self);
- gst_object_unref (parent);
- } else {
- GST_WARNING ("No parent timeline element, SHOULD NOT HAPPEN");
- }
- break;
- }
- default:
- decodebin = gst_element_factory_make ("uridecodebin", NULL);
- topbin = _create_bin ("video-src-bin", decodebin, NULL);
- break;
- }
+ decodebin = gst_element_factory_make ("uridecodebin", NULL);
g_object_set (decodebin, "caps", ges_track_get_caps (track),
"expose-all-streams", FALSE, "uri", self->uri, NULL);
- return topbin;
+ return decodebin;
}
/* Extractable interface implementation */
ges_track_filesource_class_init (GESUriSourceClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GESTrackElementClass *track_class = GES_TRACK_ELEMENT_CLASS (klass);
+ GESSourceClass *source_class = GES_SOURCE_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESUriSourcePrivate));
g_param_spec_string ("uri", "URI", "uri of the resource",
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- track_class->create_element = ges_uri_source_create_element;
+ source_class->create_source = ges_uri_source_create_source;
}
static void
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_URI_SOURCE, GESUriSourcePrivate);
- self->priv->positionner = NULL;
}
/**
#include <glib-object.h>
#include <ges/ges-types.h>
#include <ges/ges-source.h>
-#include <ges/ges-meta-container.h>
G_BEGIN_DECLS
GESVideoTestPattern pattern;
};
-static GstElement *ges_video_test_source_create_element (GESTrackElement *
- self);
+static GstElement *ges_video_test_source_create_source (GESTrackElement * self);
static void
ges_video_test_source_class_init (GESVideoTestSourceClass * klass)
{
- GESTrackElementClass *track_element_class = GES_TRACK_ELEMENT_CLASS (klass);
+ GESSourceClass *source_class = GES_SOURCE_CLASS (klass);
g_type_class_add_private (klass, sizeof (GESVideoTestSourcePrivate));
- track_element_class->create_element = ges_video_test_source_create_element;
+ source_class->create_source = ges_video_test_source_create_source;
}
static void
}
static GstElement *
-ges_video_test_source_create_element (GESTrackElement * self)
+ges_video_test_source_create_source (GESTrackElement * self)
{
gint pattern;
GstElement *ret;