"description": "Demuxer for complex timeline file formats using GES.",
"hierarchy": [
"GESDemux",
+ "GESBaseBin",
"GstBin",
"GstElement",
"GstObject",
"writable": true
},
"timeline": {
- "blurb": "Timeline to use in this source.",
+ "blurb": "Timeline to use in this src.",
"construct": false,
"construct-only": false,
"type-name": "GESTimeline",
- "writable": false
+ "writable": true
}
},
"rank": "primary",
}
},
"gessrc": {
- "author": "Erik Walthinsen <omega@cse.ogi.edu>,Wim Taymans <wim.taymans@gmail.com>",
- "description": "Simple container object",
+ "author": "Thibault Saunier <tsaunier@igalia.com",
+ "description": "Source for GESTimeline.",
"hierarchy": [
"GESSrc",
+ "GESBaseBin",
"GstBin",
"GstElement",
"GstObject",
"GInitiallyUnowned",
"GObject"
],
- "klass": "Generic/Bin",
- "long-name": "Generic bin",
+ "klass": "Codec/Source/Editing",
+ "long-name": "GStreamer Editing Services based 'source'",
"pad-templates": {
"audio_src": {
"caps": "audio/x-raw(ANY):\n",
--- /dev/null
+/* GStreamer GES plugin
+ *
+ * Copyright (C) 2019 Thibault Saunier <tsaunier@igalia.com>
+ *
+ * gesbasebin.h
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gesbasebin.h"
+
+static GstStaticPadTemplate video_src_template =
+GST_STATIC_PAD_TEMPLATE ("video_src",
+ GST_PAD_SRC,
+ GST_PAD_SOMETIMES,
+ GST_STATIC_CAPS ("video/x-raw(ANY)"));
+
+static GstStaticPadTemplate audio_src_template =
+ GST_STATIC_PAD_TEMPLATE ("audio_src",
+ GST_PAD_SRC,
+ GST_PAD_SOMETIMES,
+ GST_STATIC_CAPS ("audio/x-raw(ANY);"));
+
+typedef struct
+{
+ GESTimeline *timeline;
+ GstFlowCombiner *flow_combiner;
+} GESBaseBinPrivate;
+
+enum
+{
+ PROP_0,
+ PROP_TIMELINE,
+ PROP_LAST
+};
+
+static GParamSpec *properties[PROP_LAST];
+
+G_DEFINE_TYPE_WITH_PRIVATE (GESBaseBin, ges_base_bin, GST_TYPE_BIN);
+
+GST_DEBUG_CATEGORY_STATIC (gesbasebin);
+#define GST_CAT_DEFAULT gesbasebin
+
+static void
+ges_base_bin_dispose (GObject * object)
+{
+ GESBaseBin *self = GES_BASE_BIN (object);
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ if (priv->timeline)
+ gst_clear_object (&priv->timeline);
+}
+
+static void
+ges_base_bin_finalize (GObject * object)
+{
+ GESBaseBin *self = GES_BASE_BIN (object);
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ gst_flow_combiner_free (priv->flow_combiner);
+}
+
+static void
+ges_base_bin_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GESBaseBin *self = GES_BASE_BIN (object);
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ switch (property_id) {
+ case PROP_TIMELINE:
+ g_value_set_object (value, priv->timeline);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ges_base_bin_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GESBaseBin *self = GES_BASE_BIN (object);
+
+ switch (property_id) {
+ case PROP_TIMELINE:
+ ges_base_bin_set_timeline (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ges_base_bin_class_init (GESBaseBinClass * self_class)
+{
+ GObjectClass *gclass = G_OBJECT_CLASS (self_class);
+ GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (self_class);
+
+ GST_DEBUG_CATEGORY_INIT (gesbasebin, "gesbasebin", 0, "ges bin element");
+
+ gclass->get_property = ges_base_bin_get_property;
+ gclass->set_property = ges_base_bin_set_property;
+ gclass->dispose = ges_base_bin_dispose;
+ gclass->finalize = ges_base_bin_finalize;
+
+ /**
+ * GESBaseBin:timeline:
+ *
+ * Timeline to use in this bin.
+ */
+ properties[PROP_TIMELINE] = g_param_spec_object ("timeline", "Timeline",
+ "Timeline to use in this src.",
+ GES_TYPE_TIMELINE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (gclass, PROP_LAST, properties);
+
+ gst_element_class_add_pad_template (gstelement_klass,
+ gst_static_pad_template_get (&video_src_template));
+ gst_element_class_add_pad_template (gstelement_klass,
+ gst_static_pad_template_get (&audio_src_template));
+}
+
+static void
+ges_base_bin_init (GESBaseBin * self)
+{
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ priv->flow_combiner = gst_flow_combiner_new ();
+}
+
+static GstFlowReturn
+gst_bin_src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
+{
+ GstFlowReturn result, chain_result;
+ GESBaseBin *self = GES_BASE_BIN (GST_OBJECT_PARENT (parent));
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ chain_result = gst_proxy_pad_chain_default (pad, GST_OBJECT (self), buffer);
+ result =
+ gst_flow_combiner_update_pad_flow (priv->flow_combiner, pad,
+ chain_result);
+
+ if (result == GST_FLOW_FLUSHING)
+ return chain_result;
+
+ return result;
+}
+
+
+gboolean
+ges_base_bin_set_timeline (GESBaseBin * self, GESTimeline * timeline)
+{
+ GList *tmp;
+ guint naudiopad = 0, nvideopad = 0;
+ GstBin *sbin = GST_BIN (self);
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE);
+
+ if (priv->timeline) {
+ GST_ERROR_OBJECT (sbin, "Implement changing timeline support");
+
+ return FALSE;
+ }
+
+ priv->timeline = gst_object_ref (timeline);
+ GST_INFO_OBJECT (sbin, "Setting timeline: %" GST_PTR_FORMAT, timeline);
+ if (!gst_bin_add (sbin, GST_ELEMENT (timeline))) {
+ GST_ERROR_OBJECT (sbin, "Could not add timeline to myself!");
+
+ return FALSE;
+ }
+
+ for (tmp = timeline->tracks; tmp; tmp = tmp->next) {
+ GstPad *gpad;
+ gchar *name = NULL;
+ GstElement *queue;
+ GESTrack *track = GES_TRACK (tmp->data);
+ GstPad *proxy_pad, *tmppad, *pad =
+ ges_timeline_get_pad_for_track (timeline, track);
+ GstStaticPadTemplate *template;
+
+ if (!pad) {
+ GST_WARNING_OBJECT (sbin, "No pad for track: %" GST_PTR_FORMAT, track);
+
+ continue;
+ }
+
+ if (track->type == GES_TRACK_TYPE_AUDIO) {
+ name = g_strdup_printf ("audio_%u", naudiopad++);
+ template = &audio_src_template;
+ } else if (track->type == GES_TRACK_TYPE_VIDEO) {
+ name = g_strdup_printf ("video_%u", nvideopad++);
+ template = &video_src_template;
+ } else {
+ GST_INFO_OBJECT (sbin, "Track type not handled: %" GST_PTR_FORMAT, track);
+ continue;
+ }
+
+ queue = gst_element_factory_make ("queue", NULL);
+ /* Add queues the same way as in GESPipeline */
+ g_object_set (G_OBJECT (queue), "max-size-buffers", 0,
+ "max-size-bytes", 0, "max-size-time", (gint64) 2 * GST_SECOND, NULL);
+ gst_bin_add (sbin, queue);
+ gst_element_sync_state_with_parent (GST_ELEMENT (queue));
+
+ tmppad = gst_element_get_static_pad (queue, "sink");
+ if (gst_pad_link (pad, tmppad) != GST_PAD_LINK_OK) {
+ GST_ERROR_OBJECT (sbin, "Could not link %s:%s and %s:%s",
+ GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (tmppad));
+
+ gst_object_unref (tmppad);
+ gst_object_unref (queue);
+ continue;
+ }
+
+ tmppad = gst_element_get_static_pad (queue, "src");
+ gpad = gst_ghost_pad_new_from_template (name, tmppad,
+ gst_static_pad_template_get (template));
+
+ gst_pad_set_active (gpad, TRUE);
+ gst_element_add_pad (GST_ELEMENT (sbin), gpad);
+
+ proxy_pad = GST_PAD (gst_proxy_pad_get_internal (GST_PROXY_PAD (gpad)));
+ gst_flow_combiner_add_pad (priv->flow_combiner, proxy_pad);
+ gst_pad_set_chain_function (proxy_pad, gst_bin_src_chain);
+ gst_object_unref (proxy_pad);
+ GST_DEBUG_OBJECT (sbin, "Adding pad: %" GST_PTR_FORMAT, gpad);
+ }
+
+ gst_element_no_more_pads (GST_ELEMENT (sbin));
+ gst_element_sync_state_with_parent (GST_ELEMENT (timeline));
+
+ return TRUE;
+}
+
+GESTimeline *
+ges_base_bin_get_timeline (GESBaseBin * self)
+{
+ GESBaseBinPrivate *priv = ges_base_bin_get_instance_private (self);
+
+ return priv->timeline;
+}
--- /dev/null
+/* GStreamer GES plugin
+ *
+ * Copyright (C) 2019 Thibault Saunier <tsaunier@igalia.com>
+ *
+ * gesbasebin.h
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __GES_BASE_BIN_H__
+#define __GES_BASE_BIN_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstflowcombiner.h>
+#include <ges/ges.h>
+
+G_BEGIN_DECLS
+
+G_DECLARE_DERIVABLE_TYPE(GESBaseBin, ges_base_bin, GES, BASE_BIN, GstBin)
+
+struct _GESBaseBinClass
+{
+ GstBinClass parent_class;
+};
+
+gboolean ges_base_bin_set_timeline (GESBaseBin * self, GESTimeline * timeline);
+GESTimeline * ges_base_bin_get_timeline (GESBaseBin * self);
+
+G_END_DECLS
+#endif /* __GES_BASE_BIN_H__ */
\ No newline at end of file
#include "config.h"
#endif
+#include "gesbasebin.h"
+
#include <gst/gst.h>
#include <glib/gstdio.h>
#include <gst/pbutils/pbutils.h>
#include <gst/base/gstadapter.h>
#include <ges/ges.h>
-#include <gst/base/gstflowcombiner.h>
GST_DEBUG_CATEGORY_STATIC (gesdemux);
#define GST_CAT_DEFAULT gesdemux
-static GstStaticPadTemplate video_src_template =
-GST_STATIC_PAD_TEMPLATE ("video_src",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS ("video/x-raw(ANY)"));
-
-static GstStaticPadTemplate audio_src_template =
- GST_STATIC_PAD_TEMPLATE ("audio_src",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS ("audio/x-raw(ANY);"));
-
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/xges"));
-G_DECLARE_FINAL_TYPE (GESDemux, ges_demux, GES, Demux, GstBin);
+G_DECLARE_FINAL_TYPE (GESDemux, ges_demux, GES, Demux, GESBaseBin);
struct _GESDemux
{
- GstBin parent;
+ GESBaseBin parent;
GESTimeline *timeline;
GstPad *sinkpad;
GstAdapter *input_adapter;
- GstFlowCombiner *flow_combiner;
};
-G_DEFINE_TYPE (GESDemux, ges_demux, GST_TYPE_BIN);
+G_DEFINE_TYPE (GESDemux, ges_demux, ges_base_bin_get_type ());
#define GES_DEMUX(obj) ((GESDemux*)obj)
enum
static GParamSpec *properties[PROP_LAST];
-static GstFlowReturn
-gst_demux_src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
-{
- GstFlowReturn result, chain_result;
- GESDemux *self = GES_DEMUX (GST_OBJECT_PARENT (parent));
-
- chain_result = gst_proxy_pad_chain_default (pad, GST_OBJECT (self), buffer);
- result =
- gst_flow_combiner_update_pad_flow (self->flow_combiner, pad,
- chain_result);
-
- if (result == GST_FLOW_FLUSHING) {
- return chain_result;
- }
-
- return result;
-}
-
-static gboolean
-ges_demux_set_timeline (GESDemux * self, GESTimeline * timeline)
-{
- GList *tmp;
- guint naudiopad = 0, nvideopad = 0;
- GstBin *sbin = GST_BIN (self);
-
- g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE);
-
- if (self->timeline) {
- GST_ERROR_OBJECT (self, "Implement changing timeline support");
-
- return FALSE;
- }
-
- GST_INFO_OBJECT (self, "Setting timeline: %" GST_PTR_FORMAT, timeline);
- self->timeline = gst_object_ref (timeline);
-
- if (!gst_bin_add (sbin, GST_ELEMENT (self->timeline))) {
- GST_ERROR_OBJECT (self, "Could not add timeline to myself!");
-
- return FALSE;
- }
-
- for (tmp = self->timeline->tracks; tmp; tmp = tmp->next) {
- GstPad *gpad;
- gchar *name = NULL;
- GstElement *queue;
- GESTrack *track = GES_TRACK (tmp->data);
- GstPad *proxy_pad, *tmppad, *pad =
- ges_timeline_get_pad_for_track (self->timeline, track);
- GstStaticPadTemplate *template;
-
- if (!pad) {
- GST_WARNING_OBJECT (self, "No pad for track: %" GST_PTR_FORMAT, track);
-
- continue;
- }
-
- if (track->type == GES_TRACK_TYPE_AUDIO) {
- name = g_strdup_printf ("audio_%u", naudiopad++);
- template = &audio_src_template;
- } else if (track->type == GES_TRACK_TYPE_VIDEO) {
- name = g_strdup_printf ("video_%u", nvideopad++);
- template = &video_src_template;
- } else {
- GST_INFO_OBJECT (self, "Track type not handled: %" GST_PTR_FORMAT, track);
- continue;
- }
-
- queue = gst_element_factory_make ("queue", NULL);
- /* Add queues the same way as in GESPipeline */
- g_object_set (G_OBJECT (queue), "max-size-buffers", 0,
- "max-size-bytes", 0, "max-size-time", (gint64) 2 * GST_SECOND, NULL);
- gst_bin_add (GST_BIN (self), queue);
- gst_element_sync_state_with_parent (GST_ELEMENT (queue));
-
- tmppad = gst_element_get_static_pad (queue, "sink");
- if (gst_pad_link (pad, tmppad) != GST_PAD_LINK_OK) {
- GST_ERROR_OBJECT (self, "Could not link %s:%s and %s:%s",
- GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (tmppad));
-
- gst_object_unref (tmppad);
- gst_object_unref (queue);
- continue;
- }
-
- tmppad = gst_element_get_static_pad (queue, "src");
- gpad = gst_ghost_pad_new_from_template (name, tmppad,
- gst_static_pad_template_get (template));
-
- gst_pad_set_active (gpad, TRUE);
- gst_element_add_pad (GST_ELEMENT (self), gpad);
-
- proxy_pad = GST_PAD (gst_proxy_pad_get_internal (GST_PROXY_PAD (gpad)));
- gst_flow_combiner_add_pad (self->flow_combiner, proxy_pad);
- gst_pad_set_chain_function (proxy_pad,
- (GstPadChainFunction) gst_demux_src_chain);
- gst_object_unref (proxy_pad);
- GST_DEBUG_OBJECT (self, "Adding pad: %" GST_PTR_FORMAT, gpad);
- }
-
- gst_element_sync_state_with_parent (GST_ELEMENT (self->timeline));
- gst_element_no_more_pads (GST_ELEMENT (self));
-
- return TRUE;
-}
-
static void
ges_demux_get_property (GObject * object, guint property_id,
GValue * value, GParamSpec * pspec)
switch (property_id) {
case PROP_TIMELINE:
- g_value_set_object (value, self->timeline);
+ g_value_set_object (value,
+ ges_base_bin_get_timeline (GES_BASE_BIN (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-ges_demux_dispose (GObject * object)
-{
- GESDemux *self = GES_DEMUX (object);
-
- if (self->timeline)
- gst_clear_object (&self->timeline);
-}
-
-static void
-ges_demux_finalize (GObject * object)
-{
- GESDemux *self = GES_DEMUX (object);
-
- gst_flow_combiner_free (self->flow_combiner);
-}
-
-static void
ges_demux_class_init (GESDemuxClass * self_class)
{
GObjectClass *gclass = G_OBJECT_CLASS (self_class);
gclass->get_property = ges_demux_get_property;
gclass->set_property = ges_demux_set_property;
- gclass->dispose = ges_demux_dispose;
- gclass->finalize = ges_demux_finalize;
/**
* GESDemux:timeline:
properties[PROP_TIMELINE] = g_param_spec_object ("timeline", "Timeline",
"Timeline to use in this source.",
GES_TYPE_TIMELINE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_override_property (gclass, PROP_TIMELINE, "timeline");
- g_object_class_install_properties (gclass, PROP_LAST, properties);
-
+ gst_element_class_add_pad_template (gstelement_klass,
+ gst_static_pad_template_get (&sink_template));
gst_element_class_set_static_metadata (gstelement_klass,
"GStreamer Editing Services based 'demuxer'",
"Codec/Demux/Editing",
"Demuxer for complex timeline file formats using GES.",
"Thibault Saunier <tsaunier@igalia.com");
-
- gst_element_class_add_pad_template (gstelement_klass,
- gst_static_pad_template_get (&sink_template));
- gst_element_class_add_pad_template (gstelement_klass,
- gst_static_pad_template_get (&video_src_template));
- gst_element_class_add_pad_template (gstelement_klass,
- gst_static_pad_template_get (&audio_src_template));
}
typedef struct
GST_INFO_OBJECT (self, "Timeline properly loaded: %" GST_PTR_FORMAT,
data.timeline);
- ges_demux_set_timeline (self, data.timeline);
+ ges_base_bin_set_timeline (GES_BASE_BIN (self), data.timeline);
done:
g_free (filename);
g_free (uri);
gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
self->input_adapter = gst_adapter_new ();
- self->flow_combiner = gst_flow_combiner_new ();
gst_pad_set_chain_function (self->sinkpad,
GST_DEBUG_FUNCPTR (ges_demux_sink_chain));
#include <gst/gst.h>
#include <ges/ges.h>
+#include "gesbasebin.h"
+
GST_DEBUG_CATEGORY_STATIC (gessrc);
#define GST_CAT_DEFAULT gessrc
-static GstStaticPadTemplate video_src_template =
-GST_STATIC_PAD_TEMPLATE ("video_src",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS ("video/x-raw(ANY)"));
-
-static GstStaticPadTemplate audio_src_template =
- GST_STATIC_PAD_TEMPLATE ("audio_src",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_STATIC_CAPS ("audio/x-raw(ANY);"));
-
-G_DECLARE_FINAL_TYPE (GESSrc, ges_src, GES, SRC, GstBin);
+G_DECLARE_FINAL_TYPE (GESSrc, ges_src, GES, SRC, GESBaseBin);
struct _GESSrc
{
- GstBin parent;
-
- GESTimeline *timeline;
+ GESBaseBin parent;
};
#define GES_SRC(obj) ((GESSrc*) obj)
-enum
-{
- PROP_0,
- PROP_TIMELINE,
- PROP_LAST
-};
-
-static GParamSpec *properties[PROP_LAST];
-
-static gboolean
-ges_src_set_timeline (GESSrc * self, GESTimeline * timeline)
-{
- GList *tmp;
- guint naudiopad = 0, nvideopad = 0;
- GstBin *sbin = GST_BIN (self);
-
- g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE);
-
- if (self->timeline) {
- GST_FIXME_OBJECT (self, "Implement changing timeline support");
-
- return FALSE;
- }
-
- self->timeline = timeline;
-
- gst_bin_add (sbin, GST_ELEMENT (self->timeline));
- for (tmp = self->timeline->tracks; tmp; tmp = tmp->next) {
- GstPad *gpad;
- gchar *name = NULL;
- GstElement *queue;
- GESTrack *track = GES_TRACK (tmp->data);
- GstPad *tmppad, *pad =
- ges_timeline_get_pad_for_track (self->timeline, track);
- GstStaticPadTemplate *template;
-
- if (!pad) {
- GST_INFO_OBJECT (self, "No pad for track: %" GST_PTR_FORMAT, track);
-
- continue;
- }
-
- if (track->type == GES_TRACK_TYPE_AUDIO) {
- name = g_strdup_printf ("audio_%u", naudiopad++);
- template = &audio_src_template;
- } else if (track->type == GES_TRACK_TYPE_VIDEO) {
- name = g_strdup_printf ("video_%u", nvideopad++);
- template = &video_src_template;
- } else {
- GST_INFO_OBJECT (self, "Track type not handled: %" GST_PTR_FORMAT, track);
- continue;
- }
-
- queue = gst_element_factory_make ("queue", NULL);
- /* Add queues the same way as in GESPipeline */
- g_object_set (G_OBJECT (queue), "max-size-buffers", 0,
- "max-size-bytes", 0, "max-size-time", (gint64) 2 * GST_SECOND, NULL);
- gst_bin_add (GST_BIN (self), queue);
-
- tmppad = gst_element_get_static_pad (queue, "sink");
- if (gst_pad_link (pad, tmppad) != GST_PAD_LINK_OK) {
- GST_ERROR ("Could not link %s:%s and %s:%s",
- GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (tmppad));
-
- gst_object_unref (tmppad);
- gst_object_unref (queue);
- continue;
- }
-
- tmppad = gst_element_get_static_pad (queue, "src");
- gpad = gst_ghost_pad_new_from_template (name, tmppad,
- gst_static_pad_template_get (template));
-
- gst_pad_set_active (gpad, TRUE);
- gst_element_add_pad (GST_ELEMENT (self), gpad);
- }
-
- gst_element_sync_state_with_parent (GST_ELEMENT (self->timeline));
-
- return TRUE;
-}
-
/*** GSTURIHANDLER INTERFACE *************************************************/
static GstURIType
ges_src_uri_get_uri (GstURIHandler * handler)
{
GESSrc *self = GES_SRC (handler);
+ GESTimeline *timeline = ges_base_bin_get_timeline (GES_BASE_BIN (self));
- return self->timeline ? g_strdup_printf ("ges://%s",
- GST_OBJECT_NAME (self->timeline)) : NULL;
+ return timeline ? g_strdup_printf ("ges://%s",
+ GST_OBJECT_NAME (timeline)) : NULL;
}
static gboolean
iface->set_uri = ges_src_uri_set_uri;
}
-G_DEFINE_TYPE_WITH_CODE (GESSrc, ges_src, GST_TYPE_BIN,
+G_DEFINE_TYPE_WITH_CODE (GESSrc, ges_src, ges_base_bin_get_type (),
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, ges_src_uri_handler_init));
static void
-ges_src_get_property (GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec)
-{
- GESSrc *self = GES_SRC (object);
-
- switch (property_id) {
- case PROP_TIMELINE:
- g_value_set_object (value, self->timeline);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-ges_src_set_property (GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec)
-{
- GESSrc *self = GES_SRC (object);
-
- switch (property_id) {
- case PROP_TIMELINE:
- ges_src_set_timeline (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
ges_src_class_init (GESSrcClass * self_class)
{
- GObjectClass *gclass = G_OBJECT_CLASS (self_class);
GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (self_class);
GST_DEBUG_CATEGORY_INIT (gessrc, "gessrc", 0, "ges src element");
-
- gclass->get_property = ges_src_get_property;
- gclass->set_property = ges_src_set_property;
-
- /**
- * GESSrc:timeline:
- *
- * Timeline to use in this src.
- */
- properties[PROP_TIMELINE] = g_param_spec_object ("timeline", "Timeline",
- "Timeline to use in this src.",
- GES_TYPE_TIMELINE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (gclass, PROP_LAST, properties);
-
- gst_element_class_add_pad_template (gstelement_klass,
- gst_static_pad_template_get (&video_src_template));
- gst_element_class_add_pad_template (gstelement_klass,
- gst_static_pad_template_get (&audio_src_template));
+ gst_element_class_set_static_metadata (gstelement_klass,
+ "GStreamer Editing Services based 'source'",
+ "Codec/Source/Editing",
+ "Source for GESTimeline.", "Thibault Saunier <tsaunier@igalia.com");
}
static void
-gstges_sources = ['gesplugin.c', 'gessrc.c', 'gesdemux.c']
+gstges_sources = ['gesplugin.c', 'gessrc.c', 'gesdemux.c', 'gesbasebin.c']
gstges = library('gstges', gstges_sources,
dependencies : [gst_dep, ges_dep],