From 6876e6294a33c9ae3a2d670df7ff5df1d24c1159 Mon Sep 17 00:00:00 2001 From: Erik Mateos Date: Wed, 9 Oct 2024 12:14:35 +0200 Subject: [PATCH 01/13] Added framerate variable to CompositeMixer struct --- .../module-elements/src/gst-plugins/kmscompositemixer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c b/server/module-elements/src/gst-plugins/kmscompositemixer.c index 4c32112f8..bee993c4e 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.c +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.c @@ -97,7 +97,7 @@ struct _KmsCompositeMixerPrivate KmsLoop *loop; GRecMutex mutex; gint n_elems; - gint output_width, output_height; + gint output_width, output_height, output_framerate; }; /* class initialization */ @@ -162,7 +162,7 @@ kms_composite_mixer_recalculate_sizes (gpointer data) { KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); GstCaps *filtercaps; - gint width, height, top, left, counter, n_columns, n_rows; + gint width, height, top, left, counter, n_columns, n_rows, fps; GList *l; GList *values = g_hash_table_get_values (self->priv->ports); @@ -180,6 +180,7 @@ kms_composite_mixer_recalculate_sizes (gpointer data) width = self->priv->output_width / n_columns; height = self->priv->output_height / n_rows; + fps = self->priv->fps; for (l = values; l != NULL; l = l->next) { KmsCompositeMixerData *port_data = l->data; @@ -564,6 +565,7 @@ kms_composite_mixer_port_data_create (KmsCompositeMixer * mixer, gint id) gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, mixer->priv->output_width, "height", G_TYPE_INT, mixer->priv->output_height, + "framerate", GST_TYPE_FRACTION, mixer->priv->output_framerate, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); g_object_set (data->capsfilter, "caps", filtercaps, NULL); gst_caps_unref (filtercaps); @@ -697,7 +699,7 @@ kms_composite_mixer_handle_port (KmsBaseHub * mixer, gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, self->priv->output_width, "height", G_TYPE_INT, self->priv->output_height, - "framerate", GST_TYPE_FRACTION, 15, 1, NULL); + "framerate", GST_TYPE_FRACTION, self->priv->output_framerate, 1, NULL); g_object_set (G_OBJECT (capsfilter), "caps", filtercaps, NULL); gst_caps_unref (filtercaps); @@ -841,6 +843,7 @@ kms_composite_mixer_init (KmsCompositeMixer * self) //TODO:Obtain the dimensions of the bigger input stream self->priv->output_height = 600; self->priv->output_width = 800; + self->priv->output_framerate = 15; self->priv->n_elems = 0; self->priv->loop = kms_loop_new (); From 0c15e06d9359a0e1668394984a0ebc6b20dcc885 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Mon, 14 Oct 2024 14:01:18 +0200 Subject: [PATCH 02/13] Modified json Composite constructor to accept new parameters --- .../server/interface/elements.Composite.kmd.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/server/module-elements/src/server/interface/elements.Composite.kmd.json b/server/module-elements/src/server/interface/elements.Composite.kmd.json index ea8446384..cc50dbc06 100644 --- a/server/module-elements/src/server/interface/elements.Composite.kmd.json +++ b/server/module-elements/src/server/interface/elements.Composite.kmd.json @@ -12,6 +12,21 @@ "name": "mediaPipeline", "doc": "the :rom:cls:`MediaPipeline` to which the dispatcher belongs", "type": "MediaPipeline" + }, + { + "name": "width", + "doc": "screen width", + "type": "gInt" + }, + { + "name": "height", + "doc": "screen height", + "type": "gInt" + }, + { + "name": "framerate", + "doc": "frames per second", + "type": "gFraction" } ] } From ea2a48ec7d4b071aad8310dc615b883aa33c9bc3 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 16 Oct 2024 11:17:59 +0200 Subject: [PATCH 03/13] Modified json Composite parameter types --- .../src/server/interface/elements.Composite.kmd.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/module-elements/src/server/interface/elements.Composite.kmd.json b/server/module-elements/src/server/interface/elements.Composite.kmd.json index cc50dbc06..72961ba37 100644 --- a/server/module-elements/src/server/interface/elements.Composite.kmd.json +++ b/server/module-elements/src/server/interface/elements.Composite.kmd.json @@ -16,17 +16,17 @@ { "name": "width", "doc": "screen width", - "type": "gInt" + "type": "int64" }, { "name": "height", "doc": "screen height", - "type": "gInt" + "type": "int64" }, { "name": "framerate", "doc": "frames per second", - "type": "gFraction" + "type": "int64" } ] } From c44c109c62122ed673e2429c246f53c624670c5c Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 16 Oct 2024 11:23:07 +0200 Subject: [PATCH 04/13] Added resolution and framerate parameters to composite constructor --- .../server/implementation/objects/CompositeImpl.cpp | 11 +++++++---- .../server/implementation/objects/CompositeImpl.hpp | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp index 393b42395..d96d1fb2d 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp @@ -32,16 +32,19 @@ namespace kurento { CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline) : HubImpl (conf, - std::dynamic_pointer_cast (mediaPipeline), FACTORY_NAME) + std::shared_ptr mediaPipeline, int64_t width, int64_t height, + int64_t framerate) : HubImpl (conf, + std::dynamic_pointer_cast (mediaPipeline), FACTORY_NAME), + width (width), height (height), framerate (framerate) ) { } MediaObjectImpl * CompositeImplFactory::createObject (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline) const + std::shared_ptr mediaPipeline, + int64_t width, int64_t height, int64_t framerate) const { - return new CompositeImpl (conf, mediaPipeline); + return new CompositeImpl (conf, mediaPipeline, width, height, framerate); } CompositeImpl::StaticConstructor CompositeImpl::staticConstructor; diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp index 630c65648..11941c0b7 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp @@ -36,7 +36,8 @@ class CompositeImpl : public HubImpl, public virtual Composite public: CompositeImpl (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline); + std::shared_ptr mediaPipeline, + int64_t width, int64_t height, int64_t framerate); virtual ~CompositeImpl () {}; @@ -51,7 +52,7 @@ class CompositeImpl : public HubImpl, public virtual Composite virtual void Serialize (JsonSerializer &serializer); private: - + int64_t width, height, framerate; class StaticConstructor { public: From 01d362e8cb19fa98c49b6a15484c87f4bcab3273 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 16 Oct 2024 11:35:51 +0200 Subject: [PATCH 05/13] Fixed wrong variable name assignment --- .../src/gst-plugins/kmscompositemixer.c | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c b/server/module-elements/src/gst-plugins/kmscompositemixer.c index bee993c4e..2ddac5efb 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.c +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.c @@ -40,12 +40,12 @@ GST_DEBUG_CATEGORY_STATIC (kms_composite_mixer_debug_category); #define GST_CAT_DEFAULT kms_composite_mixer_debug_category #define KMS_COMPOSITE_MIXER_GET_PRIVATE(obj) (\ - G_TYPE_INSTANCE_GET_PRIVATE ( \ - (obj), \ - KMS_TYPE_COMPOSITE_MIXER, \ - KmsCompositeMixerPrivate \ - ) \ -) + G_TYPE_INSTANCE_GET_PRIVATE ( \ + (obj), \ + KMS_TYPE_COMPOSITE_MIXER, \ + KmsCompositeMixerPrivate \ + ) \ + ) #define AUDIO_SINK_PAD_PREFIX_COMP "audio_sink_" #define VIDEO_SINK_PAD_PREFIX_COMP "video_sink_" @@ -131,7 +131,7 @@ typedef struct _KmsCompositeMixerData kms_ref_struct_unref (KMS_REF_STRUCT_CAST (data)) static void -kms_destroy_composite_mixer_data (KmsCompositeMixerData * data) +kms_destroy_composite_mixer_data (KmsCompositeMixerData *data) { g_slice_free (KmsCompositeMixerData, data); } @@ -180,7 +180,7 @@ kms_composite_mixer_recalculate_sizes (gpointer data) width = self->priv->output_width / n_columns; height = self->priv->output_height / n_rows; - fps = self->priv->fps; + fps = self->priv->output_framerate; for (l = values; l != NULL; l = l->next) { KmsCompositeMixerData *port_data = l->data; @@ -212,7 +212,7 @@ kms_composite_mixer_recalculate_sizes (gpointer data) } static gboolean -remove_elements_from_pipeline (KmsCompositeMixerData * port_data) +remove_elements_from_pipeline (KmsCompositeMixerData *port_data) { KmsCompositeMixer *self = port_data->mixer; @@ -260,7 +260,7 @@ remove_elements_from_pipeline (KmsCompositeMixerData * port_data) } static GstPadProbeReturn -cb_EOS_received (GstPad * pad, GstPadProbeInfo * info, gpointer data) +cb_EOS_received (GstPad *pad, GstPadProbeInfo *info, gpointer data) { KmsCompositeMixerData *port_data = (KmsCompositeMixerData *) data; KmsCompositeMixer *self = port_data->mixer; @@ -297,7 +297,7 @@ cb_EOS_received (GstPad * pad, GstPadProbeInfo * info, gpointer data) } static GstPadProbeReturn -cb_latency (GstPad * pad, GstPadProbeInfo * info, gpointer data) +cb_latency (GstPad *pad, GstPadProbeInfo *info, gpointer data) { if (GST_QUERY_TYPE (GST_PAD_PROBE_INFO_QUERY (info)) != GST_QUERY_LATENCY) { return GST_PAD_PROBE_OK; @@ -359,6 +359,7 @@ kms_composite_mixer_port_data_destroy (gpointer data) self->priv->n_elems--; kms_composite_mixer_recalculate_sizes (self); } + KMS_COMPOSITE_MIXER_UNLOCK (self); if (!result) { @@ -380,6 +381,7 @@ kms_composite_mixer_port_data_destroy (gpointer data) (GDestroyNotify) kms_ref_struct_unref); } } + gst_element_unlink (port_data->capsfilter, port_data->tee); g_object_unref (pad); } else { @@ -395,6 +397,7 @@ kms_composite_mixer_port_data_destroy (gpointer data) if (port_data->link_probe_id > 0) { gst_pad_remove_probe (port_data->tee_sink_pad, port_data->link_probe_id); } + KMS_COMPOSITE_MIXER_UNLOCK (self); gst_element_unlink (port_data->capsfilter, port_data->tee); @@ -424,8 +427,8 @@ kms_composite_mixer_port_data_destroy (gpointer data) } static GstPadProbeReturn -link_to_videomixer (GstPad * pad, GstPadProbeInfo * info, - KmsCompositeMixerData * data) +link_to_videomixer (GstPad *pad, GstPadProbeInfo *info, + KmsCompositeMixerData *data) { GstPadTemplate *sink_pad_template; KmsCompositeMixer *mixer; @@ -444,8 +447,8 @@ link_to_videomixer (GstPad * pad, GstPadProbeInfo * info, data->latency_probe_id = 0; sink_pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer-> - priv->videomixer), "sink_%u"); + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer->priv-> + videomixer), "sink_%u"); if (G_UNLIKELY (sink_pad_template == NULL)) { GST_ERROR_OBJECT (mixer, "Error taking a new pad from videomixer"); @@ -503,7 +506,7 @@ create_gint (gint value) } static void -kms_composite_mixer_unhandle_port (KmsBaseHub * mixer, gint id) +kms_composite_mixer_unhandle_port (KmsBaseHub *mixer, gint id) { KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer); @@ -520,7 +523,7 @@ kms_composite_mixer_unhandle_port (KmsBaseHub * mixer, gint id) } static KmsCompositeMixerData * -kms_composite_mixer_port_data_create (KmsCompositeMixer * mixer, gint id) +kms_composite_mixer_port_data_create (KmsCompositeMixer *mixer, gint id) { KmsCompositeMixerData *data; GstPad *tee_src; @@ -534,7 +537,6 @@ kms_composite_mixer_port_data_create (KmsCompositeMixer * mixer, gint id) data->removing = FALSE; data->eos_managed = FALSE; - // Link AUDIO input padname = g_strdup_printf (AUDIO_SINK_PAD, data->id); @@ -542,7 +544,6 @@ kms_composite_mixer_port_data_create (KmsCompositeMixer * mixer, gint id) mixer->priv->audiomixer, padname, FALSE); g_free (padname); - // Link VIDEO input data->tee = kms_utils_element_factory_make ("tee", PLUGIN_NAME); @@ -583,48 +584,50 @@ kms_composite_mixer_port_data_create (KmsCompositeMixer * mixer, gint id) "sink"); g_object_unref (tee_src); - data->link_probe_id = gst_pad_add_probe (data->tee_sink_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_BLOCK, (GstPadProbeCallback) link_to_videomixer, KMS_COMPOSITE_MIXER_REF (data), (GDestroyNotify) kms_ref_struct_unref); - // Link DATA input kms_base_hub_link_data_sink (KMS_BASE_HUB (mixer), data->id, mixer->priv->datamixer_sink, "sink_%u", TRUE); - return data; } static gint -get_stream_id_from_padname (const gchar * name) +get_stream_id_from_padname (const gchar *name) { gint64 id; - if (name == NULL) + if (name == NULL) { return -1; + } - if (!g_str_has_prefix (name, AUDIO_SRC_PAD_PREFIX)) + if (!g_str_has_prefix (name, AUDIO_SRC_PAD_PREFIX)) { return -1; + } id = g_ascii_strtoll (name + LENGTH_AUDIO_SRC_PAD_PREFIX, NULL, 10); - if (id > G_MAXINT) + + if (id > G_MAXINT) { return -1; + } return id; } static void -pad_added_cb (GstElement * element, GstPad * pad, gpointer data) +pad_added_cb (GstElement *element, GstPad *pad, gpointer data) { gint id; KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); - if (gst_pad_get_direction (pad) != GST_PAD_SRC) + if (gst_pad_get_direction (pad) != GST_PAD_SRC) { return; + } id = get_stream_id_from_padname (GST_OBJECT_NAME (pad)); @@ -638,14 +641,13 @@ pad_added_cb (GstElement * element, GstPad * pad, gpointer data) } static void -pad_removed_cb (GstElement * element, GstPad * pad, gpointer data) +pad_removed_cb (GstElement *element, GstPad *pad, gpointer data) { GST_DEBUG ("Removed pad %" GST_PTR_FORMAT, pad); } static gint -kms_composite_mixer_handle_port (KmsBaseHub * mixer, - GstElement * mixer_end_point) +kms_composite_mixer_handle_port (KmsBaseHub *mixer, GstElement *mixer_end_point) { KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer); KmsCompositeMixerData *port_data; @@ -699,7 +701,8 @@ kms_composite_mixer_handle_port (KmsBaseHub * mixer, gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, self->priv->output_width, "height", G_TYPE_INT, self->priv->output_height, - "framerate", GST_TYPE_FRACTION, self->priv->output_framerate, 1, NULL); + "framerate", GST_TYPE_FRACTION, self->priv->output_framerate, 1, + NULL); g_object_set (G_OBJECT (capsfilter), "caps", filtercaps, NULL); gst_caps_unref (filtercaps); @@ -723,6 +726,7 @@ kms_composite_mixer_handle_port (KmsBaseHub * mixer, gst_element_sync_state_with_parent (capsfilter); gst_element_sync_state_with_parent (self->priv->videotestsrc); } + gst_element_sync_state_with_parent (self->priv->videomixer); gst_element_sync_state_with_parent (self->priv->mixer_video_agnostic); @@ -772,7 +776,7 @@ kms_composite_mixer_handle_port (KmsBaseHub * mixer, } static void -kms_composite_mixer_dispose (GObject * object) +kms_composite_mixer_dispose (GObject *object) { KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (object); @@ -785,7 +789,7 @@ kms_composite_mixer_dispose (GObject * object) } static void -kms_composite_mixer_finalize (GObject * object) +kms_composite_mixer_finalize (GObject *object) { KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (object); @@ -800,7 +804,7 @@ kms_composite_mixer_finalize (GObject * object) } static void -kms_composite_mixer_class_init (KmsCompositeMixerClass * klass) +kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); KmsBaseHubClass *base_hub_class = KMS_BASE_HUB_CLASS (klass); @@ -832,7 +836,7 @@ kms_composite_mixer_class_init (KmsCompositeMixerClass * klass) } static void -kms_composite_mixer_init (KmsCompositeMixer * self) +kms_composite_mixer_init (KmsCompositeMixer *self) { self->priv = KMS_COMPOSITE_MIXER_GET_PRIVATE (self); @@ -850,7 +854,7 @@ kms_composite_mixer_init (KmsCompositeMixer * self) } gboolean -kms_composite_mixer_plugin_init (GstPlugin * plugin) +kms_composite_mixer_plugin_init (GstPlugin *plugin) { return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, KMS_TYPE_COMPOSITE_MIXER); From a13be91a6a568345c546f76a40d2d30161ed9c42 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 16 Oct 2024 16:22:04 +0200 Subject: [PATCH 06/13] Added properties to Composite Mixer --- .../src/gst-plugins/kmscompositemixer.c | 68 ++++++++++++++++++- .../src/gst-plugins/kmscompositemixer.h | 8 +++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c b/server/module-elements/src/gst-plugins/kmscompositemixer.c index 2ddac5efb..e12478978 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.c +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.c @@ -817,6 +817,21 @@ kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) gobject_class->dispose = GST_DEBUG_FUNCPTR (kms_composite_mixer_dispose); gobject_class->finalize = GST_DEBUG_FUNCPTR (kms_composite_mixer_finalize); + gobject_class->set_property = kms_composite_mixer_set_property; + gobject_class->get_property = kms_composite_mixer_get_property; + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_int64 ("width", "width", + "Width of the screen", + 0, G_MAXINT64, 0, G_PARAM_READABLE | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_int64 ("height", "height", + "Height of the screen", + 0, G_MAXINT64, 0, G_PARAM_READABLE | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_FRAMERATE, + g_param_spec_int64 ("framerate", "framerate", + "Framerate of the screen", + 0, G_MAXINT64, 0, G_PARAM_READABLE | GST_PARAM_MUTABLE_READY)); base_hub_class->handle_port = GST_DEBUG_FUNCPTR (kms_composite_mixer_handle_port); base_hub_class->unhandle_port = @@ -845,9 +860,9 @@ kms_composite_mixer_init (KmsCompositeMixer *self) self->priv->ports = g_hash_table_new_full (g_int_hash, g_int_equal, release_gint, kms_composite_mixer_port_data_destroy); //TODO:Obtain the dimensions of the bigger input stream - self->priv->output_height = 600; - self->priv->output_width = 800; - self->priv->output_framerate = 15; + // self->priv->output_height = 600; + // self->priv->output_width = 800; + // self->priv->output_framerate = 15; self->priv->n_elems = 0; self->priv->loop = kms_loop_new (); @@ -859,3 +874,50 @@ kms_composite_mixer_plugin_init (GstPlugin *plugin) return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, KMS_TYPE_COMPOSITE_MIXER); } + +void +kms_composite_mixer_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); + + switch (property_id) { + case PROP_WIDTH:{ + compositeMixer->priv->width = g_value_get_int (value); + break; + } + case PROP_HEIGHT: + compositeMixer->priv->height = g_value_get_int (value); + break; + case PROP_FRAMERATE: + compositeMixer->priv->framerate = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +kms_composite_mixer_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER(object); + + switch (property_id) { + case PROP_WIDTH: + g_value_set_int64 (value, compositeMixer->priv->width); + break; + case PROP_HEIGHT:{ + g_value_set_int64 (value, compositeMixer->priv->height); + break; + } + case PROP_FRAMERATE:{ + g_value_set_int64 (value, compositeMixer->priv->framerate); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} \ No newline at end of file diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.h b/server/module-elements/src/gst-plugins/kmscompositemixer.h index 05dff2710..a5b4f882d 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.h +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.h @@ -57,6 +57,14 @@ typedef struct _KmsCompositeMixer KmsCompositeMixer; typedef struct _KmsCompositeMixerClass KmsCompositeMixerClass; typedef struct _KmsCompositeMixerPrivate KmsCompositeMixerPrivate; +enum +{ + PROP_WIDTH, + PROP_HEIGHT, + PROP_FRAMERATE, + N_PROPERTIES +}; + struct _KmsCompositeMixer { KmsBaseHub parent; From ce6ecc07982d462c6c23a5528175a4a69ae1fcf4 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 16 Oct 2024 16:32:58 +0200 Subject: [PATCH 07/13] Added properties from Composite.conf.ini --- .../src/server/config/Composite.conf.ini | 4 ++++ .../implementation/objects/CompositeImpl.cpp | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 server/module-elements/src/server/config/Composite.conf.ini diff --git a/server/module-elements/src/server/config/Composite.conf.ini b/server/module-elements/src/server/config/Composite.conf.ini new file mode 100644 index 000000000..a249a2c16 --- /dev/null +++ b/server/module-elements/src/server/config/Composite.conf.ini @@ -0,0 +1,4 @@ +width=800 +height=600 +framerate=15 +; Default resolution and framerate diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp index d96d1fb2d..983dd7437 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp @@ -28,6 +28,10 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); #define FACTORY_NAME "compositemixer" +#define WIDTH_PROPERTY "width" +#define HEIGHT_PROPERTY "height" +#define FRAMERATE_PROPERTY "framerate" + namespace kurento { @@ -37,6 +41,21 @@ CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, std::dynamic_pointer_cast (mediaPipeline), FACTORY_NAME), width (width), height (height), framerate (framerate) ) { + // Width property + if (getConfigValue (&width, + WIDTH_PROPERTY)) { + g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); + } + // Height property + if (getConfigValue (&height, + HEIGHT_PROPERTY)) { + g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); + } + // Framerate property + if (getConfigValue (&framerate, + FRAMERATE_PROPERTY)) { + g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); + } } MediaObjectImpl * From 0927bfccd11105d66707d3855f86745d7e745b7e Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 16 Oct 2024 17:29:12 +0200 Subject: [PATCH 08/13] Fixed multiple issues with properties --- .../src/gst-plugins/kmscompositemixer.c | 101 +++++++++--------- .../implementation/objects/CompositeImpl.cpp | 29 ++--- 2 files changed, 66 insertions(+), 64 deletions(-) diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c b/server/module-elements/src/gst-plugins/kmscompositemixer.c index e12478978..93bd58027 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.c +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.c @@ -162,7 +162,7 @@ kms_composite_mixer_recalculate_sizes (gpointer data) { KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); GstCaps *filtercaps; - gint width, height, top, left, counter, n_columns, n_rows, fps; + gint width, height, top, left, counter, n_columns, n_rows; GList *l; GList *values = g_hash_table_get_values (self->priv->ports); @@ -180,7 +180,7 @@ kms_composite_mixer_recalculate_sizes (gpointer data) width = self->priv->output_width / n_columns; height = self->priv->output_height / n_rows; - fps = self->priv->output_framerate; + //fps = self->priv->output_framerate; for (l = values; l != NULL; l = l->next) { KmsCompositeMixerData *port_data = l->data; @@ -802,7 +802,52 @@ kms_composite_mixer_finalize (GObject *object) G_OBJECT_CLASS (kms_composite_mixer_parent_class)->finalize (object); } +void +kms_composite_mixer_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); + + switch (property_id) { + case PROP_WIDTH:{ + compositeMixer->priv->output_width = g_value_get_int (value); + break; + } + case PROP_HEIGHT: + compositeMixer->priv->output_height = g_value_get_int (value); + break; + case PROP_FRAMERATE: + compositeMixer->priv->output_framerate = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} +void +kms_composite_mixer_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER(object); + + switch (property_id) { + case PROP_WIDTH: + g_value_set_int64 (value, compositeMixer->priv->output_width); + break; + case PROP_HEIGHT:{ + g_value_set_int64 (value, compositeMixer->priv->output_height); + break; + } + case PROP_FRAMERATE:{ + g_value_set_int64 (value, compositeMixer->priv->output_framerate); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} static void kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) { @@ -860,9 +905,9 @@ kms_composite_mixer_init (KmsCompositeMixer *self) self->priv->ports = g_hash_table_new_full (g_int_hash, g_int_equal, release_gint, kms_composite_mixer_port_data_destroy); //TODO:Obtain the dimensions of the bigger input stream - // self->priv->output_height = 600; - // self->priv->output_width = 800; - // self->priv->output_framerate = 15; + self->priv->output_height = 600; + self->priv->output_width = 800; + self->priv->output_framerate = 15; self->priv->n_elems = 0; self->priv->loop = kms_loop_new (); @@ -875,49 +920,3 @@ kms_composite_mixer_plugin_init (GstPlugin *plugin) KMS_TYPE_COMPOSITE_MIXER); } -void -kms_composite_mixer_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); - - switch (property_id) { - case PROP_WIDTH:{ - compositeMixer->priv->width = g_value_get_int (value); - break; - } - case PROP_HEIGHT: - compositeMixer->priv->height = g_value_get_int (value); - break; - case PROP_FRAMERATE: - compositeMixer->priv->framerate = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -void -kms_composite_mixer_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER(object); - - switch (property_id) { - case PROP_WIDTH: - g_value_set_int64 (value, compositeMixer->priv->width); - break; - case PROP_HEIGHT:{ - g_value_set_int64 (value, compositeMixer->priv->height); - break; - } - case PROP_FRAMERATE:{ - g_value_set_int64 (value, compositeMixer->priv->framerate); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} \ No newline at end of file diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp index 983dd7437..09e5dfc72 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp @@ -39,23 +39,26 @@ CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, std::shared_ptr mediaPipeline, int64_t width, int64_t height, int64_t framerate) : HubImpl (conf, std::dynamic_pointer_cast (mediaPipeline), FACTORY_NAME), - width (width), height (height), framerate (framerate) ) + width (width), height (height), framerate (framerate) { - // Width property - if (getConfigValue (&width, - WIDTH_PROPERTY)) { + // // Width property + // if (getConfigValue (width, + // WIDTH_PROPERTY, NULL)) { + // g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); + // } + // // Height property + // if (getConfigValue (height, + // HEIGHT_PROPERTY, NULL)) { + // g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); + // } + // // Framerate property + // if (getConfigValue (framerate, + // FRAMERATE_PROPERTY, NULL)) { + // g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); + // } g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); - } - // Height property - if (getConfigValue (&height, - HEIGHT_PROPERTY)) { g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); - } - // Framerate property - if (getConfigValue (&framerate, - FRAMERATE_PROPERTY)) { g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); - } } MediaObjectImpl * From 2d825d2a10ad8870aaca380d68fd7b01a6715316 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Mon, 21 Oct 2024 09:39:13 +0200 Subject: [PATCH 09/13] Added default parameters and fixed configuration parameter overlap in Composite constructor --- .../implementation/objects/CompositeImpl.cpp | 34 ++++++++----------- .../implementation/objects/CompositeImpl.hpp | 6 +++- .../interface/elements.Composite.kmd.json | 13 +++++-- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp index 09e5dfc72..060d9e0ef 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp @@ -41,30 +41,26 @@ CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, std::dynamic_pointer_cast (mediaPipeline), FACTORY_NAME), width (width), height (height), framerate (framerate) { - // // Width property - // if (getConfigValue (width, - // WIDTH_PROPERTY, NULL)) { - // g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); - // } - // // Height property - // if (getConfigValue (height, - // HEIGHT_PROPERTY, NULL)) { - // g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); - // } - // // Framerate property - // if (getConfigValue (framerate, - // FRAMERATE_PROPERTY, NULL)) { - // g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); - // } - g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); - g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); - g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); + // Check if "width" exists in the config + if (width != 0 || kurento::MediaObjectImpl::getConfigValue(&width, "width", conf)) { + g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); + } + + // Check if "height" exists in the config + if (height != 0 || kurento::MediaObjectImpl::getConfigValue(&height, "height", conf)) { + g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); + } + + // Check if "framerate" exists in the config + if (framerate != 0 || kurento::MediaObjectImpl::getConfigValue(&framerate, "framerate", conf)) { + g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); + } } MediaObjectImpl * CompositeImplFactory::createObject (const boost::property_tree::ptree &conf, std::shared_ptr mediaPipeline, - int64_t width, int64_t height, int64_t framerate) const + int64_t width = DEFAULT_WIDTH, int64_t height = DEFAULT_HEIGHT, int64_t framerate = DEFAULT_FRAMERATE) const { return new CompositeImpl (conf, mediaPipeline, width, height, framerate); } diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp index 11941c0b7..fb3546855 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp @@ -27,6 +27,10 @@ namespace kurento class MediaPipeline; class CompositeImpl; +const int64_t DEFAULT_WIDTH = 800; +const int64_t DEFAULT_HEIGHT = 600; +const int64_t DEFAULT_FRAMERATE = 15; + void Serialize (std::shared_ptr &object, JsonSerializer &serializer); @@ -37,7 +41,7 @@ class CompositeImpl : public HubImpl, public virtual Composite CompositeImpl (const boost::property_tree::ptree &conf, std::shared_ptr mediaPipeline, - int64_t width, int64_t height, int64_t framerate); + int64_t width = DEFAULT_WIDTH, int64_t height = DEFAULT_HEIGHT, int64_t framerate = DEFAULT_FRAMERATE); virtual ~CompositeImpl () {}; diff --git a/server/module-elements/src/server/interface/elements.Composite.kmd.json b/server/module-elements/src/server/interface/elements.Composite.kmd.json index 72961ba37..c73398fc7 100644 --- a/server/module-elements/src/server/interface/elements.Composite.kmd.json +++ b/server/module-elements/src/server/interface/elements.Composite.kmd.json @@ -16,17 +16,24 @@ { "name": "width", "doc": "screen width", - "type": "int64" + "type": "int64", + "optional": true, + "defaultValue": 800 }, { "name": "height", "doc": "screen height", - "type": "int64" + "type": "int64", + "optional": true, + "defaultValue": 600 + }, { "name": "framerate", "doc": "frames per second", - "type": "int64" + "type": "int64", + "optional": true, + "defaultValue": 15 } ] } From 8bda2236d20cc7fe188bac097f1b30dd2565e0c3 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Mon, 28 Oct 2024 11:25:54 +0100 Subject: [PATCH 10/13] Added parameter Test to composite.cpp --- .../tests/server/composite.cpp | 90 ++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/server/module-elements/tests/server/composite.cpp b/server/module-elements/tests/server/composite.cpp index e9f680e7a..9bff1a026 100644 --- a/server/module-elements/tests/server/composite.cpp +++ b/server/module-elements/tests/server/composite.cpp @@ -84,7 +84,23 @@ createComposite () return std::dynamic_pointer_cast (composite); } +static std::shared_ptr +createComposite (int64_t width, int64_t height, int64_t framerate) +{ + std::shared_ptr composite; + Json::Value constructorParams; + + constructorParams ["mediaPipeline"] = mediaPipelineId; + constructorParams ["width"] = width; + constructorParams ["height"] = height; + constructorParams ["framerate"] = framerate; + composite = moduleManager.getFactory ("Composite")->createObject ( + config, "", + constructorParams ); + + return std::dynamic_pointer_cast (composite); +} static void releaseComposite (std::shared_ptr &ep) { @@ -198,6 +214,7 @@ releasePassTrhough (std::shared_ptr &ep) static void composite_setup () + { std::atomic media_state_changed (false); std::condition_variable cv; @@ -269,13 +286,82 @@ composite_setup () releaseTestSrc(src2); } +static void composite_param_setup (){ +std::atomic media_state_changed (false); + std::condition_variable cv; + std::mutex mtx; + std::unique_lock lck (mtx); + std::shared_ptr composite = createComposite (800, 600, 15); + std::shared_ptr src1 = createTestSrc(); + std::shared_ptr src2 = createTestSrc(); + std::shared_ptr pt = createPassThrough(mediaPipelineId); + std::shared_ptr port1 = createHubPort (composite); + std::shared_ptr port2 = createHubPort (composite); + bool audio_flowing = false; + bool video_flowing = false; + + sigc::connection conn = getMediaElement(pt)->signalMediaFlowInStateChanged.connect([&] ( + MediaFlowInStateChanged event) { + std::shared_ptr state = event.getState(); + if (state->getValue() == MediaFlowState::FLOWING) { + BOOST_CHECK (state->getValue() == MediaFlowState::FLOWING); + if (event.getMediaType ()->getValue() == MediaType::AUDIO) { + BOOST_TEST_MESSAGE ("Audio flowing"); + audio_flowing = true; + } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { + BOOST_TEST_MESSAGE ("Video flowing"); + video_flowing = true; + } + } else if (state->getValue() == MediaFlowState::NOT_FLOWING) { + if (event.getMediaType ()->getValue() == MediaType::AUDIO) { + BOOST_TEST_MESSAGE ("Audio not flowing"); + audio_flowing = false; + } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { + BOOST_TEST_MESSAGE ("Video not flowing"); + video_flowing = false; + } + } + if (audio_flowing && video_flowing) { + media_state_changed = true; + cv.notify_one(); + } + } + ); + + src1->connect (port1); + src2->connect (port2); + port1->connect (pt); + + + dumpPipeline (mediaPipelineId, "composite_start.dot"); + // First stream + cv.wait_for (lck, std::chrono::seconds(10), [&] () { + return media_state_changed.load(); + }); + conn.disconnect (); + + dumpPipeline (mediaPipelineId, "composite_end.dot"); + + if (!((getMediaElement(pt)->isMediaFlowingIn (std::make_shared(MediaType::AUDIO))) && ((getMediaElement(pt)->isMediaFlowingIn (std::make_shared(MediaType::VIDEO)))))) { + BOOST_ERROR ("Media is not flowing out from composite"); + } + + + + releasePassTrhough(pt); + releaseHubPort(port1); + releaseHubPort(port2); + releaseComposite (composite); + releaseTestSrc(src1); + releaseTestSrc(src2); +} test_suite * init_unit_test_suite ( int , char *[] ) { test_suite *test = BOOST_TEST_SUITE ( "RecorderEndpoint" ); test->add (BOOST_TEST_CASE ( &composite_setup), 0, /* timeout */ 100); - + test->add (BOOST_TEST_CASE ( &composite_param_setup), 0, /* timeout */ 100); return test; -} +} \ No newline at end of file From d5ff580b6b39daa0a49d0b3e0542f794a52f5882 Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 30 Oct 2024 10:29:30 +0100 Subject: [PATCH 11/13] Added Prop Zero to CompositeMixer enum --- server/module-elements/src/gst-plugins/kmscompositemixer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.h b/server/module-elements/src/gst-plugins/kmscompositemixer.h index a5b4f882d..e302bafbe 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.h +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.h @@ -59,6 +59,7 @@ typedef struct _KmsCompositeMixerPrivate KmsCompositeMixerPrivate; enum { + PROP_ZERO, PROP_WIDTH, PROP_HEIGHT, PROP_FRAMERATE, From 5e5f75bbd79e719e2dabee7ccb03557ec34e971b Mon Sep 17 00:00:00 2001 From: ErikNae Date: Wed, 30 Oct 2024 12:39:44 +0000 Subject: [PATCH 12/13] Fixed type error from int64 to int --- .../src/gst-plugins/kmscompositemixer.c | 40 +- .../src/gst-plugins/kmscompositemixer.c~ | 921 ++++++++++++++++++ .../src/server/config/Composite.conf.ini | 6 +- .../implementation/objects/CompositeImpl.cpp | 57 +- .../objects/CompositeImpl.cpp.orig | 90 ++ .../implementation/objects/CompositeImpl.hpp | 11 +- .../objects/CompositeImpl.hpp.orig | 72 ++ .../interface/elements.Composite.kmd.json | 6 +- .../tests/server/composite.cpp | 204 ++-- 9 files changed, 1264 insertions(+), 143 deletions(-) create mode 100644 server/module-elements/src/gst-plugins/kmscompositemixer.c~ create mode 100644 server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig create mode 100644 server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c b/server/module-elements/src/gst-plugins/kmscompositemixer.c index 93bd58027..ee1067057 100644 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.c +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.c @@ -180,7 +180,6 @@ kms_composite_mixer_recalculate_sizes (gpointer data) width = self->priv->output_width / n_columns; height = self->priv->output_height / n_rows; - //fps = self->priv->output_framerate; for (l = values; l != NULL; l = l->next) { KmsCompositeMixerData *port_data = l->data; @@ -447,8 +446,8 @@ link_to_videomixer (GstPad *pad, GstPadProbeInfo *info, data->latency_probe_id = 0; sink_pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer->priv-> - videomixer), "sink_%u"); + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer-> + priv->videomixer), "sink_%u"); if (G_UNLIKELY (sink_pad_template == NULL)) { GST_ERROR_OBJECT (mixer, "Error taking a new pad from videomixer"); @@ -566,7 +565,7 @@ kms_composite_mixer_port_data_create (KmsCompositeMixer *mixer, gint id) gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, mixer->priv->output_width, "height", G_TYPE_INT, mixer->priv->output_height, - "framerate", GST_TYPE_FRACTION, mixer->priv->output_framerate, + "framerate", GST_TYPE_FRACTION, mixer->priv->output_framerate, 1, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); g_object_set (data->capsfilter, "caps", filtercaps, NULL); gst_caps_unref (filtercaps); @@ -802,9 +801,10 @@ kms_composite_mixer_finalize (GObject *object) G_OBJECT_CLASS (kms_composite_mixer_parent_class)->finalize (object); } + void -kms_composite_mixer_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) +kms_composite_mixer_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) { KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); @@ -826,21 +826,21 @@ kms_composite_mixer_set_property (GObject * object, guint property_id, } void -kms_composite_mixer_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) +kms_composite_mixer_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) { - KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER(object); + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); switch (property_id) { case PROP_WIDTH: - g_value_set_int64 (value, compositeMixer->priv->output_width); + g_value_set_int (value, compositeMixer->priv->output_width); break; case PROP_HEIGHT:{ - g_value_set_int64 (value, compositeMixer->priv->output_height); + g_value_set_int (value, compositeMixer->priv->output_height); break; } case PROP_FRAMERATE:{ - g_value_set_int64 (value, compositeMixer->priv->output_framerate); + g_value_set_int (value, compositeMixer->priv->output_framerate); break; } default: @@ -848,6 +848,7 @@ kms_composite_mixer_get_property (GObject * object, guint property_id, break; } } + static void kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) { @@ -866,17 +867,17 @@ kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) gobject_class->get_property = kms_composite_mixer_get_property; g_object_class_install_property (gobject_class, PROP_WIDTH, - g_param_spec_int64 ("width", "width", + g_param_spec_int ("width", "width", "Width of the screen", - 0, G_MAXINT64, 0, G_PARAM_READABLE | GST_PARAM_MUTABLE_READY)); + 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); g_object_class_install_property (gobject_class, PROP_HEIGHT, - g_param_spec_int64 ("height", "height", + g_param_spec_int ("height", "height", "Height of the screen", - 0, G_MAXINT64, 0, G_PARAM_READABLE | GST_PARAM_MUTABLE_READY)); - g_object_class_install_property (gobject_class, PROP_FRAMERATE, - g_param_spec_int64 ("framerate", "framerate", + 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_FRAMERATE, + g_param_spec_int ("framerate", "framerate", "Framerate of the screen", - 0, G_MAXINT64, 0, G_PARAM_READABLE | GST_PARAM_MUTABLE_READY)); + 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); base_hub_class->handle_port = GST_DEBUG_FUNCPTR (kms_composite_mixer_handle_port); base_hub_class->unhandle_port = @@ -919,4 +920,3 @@ kms_composite_mixer_plugin_init (GstPlugin *plugin) return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, KMS_TYPE_COMPOSITE_MIXER); } - diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c~ b/server/module-elements/src/gst-plugins/kmscompositemixer.c~ new file mode 100644 index 000000000..6a7cb2775 --- /dev/null +++ b/server/module-elements/src/gst-plugins/kmscompositemixer.c~ @@ -0,0 +1,921 @@ +/* + * (C) Copyright 2013 Kurento (http://kurento.org/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "kmscompositemixer.h" +#include +#include +#include +#include +#include +#include + +#define LATENCY 600 //ms + +#define PLUGIN_NAME "compositemixer" + +#define KMS_COMPOSITE_MIXER_LOCK(mixer) \ + (g_rec_mutex_lock (&( (KmsCompositeMixer *) (mixer))->priv->mutex)) + +#define KMS_COMPOSITE_MIXER_UNLOCK(mixer) \ + (g_rec_mutex_unlock (&( (KmsCompositeMixer *) (mixer))->priv->mutex)) + +GST_DEBUG_CATEGORY_STATIC (kms_composite_mixer_debug_category); +#define GST_CAT_DEFAULT kms_composite_mixer_debug_category + +#define KMS_COMPOSITE_MIXER_GET_PRIVATE(obj) (\ + G_TYPE_INSTANCE_GET_PRIVATE ( \ + (obj), \ + KMS_TYPE_COMPOSITE_MIXER, \ + KmsCompositeMixerPrivate \ + ) \ + ) + +#define AUDIO_SINK_PAD_PREFIX_COMP "audio_sink_" +#define VIDEO_SINK_PAD_PREFIX_COMP "video_sink_" +#define AUDIO_SRC_PAD_PREFIX_COMP "audio_src_" +#define VIDEO_SRC_PAD_PREFIX_COMP "video_src_" +#define AUDIO_SINK_PAD_NAME_COMP AUDIO_SINK_PAD_PREFIX_COMP "%u" +#define VIDEO_SINK_PAD_NAME_COMP VIDEO_SINK_PAD_PREFIX_COMP "%u" +#define AUDIO_SRC_PAD_NAME_COMP AUDIO_SRC_PAD_PREFIX_COMP "%u" +#define VIDEO_SRC_PAD_NAME_COMP VIDEO_SRC_PAD_PREFIX_COMP "%u" + +static GstStaticPadTemplate audio_sink_factory = +GST_STATIC_PAD_TEMPLATE (AUDIO_SINK_PAD_NAME_COMP, + GST_PAD_SINK, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_AUDIO_CAPS) + ); + +static GstStaticPadTemplate video_sink_factory = +GST_STATIC_PAD_TEMPLATE (VIDEO_SINK_PAD_NAME_COMP, + GST_PAD_SINK, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_VIDEO_CAPS) + ); + +static GstStaticPadTemplate audio_src_factory = +GST_STATIC_PAD_TEMPLATE (AUDIO_SRC_PAD_NAME_COMP, + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_AUDIO_CAPS) + ); + +static GstStaticPadTemplate video_src_factory = +GST_STATIC_PAD_TEMPLATE (VIDEO_SRC_PAD_NAME_COMP, + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_VIDEO_CAPS) + ); + +struct _KmsCompositeMixerPrivate +{ + GstElement *videomixer; + GstElement *audiomixer; + GstElement *datamixer_sink; + GstElement *datamixer_src; + GstElement *videotestsrc; + GHashTable *ports; + GstElement *mixer_audio_agnostic; + GstElement *mixer_video_agnostic; + KmsLoop *loop; + GRecMutex mutex; + gint n_elems; + gint output_width, output_height, output_framerate; +}; + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (KmsCompositeMixer, kms_composite_mixer, + KMS_TYPE_BASE_HUB, + GST_DEBUG_CATEGORY_INIT (kms_composite_mixer_debug_category, PLUGIN_NAME, + 0, "debug category for compositemixer element")); + +typedef struct _KmsCompositeMixerData +{ + KmsRefStruct parent; + gint id; + KmsCompositeMixer *mixer; + GstElement *capsfilter; + GstElement *tee; + GstElement *fakesink; + gboolean input; + gboolean removing; + gboolean eos_managed; + gulong probe_id; + gulong link_probe_id; + gulong latency_probe_id; + GstPad *video_mixer_pad; + GstPad *tee_sink_pad; +} KmsCompositeMixerData; + +#define KMS_COMPOSITE_MIXER_REF(data) \ + kms_ref_struct_ref (KMS_REF_STRUCT_CAST (data)) +#define KMS_COMPOSITE_MIXER_UNREF(data) \ + kms_ref_struct_unref (KMS_REF_STRUCT_CAST (data)) + +static void +kms_destroy_composite_mixer_data (KmsCompositeMixerData *data) +{ + g_slice_free (KmsCompositeMixerData, data); +} + +static KmsCompositeMixerData * +kms_create_composite_mixer_data () +{ + KmsCompositeMixerData *data; + + data = g_slice_new0 (KmsCompositeMixerData); + kms_ref_struct_init (KMS_REF_STRUCT_CAST (data), + (GDestroyNotify) kms_destroy_composite_mixer_data); + + return data; +} + +static gint +compare_port_data (gconstpointer a, gconstpointer b) +{ + KmsCompositeMixerData *port_data_a = (KmsCompositeMixerData *) a; + KmsCompositeMixerData *port_data_b = (KmsCompositeMixerData *) b; + + return port_data_a->id - port_data_b->id; +} + +static void +kms_composite_mixer_recalculate_sizes (gpointer data) +{ + KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); + GstCaps *filtercaps; + gint width, height, top, left, counter, n_columns, n_rows; + GList *l; + GList *values = g_hash_table_get_values (self->priv->ports); + + if (self->priv->n_elems <= 0) { + return; + } + + counter = 0; + values = g_list_sort (values, compare_port_data); + + n_columns = (gint) ceil (sqrt (self->priv->n_elems)); + n_rows = (gint) ceil ((float) self->priv->n_elems / (float) n_columns); + + GST_DEBUG_OBJECT (self, "columns %d rows %d", n_columns, n_rows); + + width = self->priv->output_width / n_columns; + height = self->priv->output_height / n_rows; + + for (l = values; l != NULL; l = l->next) { + KmsCompositeMixerData *port_data = l->data; + + if (port_data->input == FALSE) { + continue; + } + + filtercaps = + gst_caps_new_simple ("video/x-raw", + "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); + g_object_set (port_data->capsfilter, "caps", filtercaps, NULL); + gst_caps_unref (filtercaps); + + top = ((counter / n_columns) * height); + left = ((counter % n_columns) * width); + + g_object_set (port_data->video_mixer_pad, "xpos", left, "ypos", top, + "alpha", 1.0, NULL); + counter++; + + GST_DEBUG_OBJECT (self, "counter %d id_port %d ", counter, port_data->id); + GST_DEBUG_OBJECT (self, "top %d left %d width %d height %d", top, left, + width, height); + } + + g_list_free (values); +} + +static gboolean +remove_elements_from_pipeline (KmsCompositeMixerData *port_data) +{ + KmsCompositeMixer *self = port_data->mixer; + + KMS_COMPOSITE_MIXER_LOCK (self); + + gst_element_unlink (port_data->capsfilter, self->priv->videomixer); + + if (port_data->latency_probe_id > 0) { + gst_pad_remove_probe (port_data->video_mixer_pad, + port_data->latency_probe_id); + port_data->latency_probe_id = 0; + } + + if (port_data->video_mixer_pad != NULL) { + gst_element_release_request_pad (self->priv->videomixer, + port_data->video_mixer_pad); + g_object_unref (port_data->video_mixer_pad); + port_data->video_mixer_pad = NULL; + } + + gst_bin_remove_many (GST_BIN (self), + g_object_ref (port_data->capsfilter), + g_object_ref (port_data->tee), g_object_ref (port_data->fakesink), NULL); + + kms_base_hub_unlink_video_src (KMS_BASE_HUB (self), port_data->id); + kms_base_hub_unlink_data_src (KMS_BASE_HUB (self), port_data->id); + + KMS_COMPOSITE_MIXER_UNLOCK (self); + + gst_element_set_state (port_data->capsfilter, GST_STATE_NULL); + gst_element_set_state (port_data->tee, GST_STATE_NULL); + gst_element_set_state (port_data->fakesink, GST_STATE_NULL); + + g_object_unref (port_data->capsfilter); + g_object_unref (port_data->tee); + g_object_unref (port_data->fakesink); + g_object_unref (port_data->tee_sink_pad); + + port_data->tee_sink_pad = NULL; + port_data->capsfilter = NULL; + port_data->tee = NULL; + port_data->fakesink = NULL; + + return G_SOURCE_REMOVE; +} + +static GstPadProbeReturn +cb_EOS_received (GstPad *pad, GstPadProbeInfo *info, gpointer data) +{ + KmsCompositeMixerData *port_data = (KmsCompositeMixerData *) data; + KmsCompositeMixer *self = port_data->mixer; + GstEvent *event; + + if (GST_EVENT_TYPE (gst_pad_probe_info_get_event (info)) != GST_EVENT_EOS) { + return GST_PAD_PROBE_OK; + } + + KMS_COMPOSITE_MIXER_LOCK (self); + + if (!port_data->removing) { + port_data->eos_managed = TRUE; + KMS_COMPOSITE_MIXER_UNLOCK (self); + return GST_PAD_PROBE_OK; + } + + if (port_data->probe_id > 0) { + gst_pad_remove_probe (pad, port_data->probe_id); + port_data->probe_id = 0; + } + + KMS_COMPOSITE_MIXER_UNLOCK (self); + + event = gst_event_new_eos (); + gst_pad_send_event (pad, event); + + kms_loop_idle_add_full (self->priv->loop, G_PRIORITY_DEFAULT, + (GSourceFunc) remove_elements_from_pipeline, + KMS_COMPOSITE_MIXER_REF (port_data), + (GDestroyNotify) kms_ref_struct_unref); + + return GST_PAD_PROBE_OK; +} + +static GstPadProbeReturn +cb_latency (GstPad *pad, GstPadProbeInfo *info, gpointer data) +{ + if (GST_QUERY_TYPE (GST_PAD_PROBE_INFO_QUERY (info)) != GST_QUERY_LATENCY) { + return GST_PAD_PROBE_OK; + } + + GST_LOG_OBJECT (pad, "Modifing latency query. New latency %" G_GUINT64_FORMAT, + (guint64) (LATENCY * GST_MSECOND)); + + gst_query_set_latency (GST_PAD_PROBE_INFO_QUERY (info), + TRUE, 0, LATENCY * GST_MSECOND); + + return GST_PAD_PROBE_HANDLED; +} + +static void +kms_composite_mixer_port_data_destroy (gpointer data) +{ + KmsCompositeMixerData *port_data = (KmsCompositeMixerData *) data; + KmsCompositeMixer *self = port_data->mixer; + GstPad *audiosink; + gchar *padname; + + KMS_COMPOSITE_MIXER_LOCK (self); + + port_data->removing = TRUE; + + kms_base_hub_unlink_video_sink (KMS_BASE_HUB (self), port_data->id); + kms_base_hub_unlink_audio_sink (KMS_BASE_HUB (self), port_data->id); + kms_base_hub_unlink_data_sink (KMS_BASE_HUB (self), port_data->id); + + if (port_data->input) { + GstEvent *event; + gboolean result; + GstPad *pad; + + if (port_data->capsfilter == NULL) { + KMS_COMPOSITE_MIXER_UNLOCK (self); + return; + } + + pad = gst_element_get_static_pad (port_data->capsfilter, "sink"); + + if (pad == NULL) { + KMS_COMPOSITE_MIXER_UNLOCK (self); + return; + } + + if (!GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_EOS)) { + + if (GST_PAD_IS_FLUSHING (pad)) { + gst_pad_send_event (pad, gst_event_new_flush_stop (FALSE)); + } + + event = gst_event_new_eos (); + result = gst_pad_send_event (pad, event); + + if (port_data->input && self->priv->n_elems > 0) { + port_data->input = FALSE; + self->priv->n_elems--; + kms_composite_mixer_recalculate_sizes (self); + } + + KMS_COMPOSITE_MIXER_UNLOCK (self); + + if (!result) { + GST_WARNING ("EOS event did not send"); + } + } else { + gboolean remove = FALSE; + + /* EOS callback was triggered before we could remove the port data */ + /* so we have to remove elements to avoid memory leaks. */ + remove = port_data->eos_managed; + KMS_COMPOSITE_MIXER_UNLOCK (self); + + if (remove) { + /* Remove pipeline without helding the mutex */ + kms_loop_idle_add_full (self->priv->loop, G_PRIORITY_DEFAULT, + (GSourceFunc) remove_elements_from_pipeline, + KMS_COMPOSITE_MIXER_REF (port_data), + (GDestroyNotify) kms_ref_struct_unref); + } + } + + gst_element_unlink (port_data->capsfilter, port_data->tee); + g_object_unref (pad); + } else { + if (port_data->probe_id > 0) { + gst_pad_remove_probe (port_data->video_mixer_pad, port_data->probe_id); + } + + if (port_data->latency_probe_id > 0) { + gst_pad_remove_probe (port_data->video_mixer_pad, + port_data->latency_probe_id); + } + + if (port_data->link_probe_id > 0) { + gst_pad_remove_probe (port_data->tee_sink_pad, port_data->link_probe_id); + } + + KMS_COMPOSITE_MIXER_UNLOCK (self); + + gst_element_unlink (port_data->capsfilter, port_data->tee); + gst_element_unlink (port_data->tee, port_data->fakesink); + + gst_bin_remove (GST_BIN (self), g_object_ref (port_data->capsfilter)); + gst_element_set_state (port_data->capsfilter, GST_STATE_NULL); + g_object_unref (port_data->capsfilter); + port_data->capsfilter = NULL; + + gst_bin_remove (GST_BIN (self), g_object_ref (port_data->tee)); + gst_element_set_state (port_data->tee, GST_STATE_NULL); + g_object_unref (port_data->tee); + port_data->tee = NULL; + + gst_bin_remove (GST_BIN (self), g_object_ref (port_data->fakesink)); + gst_element_set_state (port_data->fakesink, GST_STATE_NULL); + g_object_unref (port_data->fakesink); + port_data->fakesink = NULL; + } + + padname = g_strdup_printf (AUDIO_SINK_PAD, port_data->id); + audiosink = gst_element_get_static_pad (self->priv->audiomixer, padname); + gst_element_release_request_pad (self->priv->audiomixer, audiosink); + gst_object_unref (audiosink); + g_free (padname); +} + +static GstPadProbeReturn +link_to_videomixer (GstPad *pad, GstPadProbeInfo *info, + KmsCompositeMixerData *data) +{ + GstPadTemplate *sink_pad_template; + KmsCompositeMixer *mixer; + GstPad *tee_src; + + if (GST_EVENT_TYPE (gst_pad_probe_info_get_event (info)) != + GST_EVENT_STREAM_START) { + return GST_PAD_PROBE_PASS; + } + + mixer = KMS_COMPOSITE_MIXER (data->mixer); + GST_DEBUG ("stream start detected %d", data->id); + KMS_COMPOSITE_MIXER_LOCK (mixer); + + data->link_probe_id = 0; + data->latency_probe_id = 0; + + sink_pad_template = + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer->priv-> + videomixer), "sink_%u"); + + if (G_UNLIKELY (sink_pad_template == NULL)) { + GST_ERROR_OBJECT (mixer, "Error taking a new pad from videomixer"); + KMS_COMPOSITE_MIXER_UNLOCK (mixer); + return GST_PAD_PROBE_DROP; + } + + data->input = TRUE; + + /*link tee -> videomixer */ + data->video_mixer_pad = + gst_element_request_pad (mixer->priv->videomixer, + sink_pad_template, NULL, NULL); + + tee_src = gst_element_request_pad_simple (data->tee, "src_%u"); + + gst_element_link_pads (data->tee, GST_OBJECT_NAME (tee_src), + mixer->priv->videomixer, GST_OBJECT_NAME (data->video_mixer_pad)); + g_object_unref (tee_src); + + data->probe_id = gst_pad_add_probe (data->video_mixer_pad, + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + (GstPadProbeCallback) cb_EOS_received, + KMS_COMPOSITE_MIXER_REF (data), (GDestroyNotify) kms_ref_struct_unref); + + data->latency_probe_id = gst_pad_add_probe (data->video_mixer_pad, + GST_PAD_PROBE_TYPE_QUERY_UPSTREAM, + (GstPadProbeCallback) cb_latency, NULL, NULL); + + /*recalculate the output sizes */ + mixer->priv->n_elems++; + kms_composite_mixer_recalculate_sizes (mixer); + + //Recalculate latency to avoid video freezes when an element stops to send media. + gst_bin_recalculate_latency (GST_BIN (mixer)); + + KMS_COMPOSITE_MIXER_UNLOCK (mixer); + + return GST_PAD_PROBE_REMOVE; +} + +static void +release_gint (gpointer data) +{ + g_slice_free (gint, data); +} + +static gint * +create_gint (gint value) +{ + gint *p = g_slice_new (gint); + + *p = value; + return p; +} + +static void +kms_composite_mixer_unhandle_port (KmsBaseHub *mixer, gint id) +{ + KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer); + + GST_DEBUG ("unhandle id %d", id); + + KMS_COMPOSITE_MIXER_LOCK (self); + + g_hash_table_remove (self->priv->ports, &id); + + KMS_COMPOSITE_MIXER_UNLOCK (self); + + KMS_BASE_HUB_CLASS (G_OBJECT_CLASS + (kms_composite_mixer_parent_class))->unhandle_port (mixer, id); +} + +static KmsCompositeMixerData * +kms_composite_mixer_port_data_create (KmsCompositeMixer *mixer, gint id) +{ + KmsCompositeMixerData *data; + GstPad *tee_src; + GstCaps *filtercaps; + gchar *padname; + + data = kms_create_composite_mixer_data (); + data->mixer = mixer; + data->id = id; + data->input = FALSE; + data->removing = FALSE; + data->eos_managed = FALSE; + + // Link AUDIO input + + padname = g_strdup_printf (AUDIO_SINK_PAD, data->id); + kms_base_hub_link_audio_sink (KMS_BASE_HUB (mixer), data->id, + mixer->priv->audiomixer, padname, FALSE); + g_free (padname); + + // Link VIDEO input + + data->tee = kms_utils_element_factory_make ("tee", PLUGIN_NAME); + data->fakesink = kms_utils_element_factory_make ("fakesink", PLUGIN_NAME); + data->capsfilter = kms_utils_element_factory_make ("capsfilter", PLUGIN_NAME); + + g_object_set (G_OBJECT (data->capsfilter), "caps-change-mode", + 1 /*delayed */ , NULL); + + g_object_set (G_OBJECT (data->fakesink), "async", FALSE, "sync", FALSE, NULL); + + gst_bin_add_many (GST_BIN (mixer), data->capsfilter, data->tee, + data->fakesink, NULL); + + gst_element_sync_state_with_parent (data->capsfilter); + gst_element_sync_state_with_parent (data->tee); + gst_element_sync_state_with_parent (data->fakesink); + + filtercaps = + gst_caps_new_simple ("video/x-raw", + "width", G_TYPE_INT, mixer->priv->output_width, + "height", G_TYPE_INT, mixer->priv->output_height, + "framerate", GST_TYPE_FRACTION, mixer->priv->output_framerate, 1, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); + g_object_set (data->capsfilter, "caps", filtercaps, NULL); + gst_caps_unref (filtercaps); + + /*link basemixer -> video_agnostic */ + kms_base_hub_link_video_sink (KMS_BASE_HUB (mixer), data->id, + data->capsfilter, "sink", FALSE); + + data->tee_sink_pad = gst_element_get_static_pad (data->tee, "sink"); + gst_element_link_pads (data->capsfilter, NULL, data->tee, + GST_OBJECT_NAME (data->tee_sink_pad)); + + tee_src = gst_element_request_pad_simple (data->tee, "src_%u"); + gst_element_link_pads (data->tee, GST_OBJECT_NAME (tee_src), data->fakesink, + "sink"); + g_object_unref (tee_src); + + data->link_probe_id = gst_pad_add_probe (data->tee_sink_pad, + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_BLOCK, + (GstPadProbeCallback) link_to_videomixer, + KMS_COMPOSITE_MIXER_REF (data), (GDestroyNotify) kms_ref_struct_unref); + + // Link DATA input + + kms_base_hub_link_data_sink (KMS_BASE_HUB (mixer), data->id, + mixer->priv->datamixer_sink, "sink_%u", TRUE); + + return data; +} + +static gint +get_stream_id_from_padname (const gchar *name) +{ + gint64 id; + + if (name == NULL) { + return -1; + } + + if (!g_str_has_prefix (name, AUDIO_SRC_PAD_PREFIX)) { + return -1; + } + + id = g_ascii_strtoll (name + LENGTH_AUDIO_SRC_PAD_PREFIX, NULL, 10); + + if (id > G_MAXINT) { + return -1; + } + + return id; +} + +static void +pad_added_cb (GstElement *element, GstPad *pad, gpointer data) +{ + gint id; + KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); + + if (gst_pad_get_direction (pad) != GST_PAD_SRC) { + return; + } + + id = get_stream_id_from_padname (GST_OBJECT_NAME (pad)); + + if (id < 0) { + GST_ERROR_OBJECT (self, "Invalid HubPort for %" GST_PTR_FORMAT, pad); + return; + } + + kms_base_hub_link_audio_src (KMS_BASE_HUB (self), id, + self->priv->audiomixer, GST_OBJECT_NAME (pad), TRUE); +} + +static void +pad_removed_cb (GstElement *element, GstPad *pad, gpointer data) +{ + GST_DEBUG ("Removed pad %" GST_PTR_FORMAT, pad); +} + +static gint +kms_composite_mixer_handle_port (KmsBaseHub *mixer, GstElement *mixer_end_point) +{ + KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer); + KmsCompositeMixerData *port_data; + gint port_id; + + GST_DEBUG ("Handle new HubPort"); + port_id = KMS_BASE_HUB_CLASS (G_OBJECT_CLASS + (kms_composite_mixer_parent_class))->handle_port (mixer, mixer_end_point); + + if (port_id < 0) { + return port_id; + } + + KMS_COMPOSITE_MIXER_LOCK (self); + + if (self->priv->videomixer == NULL) { + self->priv->videomixer = + kms_utils_element_factory_make ("compositor", PLUGIN_NAME); + g_object_set (G_OBJECT (self->priv->videomixer), "background", + 1 /*black */ , "start-time-selection", 1 /*first */ , + "latency", LATENCY * GST_MSECOND, NULL); + self->priv->mixer_video_agnostic = + kms_utils_element_factory_make ("agnosticbin", PLUGIN_NAME); + + gst_bin_add_many (GST_BIN (mixer), self->priv->videomixer, + self->priv->mixer_video_agnostic, NULL); + + if (self->priv->videotestsrc == NULL) { + GstElement *capsfilter; + GstCaps *filtercaps; + GstPad *pad; + GstPadTemplate *sink_pad_template; + + sink_pad_template = + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS + (self->priv->videomixer), "sink_%u"); + + if (G_UNLIKELY (sink_pad_template == NULL)) { + GST_ERROR_OBJECT (self, "Error taking a new pad from videomixer"); + } + + self->priv->videotestsrc = + kms_utils_element_factory_make ("videotestsrc", PLUGIN_NAME); + capsfilter = kms_utils_element_factory_make ("capsfilter", PLUGIN_NAME); + g_object_set (G_OBJECT (capsfilter), "caps-change-mode", 1, NULL); + + g_object_set (self->priv->videotestsrc, "is-live", TRUE, "pattern", + /*black */ 2, NULL); + + filtercaps = + gst_caps_new_simple ("video/x-raw", + "width", G_TYPE_INT, self->priv->output_width, + "height", G_TYPE_INT, self->priv->output_height, + "framerate", GST_TYPE_FRACTION, self->priv->output_framerate, 1, + NULL); + g_object_set (G_OBJECT (capsfilter), "caps", filtercaps, NULL); + gst_caps_unref (filtercaps); + + gst_bin_add_many (GST_BIN (self), self->priv->videotestsrc, + capsfilter, NULL); + + gst_element_link (self->priv->videotestsrc, capsfilter); + + /*link capsfilter -> videomixer */ + pad = gst_element_request_pad (self->priv->videomixer, sink_pad_template, + NULL, NULL); + + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_QUERY_UPSTREAM, + (GstPadProbeCallback) cb_latency, NULL, NULL); + + gst_element_link_pads (capsfilter, NULL, + self->priv->videomixer, GST_OBJECT_NAME (pad)); + g_object_set (pad, "xpos", 0, "ypos", 0, "alpha", 0.0, NULL); + g_object_unref (pad); + + gst_element_sync_state_with_parent (capsfilter); + gst_element_sync_state_with_parent (self->priv->videotestsrc); + } + + gst_element_sync_state_with_parent (self->priv->videomixer); + gst_element_sync_state_with_parent (self->priv->mixer_video_agnostic); + + gst_element_link (self->priv->videomixer, self->priv->mixer_video_agnostic); + } + + if (self->priv->audiomixer == NULL) { + self->priv->audiomixer = + kms_utils_element_factory_make ("kmsaudiomixer", PLUGIN_NAME); + + gst_bin_add (GST_BIN (mixer), self->priv->audiomixer); + + gst_element_sync_state_with_parent (self->priv->audiomixer); + g_signal_connect (self->priv->audiomixer, "pad-added", + G_CALLBACK (pad_added_cb), self); + g_signal_connect (self->priv->audiomixer, "pad-removed", + G_CALLBACK (pad_removed_cb), self); + } + + if (self->priv->datamixer_sink == NULL) { + self->priv->datamixer_sink = + kms_utils_element_factory_make ("funnel", PLUGIN_NAME); + self->priv->datamixer_src = + kms_utils_element_factory_make ("tee", PLUGIN_NAME); + + gst_bin_add_many (GST_BIN (mixer), self->priv->datamixer_sink, + self->priv->datamixer_src, NULL); + + gst_element_sync_state_with_parent (self->priv->datamixer_sink); + gst_element_sync_state_with_parent (self->priv->datamixer_src); + + gst_element_link (self->priv->datamixer_sink, self->priv->datamixer_src); + } + + kms_base_hub_link_video_src (KMS_BASE_HUB (self), port_id, + self->priv->mixer_video_agnostic, "src_%u", TRUE); + + kms_base_hub_link_data_src (KMS_BASE_HUB (self), port_id, + self->priv->datamixer_src, "src_%u", TRUE); + + port_data = kms_composite_mixer_port_data_create (self, port_id); + g_hash_table_insert (self->priv->ports, create_gint (port_id), port_data); + + KMS_COMPOSITE_MIXER_UNLOCK (self); + + return port_id; +} + +static void +kms_composite_mixer_dispose (GObject *object) +{ + KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (object); + + KMS_COMPOSITE_MIXER_LOCK (self); + g_hash_table_remove_all (self->priv->ports); + KMS_COMPOSITE_MIXER_UNLOCK (self); + g_clear_object (&self->priv->loop); + + G_OBJECT_CLASS (kms_composite_mixer_parent_class)->dispose (object); +} + +static void +kms_composite_mixer_finalize (GObject *object) +{ + KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (object); + + g_rec_mutex_clear (&self->priv->mutex); + + if (self->priv->ports != NULL) { + g_hash_table_unref (self->priv->ports); + self->priv->ports = NULL; + } + + G_OBJECT_CLASS (kms_composite_mixer_parent_class)->finalize (object); +} +void +kms_composite_mixer_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); + + switch (property_id) { + case PROP_WIDTH:{ + compositeMixer->priv->output_width = g_value_get_int (value); + break; + } + case PROP_HEIGHT: + compositeMixer->priv->output_height = g_value_get_int (value); + break; + case PROP_FRAMERATE: + compositeMixer->priv->output_framerate = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +kms_composite_mixer_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER(object); + + switch (property_id) { + case PROP_WIDTH: + g_value_set_int (value, compositeMixer->priv->output_width); + break; + case PROP_HEIGHT:{ + g_value_set_int (value, compositeMixer->priv->output_height); + break; + } + case PROP_FRAMERATE:{ + g_value_set_int (value, compositeMixer->priv->output_framerate); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} +static void +kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + KmsBaseHubClass *base_hub_class = KMS_BASE_HUB_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "CompositeMixer", "Generic", "Mixer element that composes n input flows" + " in one output flow", "David Fernandez "); + + gobject_class->dispose = GST_DEBUG_FUNCPTR (kms_composite_mixer_dispose); + gobject_class->finalize = GST_DEBUG_FUNCPTR (kms_composite_mixer_finalize); + + gobject_class->set_property = kms_composite_mixer_set_property; + gobject_class->get_property = kms_composite_mixer_get_property; + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_int ("width", "width", + "Width of the screen", + 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_int ("height", "height", + "Height of the screen", + 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_FRAMERATE, + g_param_spec_int ("framerate", "framerate", + "Framerate of the screen", + 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); + base_hub_class->handle_port = + GST_DEBUG_FUNCPTR (kms_composite_mixer_handle_port); + base_hub_class->unhandle_port = + GST_DEBUG_FUNCPTR (kms_composite_mixer_unhandle_port); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&audio_src_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&video_src_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&audio_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&video_sink_factory)); + + /* Registers a private structure for the instantiatable type */ + g_type_class_add_private (klass, sizeof (KmsCompositeMixerPrivate)); +} + +static void +kms_composite_mixer_init (KmsCompositeMixer *self) +{ + self->priv = KMS_COMPOSITE_MIXER_GET_PRIVATE (self); + + g_rec_mutex_init (&self->priv->mutex); + + self->priv->ports = g_hash_table_new_full (g_int_hash, g_int_equal, + release_gint, kms_composite_mixer_port_data_destroy); + //TODO:Obtain the dimensions of the bigger input stream + self->priv->output_height = 600; + self->priv->output_width = 800; + self->priv->output_framerate = 15; + self->priv->n_elems = 0; + + self->priv->loop = kms_loop_new (); +} + +gboolean +kms_composite_mixer_plugin_init (GstPlugin *plugin) +{ + return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, + KMS_TYPE_COMPOSITE_MIXER); +} + diff --git a/server/module-elements/src/server/config/Composite.conf.ini b/server/module-elements/src/server/config/Composite.conf.ini index a249a2c16..82a82d0bf 100644 --- a/server/module-elements/src/server/config/Composite.conf.ini +++ b/server/module-elements/src/server/config/Composite.conf.ini @@ -1,4 +1,4 @@ -width=800 -height=600 -framerate=15 +width=10 +height=10 +framerate=10 ; Default resolution and framerate diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp index 060d9e0ef..ddb17f669 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp @@ -36,41 +36,58 @@ namespace kurento { CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline, int64_t width, int64_t height, - int64_t framerate) : HubImpl (conf, - std::dynamic_pointer_cast (mediaPipeline), FACTORY_NAME), - width (width), height (height), framerate (framerate) + std::shared_ptr mediaPipeline, + int width, + int height, + int framerate) + : HubImpl (conf, + std::dynamic_pointer_cast (mediaPipeline), + FACTORY_NAME), + width (width), height (height), framerate (framerate) { - // Check if "width" exists in the config - if (width != 0 || kurento::MediaObjectImpl::getConfigValue(&width, "width", conf)) { - g_object_set(G_OBJECT(element), WIDTH_PROPERTY, width, NULL); - } + if (this->width == 0) { + kurento::MediaObjectImpl::getConfigValue (&this->width, WIDTH_PROPERTY, conf); + } - // Check if "height" exists in the config - if (height != 0 || kurento::MediaObjectImpl::getConfigValue(&height, "height", conf)) { - g_object_set(G_OBJECT(element), HEIGHT_PROPERTY, height, NULL); - } + if (this->width != 0) { + g_object_set (G_OBJECT (element), WIDTH_PROPERTY, this->width, NULL); + } - // Check if "framerate" exists in the config - if (framerate != 0 || kurento::MediaObjectImpl::getConfigValue(&framerate, "framerate", conf)) { - g_object_set(G_OBJECT(element), FRAMERATE_PROPERTY, framerate, NULL); - } + if (this->height == 0) { + kurento::MediaObjectImpl::getConfigValue (&this->height, HEIGHT_PROPERTY, conf); + } + + if (this->height != 0) { + g_object_set (G_OBJECT (element), HEIGHT_PROPERTY, this->height, NULL); + } + + if (this->framerate == 0) { + kurento::MediaObjectImpl::getConfigValue (&this->framerate, FRAMERATE_PROPERTY, + conf); + } + + if (this->framerate != 0) { + g_object_set (G_OBJECT (element), FRAMERATE_PROPERTY, this->framerate, + NULL); + } } MediaObjectImpl * CompositeImplFactory::createObject (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline, - int64_t width = DEFAULT_WIDTH, int64_t height = DEFAULT_HEIGHT, int64_t framerate = DEFAULT_FRAMERATE) const + std::shared_ptr mediaPipeline, + int width = DEFAULT_WIDTH, + int height = DEFAULT_HEIGHT, + int framerate = DEFAULT_FRAMERATE) const { return new CompositeImpl (conf, mediaPipeline, width, height, framerate); } CompositeImpl::StaticConstructor CompositeImpl::staticConstructor; -CompositeImpl::StaticConstructor::StaticConstructor() +CompositeImpl::StaticConstructor::StaticConstructor () { GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, GST_DEFAULT_NAME); } -} /* kurento */ +} // namespace kurento diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig new file mode 100644 index 000000000..1bae88de0 --- /dev/null +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2016 Kurento (http://kurento.org/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include "MediaPipeline.hpp" +#include +#include "CompositeImpl.hpp" +#include +#include +#include + +#define GST_CAT_DEFAULT kurento_composite_impl +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); +#define GST_DEFAULT_NAME "KurentoCompositeImpl" + +#define FACTORY_NAME "compositemixer" + +#define WIDTH_PROPERTY "width" +#define HEIGHT_PROPERTY "height" +#define FRAMERATE_PROPERTY "framerate" + +namespace kurento +{ + +CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, + std::shared_ptr mediaPipeline, + int width, + int height, + int framerate) + : HubImpl (conf, + std::dynamic_pointer_cast (mediaPipeline), + FACTORY_NAME), + width (width), height (height), framerate (framerate) +{ + if (this->width == 0) { + kurento::MediaObjectImpl::getConfigValue (&this->width, WIDTH_PROPERTY, conf); + } + if (this->width != 0) { + g_object_set (G_OBJECT (element), WIDTH_PROPERTY, this->width, NULL); + } + + if (this->height == 0) { + kurento::MediaObjectImpl::getConfigValue (&this->height, HEIGHT_PROPERTY, conf); + } + if (this->height != 0) { + g_object_set (G_OBJECT (element), HEIGHT_PROPERTY, this->height, NULL); + } + + if (this->framerate == 0) { + kurento::MediaObjectImpl::getConfigValue (&this->framerate, FRAMERATE_PROPERTY, + conf); + } + if (this->framerate != 0) { + g_object_set (G_OBJECT (element), FRAMERATE_PROPERTY, this->framerate, + NULL); + } +} + +MediaObjectImpl * +CompositeImplFactory::createObject (const boost::property_tree::ptree &conf, + std::shared_ptr mediaPipeline, + int width = DEFAULT_WIDTH, + int height = DEFAULT_HEIGHT, + int framerate = DEFAULT_FRAMERATE) const +{ + return new CompositeImpl (conf, mediaPipeline, width, height, framerate); +} + +CompositeImpl::StaticConstructor CompositeImpl::staticConstructor; + +CompositeImpl::StaticConstructor::StaticConstructor () +{ + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, + GST_DEFAULT_NAME); +} + +} // namespace kurento diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp index fb3546855..c6fb78aa4 100644 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp @@ -27,9 +27,9 @@ namespace kurento class MediaPipeline; class CompositeImpl; -const int64_t DEFAULT_WIDTH = 800; -const int64_t DEFAULT_HEIGHT = 600; -const int64_t DEFAULT_FRAMERATE = 15; +const int64_t DEFAULT_WIDTH = 800; +const int64_t DEFAULT_HEIGHT = 600; +const int64_t DEFAULT_FRAMERATE = 15; void Serialize (std::shared_ptr &object, JsonSerializer &serializer); @@ -41,7 +41,8 @@ class CompositeImpl : public HubImpl, public virtual Composite CompositeImpl (const boost::property_tree::ptree &conf, std::shared_ptr mediaPipeline, - int64_t width = DEFAULT_WIDTH, int64_t height = DEFAULT_HEIGHT, int64_t framerate = DEFAULT_FRAMERATE); + int width = DEFAULT_WIDTH, int height = DEFAULT_HEIGHT, + int framerate = DEFAULT_FRAMERATE); virtual ~CompositeImpl () {}; @@ -56,7 +57,7 @@ class CompositeImpl : public HubImpl, public virtual Composite virtual void Serialize (JsonSerializer &serializer); private: - int64_t width, height, framerate; + int width, height, framerate; class StaticConstructor { public: diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig new file mode 100644 index 000000000..108c4112a --- /dev/null +++ b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2016 Kurento (http://kurento.org/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __COMPOSITE_IMPL_HPP__ +#define __COMPOSITE_IMPL_HPP__ + +#include "HubImpl.hpp" +#include "Composite.hpp" +#include + +namespace kurento +{ + +class MediaPipeline; +class CompositeImpl; + +const int64_t DEFAULT_WIDTH = 800; +const int64_t DEFAULT_HEIGHT = 600; +const int64_t DEFAULT_FRAMERATE = 15; + +void Serialize (std::shared_ptr &object, + JsonSerializer &serializer); + +class CompositeImpl : public HubImpl, public virtual Composite +{ + +public: + + CompositeImpl (const boost::property_tree::ptree &conf, + std::shared_ptr mediaPipeline, + int width = DEFAULT_WIDTH, int height = DEFAULT_HEIGHT, int framerate = DEFAULT_FRAMERATE); + + virtual ~CompositeImpl () {}; + + /* Next methods are automatically implemented by code generator */ + virtual bool connect (const std::string &eventType, + std::shared_ptr handler); + + virtual void invoke (std::shared_ptr obj, + const std::string &methodName, const Json::Value ¶ms, + Json::Value &response); + + virtual void Serialize (JsonSerializer &serializer); + +private: + int width, height, framerate; + class StaticConstructor + { + public: + StaticConstructor(); + }; + + static StaticConstructor staticConstructor; + +}; + +} /* kurento */ + +#endif /* __COMPOSITE_IMPL_HPP__ */ diff --git a/server/module-elements/src/server/interface/elements.Composite.kmd.json b/server/module-elements/src/server/interface/elements.Composite.kmd.json index c73398fc7..7452ad89a 100644 --- a/server/module-elements/src/server/interface/elements.Composite.kmd.json +++ b/server/module-elements/src/server/interface/elements.Composite.kmd.json @@ -16,14 +16,14 @@ { "name": "width", "doc": "screen width", - "type": "int64", + "type": "int", "optional": true, "defaultValue": 800 }, { "name": "height", "doc": "screen height", - "type": "int64", + "type": "int", "optional": true, "defaultValue": 600 @@ -31,7 +31,7 @@ { "name": "framerate", "doc": "frames per second", - "type": "int64", + "type": "int", "optional": true, "defaultValue": 15 } diff --git a/server/module-elements/tests/server/composite.cpp b/server/module-elements/tests/server/composite.cpp index 9bff1a026..a5d01f6b1 100644 --- a/server/module-elements/tests/server/composite.cpp +++ b/server/module-elements/tests/server/composite.cpp @@ -56,7 +56,7 @@ BOOST_GLOBAL_FIXTURE (GF); GF::GF() { boost::property_tree::ptree ac, audioCodecs, vc, videoCodecs; - gst_init(nullptr, nullptr); + gst_init (nullptr, nullptr); moduleManager.loadModulesFromDirectories ("../../src/server:../../.."); @@ -79,8 +79,8 @@ createComposite () constructorParams ["mediaPipeline"] = mediaPipelineId; composite = moduleManager.getFactory ("Composite")->createObject ( - config, "", - constructorParams ); + config, "", + constructorParams ); return std::dynamic_pointer_cast (composite); } @@ -96,8 +96,8 @@ createComposite (int64_t width, int64_t height, int64_t framerate) constructorParams ["framerate"] = framerate; composite = moduleManager.getFactory ("Composite")->createObject ( - config, "", - constructorParams ); + config, "", + constructorParams ); return std::dynamic_pointer_cast (composite); } @@ -120,8 +120,8 @@ createHubPort (std::shared_ptr composite) constructorParams ["hub"] = composite->getId(); port = moduleManager.getFactory ("HubPort")->createObject ( - config, "", - constructorParams ); + config, "", + constructorParams ); return std::dynamic_pointer_cast (port); } @@ -136,7 +136,8 @@ releaseHubPort (std::shared_ptr &ep) } -static std::shared_ptr createTestSrc() { +static std::shared_ptr createTestSrc() +{ std::shared_ptr src = std::dynamic_pointer_cast (MediaSet::getMediaSet()->ref (new MediaElementImpl ( boost::property_tree::ptree(), @@ -161,10 +162,11 @@ static void dumpPipeline (std::shared_ptr pipeline, std::string fileName) { std::string pipelineDot; - std::shared_ptr details (new GstreamerDotDetails ("SHOW_ALL")); + std::shared_ptr details (new + GstreamerDotDetails ("SHOW_ALL") ); pipelineDot = pipeline->getGstreamerDot (details); - std::ofstream out(fileName); + std::ofstream out (fileName); out << pipelineDot; out.close (); @@ -174,15 +176,18 @@ dumpPipeline (std::shared_ptr pipeline, std::string fileName) void dumpPipeline (std::string pipelineId, std::string fileName) { - std::shared_ptr pipeline = std::dynamic_pointer_cast (MediaSet::getMediaSet ()->getMediaObject (pipelineId)); + std::shared_ptr pipeline = + std::dynamic_pointer_cast + (MediaSet::getMediaSet ()->getMediaObject (pipelineId) ); dumpPipeline (pipeline, fileName); // MediaSet::getMediaSet ()->release (pipelineId); } -static std::shared_ptr getMediaElement (std::shared_ptr element) +static std::shared_ptr getMediaElement ( + std::shared_ptr element) { - return std::dynamic_pointer_cast (element); + return std::dynamic_pointer_cast (element); } @@ -195,8 +200,8 @@ createPassThrough (std::string mediaPipelineId) constructorParams ["mediaPipeline"] = mediaPipelineId; pt = moduleManager.getFactory ("PassThrough")->createObject ( - config, "", - constructorParams ); + config, "", + constructorParams ); return std::dynamic_pointer_cast (pt); } @@ -223,40 +228,44 @@ composite_setup () std::shared_ptr composite = createComposite (); std::shared_ptr src1 = createTestSrc(); std::shared_ptr src2 = createTestSrc(); - std::shared_ptr pt = createPassThrough(mediaPipelineId); + std::shared_ptr pt = createPassThrough (mediaPipelineId); std::shared_ptr port1 = createHubPort (composite); std::shared_ptr port2 = createHubPort (composite); bool audio_flowing = false; bool video_flowing = false; - sigc::connection conn = getMediaElement(pt)->signalMediaFlowInStateChanged.connect([&] ( - MediaFlowInStateChanged event) { - std::shared_ptr state = event.getState(); - if (state->getValue() == MediaFlowState::FLOWING) { - BOOST_CHECK (state->getValue() == MediaFlowState::FLOWING); - if (event.getMediaType ()->getValue() == MediaType::AUDIO) { - BOOST_TEST_MESSAGE ("Audio flowing"); - audio_flowing = true; - } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { - BOOST_TEST_MESSAGE ("Video flowing"); - video_flowing = true; - } - } else if (state->getValue() == MediaFlowState::NOT_FLOWING) { - if (event.getMediaType ()->getValue() == MediaType::AUDIO) { - BOOST_TEST_MESSAGE ("Audio not flowing"); - audio_flowing = false; - } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { - BOOST_TEST_MESSAGE ("Video not flowing"); - video_flowing = false; - } - } - if (audio_flowing && video_flowing) { - media_state_changed = true; - cv.notify_one(); - } - } - ); + sigc::connection conn = getMediaElement ( + pt)->signalMediaFlowInStateChanged.connect ([&] ( + MediaFlowInStateChanged event) { + std::shared_ptr state = event.getState(); + + if (state->getValue() == MediaFlowState::FLOWING) { + BOOST_CHECK (state->getValue() == MediaFlowState::FLOWING); + + if (event.getMediaType ()->getValue() == MediaType::AUDIO) { + BOOST_TEST_MESSAGE ("Audio flowing"); + audio_flowing = true; + } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { + BOOST_TEST_MESSAGE ("Video flowing"); + video_flowing = true; + } + } else if (state->getValue() == MediaFlowState::NOT_FLOWING) { + if (event.getMediaType ()->getValue() == MediaType::AUDIO) { + BOOST_TEST_MESSAGE ("Audio not flowing"); + audio_flowing = false; + } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { + BOOST_TEST_MESSAGE ("Video not flowing"); + video_flowing = false; + } + } + + if (audio_flowing && video_flowing) { + media_state_changed = true; + cv.notify_one(); + } + } + ); src1->connect (port1); src2->connect (port2); @@ -265,69 +274,77 @@ composite_setup () dumpPipeline (mediaPipelineId, "composite_start.dot"); // First stream - cv.wait_for (lck, std::chrono::seconds(10), [&] () { + cv.wait_for (lck, std::chrono::seconds (10), [&] () { return media_state_changed.load(); }); conn.disconnect (); dumpPipeline (mediaPipelineId, "composite_end.dot"); - if (!((getMediaElement(pt)->isMediaFlowingIn (std::make_shared(MediaType::AUDIO))) && ((getMediaElement(pt)->isMediaFlowingIn (std::make_shared(MediaType::VIDEO)))))) { + if (! ( (getMediaElement (pt)->isMediaFlowingIn (std::make_shared + (MediaType::AUDIO) ) ) + && ( (getMediaElement (pt)->isMediaFlowingIn (std::make_shared + (MediaType::VIDEO) ) ) ) ) ) { BOOST_ERROR ("Media is not flowing out from composite"); } - - releasePassTrhough(pt); - releaseHubPort(port1); - releaseHubPort(port2); + + releasePassTrhough (pt); + releaseHubPort (port1); + releaseHubPort (port2); releaseComposite (composite); - releaseTestSrc(src1); - releaseTestSrc(src2); + releaseTestSrc (src1); + releaseTestSrc (src2); } -static void composite_param_setup (){ -std::atomic media_state_changed (false); +static void composite_param_setup () +{ + std::atomic media_state_changed (false); std::condition_variable cv; std::mutex mtx; std::unique_lock lck (mtx); - std::shared_ptr composite = createComposite (800, 600, 15); + std::shared_ptr composite = createComposite (1200, 215, 60); std::shared_ptr src1 = createTestSrc(); std::shared_ptr src2 = createTestSrc(); - std::shared_ptr pt = createPassThrough(mediaPipelineId); + std::shared_ptr pt = createPassThrough (mediaPipelineId); std::shared_ptr port1 = createHubPort (composite); std::shared_ptr port2 = createHubPort (composite); bool audio_flowing = false; bool video_flowing = false; - sigc::connection conn = getMediaElement(pt)->signalMediaFlowInStateChanged.connect([&] ( - MediaFlowInStateChanged event) { - std::shared_ptr state = event.getState(); - if (state->getValue() == MediaFlowState::FLOWING) { - BOOST_CHECK (state->getValue() == MediaFlowState::FLOWING); - if (event.getMediaType ()->getValue() == MediaType::AUDIO) { - BOOST_TEST_MESSAGE ("Audio flowing"); - audio_flowing = true; - } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { - BOOST_TEST_MESSAGE ("Video flowing"); - video_flowing = true; - } - } else if (state->getValue() == MediaFlowState::NOT_FLOWING) { - if (event.getMediaType ()->getValue() == MediaType::AUDIO) { - BOOST_TEST_MESSAGE ("Audio not flowing"); - audio_flowing = false; - } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { - BOOST_TEST_MESSAGE ("Video not flowing"); - video_flowing = false; - } - } - if (audio_flowing && video_flowing) { - media_state_changed = true; - cv.notify_one(); - } - } - ); + sigc::connection conn = getMediaElement ( + pt)->signalMediaFlowInStateChanged.connect ([&] ( + MediaFlowInStateChanged event) { + std::shared_ptr state = event.getState(); + + if (state->getValue() == MediaFlowState::FLOWING) { + BOOST_CHECK (state->getValue() == MediaFlowState::FLOWING); + + if (event.getMediaType ()->getValue() == MediaType::AUDIO) { + BOOST_TEST_MESSAGE ("Audio flowing"); + audio_flowing = true; + } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { + BOOST_TEST_MESSAGE ("Video flowing"); + video_flowing = true; + } + } else if (state->getValue() == MediaFlowState::NOT_FLOWING) { + if (event.getMediaType ()->getValue() == MediaType::AUDIO) { + BOOST_TEST_MESSAGE ("Audio not flowing"); + audio_flowing = false; + } else if (event.getMediaType ()->getValue() == MediaType::VIDEO) { + BOOST_TEST_MESSAGE ("Video not flowing"); + video_flowing = false; + } + } + + if (audio_flowing && video_flowing) { + media_state_changed = true; + cv.notify_one(); + } + } + ); src1->connect (port1); src2->connect (port2); @@ -336,32 +353,35 @@ std::atomic media_state_changed (false); dumpPipeline (mediaPipelineId, "composite_start.dot"); // First stream - cv.wait_for (lck, std::chrono::seconds(10), [&] () { + cv.wait_for (lck, std::chrono::seconds (10), [&] () { return media_state_changed.load(); }); conn.disconnect (); dumpPipeline (mediaPipelineId, "composite_end.dot"); - if (!((getMediaElement(pt)->isMediaFlowingIn (std::make_shared(MediaType::AUDIO))) && ((getMediaElement(pt)->isMediaFlowingIn (std::make_shared(MediaType::VIDEO)))))) { + if (! ( (getMediaElement (pt)->isMediaFlowingIn (std::make_shared + (MediaType::AUDIO) ) ) + && ( (getMediaElement (pt)->isMediaFlowingIn (std::make_shared + (MediaType::VIDEO) ) ) ) ) ) { BOOST_ERROR ("Media is not flowing out from composite"); } - - releasePassTrhough(pt); - releaseHubPort(port1); - releaseHubPort(port2); + + releasePassTrhough (pt); + releaseHubPort (port1); + releaseHubPort (port2); releaseComposite (composite); - releaseTestSrc(src1); - releaseTestSrc(src2); + releaseTestSrc (src1); + releaseTestSrc (src2); } test_suite * -init_unit_test_suite ( int , char *[] ) +init_unit_test_suite ( int, char *[] ) { test_suite *test = BOOST_TEST_SUITE ( "RecorderEndpoint" ); test->add (BOOST_TEST_CASE ( &composite_setup), 0, /* timeout */ 100); test->add (BOOST_TEST_CASE ( &composite_param_setup), 0, /* timeout */ 100); return test; -} \ No newline at end of file +} From b934bb90f18129464628a2288a7451484aa149fa Mon Sep 17 00:00:00 2001 From: emateos Date: Thu, 7 Nov 2024 07:49:52 +0100 Subject: [PATCH 13/13] Deleted unnecessary files generated on previous commit --- .../src/gst-plugins/kmscompositemixer.c~ | 921 ------------------ .../objects/CompositeImpl.cpp.orig | 90 -- .../objects/CompositeImpl.hpp.orig | 72 -- 3 files changed, 1083 deletions(-) delete mode 100644 server/module-elements/src/gst-plugins/kmscompositemixer.c~ delete mode 100644 server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig delete mode 100644 server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig diff --git a/server/module-elements/src/gst-plugins/kmscompositemixer.c~ b/server/module-elements/src/gst-plugins/kmscompositemixer.c~ deleted file mode 100644 index 6a7cb2775..000000000 --- a/server/module-elements/src/gst-plugins/kmscompositemixer.c~ +++ /dev/null @@ -1,921 +0,0 @@ -/* - * (C) Copyright 2013 Kurento (http://kurento.org/) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "kmscompositemixer.h" -#include -#include -#include -#include -#include -#include - -#define LATENCY 600 //ms - -#define PLUGIN_NAME "compositemixer" - -#define KMS_COMPOSITE_MIXER_LOCK(mixer) \ - (g_rec_mutex_lock (&( (KmsCompositeMixer *) (mixer))->priv->mutex)) - -#define KMS_COMPOSITE_MIXER_UNLOCK(mixer) \ - (g_rec_mutex_unlock (&( (KmsCompositeMixer *) (mixer))->priv->mutex)) - -GST_DEBUG_CATEGORY_STATIC (kms_composite_mixer_debug_category); -#define GST_CAT_DEFAULT kms_composite_mixer_debug_category - -#define KMS_COMPOSITE_MIXER_GET_PRIVATE(obj) (\ - G_TYPE_INSTANCE_GET_PRIVATE ( \ - (obj), \ - KMS_TYPE_COMPOSITE_MIXER, \ - KmsCompositeMixerPrivate \ - ) \ - ) - -#define AUDIO_SINK_PAD_PREFIX_COMP "audio_sink_" -#define VIDEO_SINK_PAD_PREFIX_COMP "video_sink_" -#define AUDIO_SRC_PAD_PREFIX_COMP "audio_src_" -#define VIDEO_SRC_PAD_PREFIX_COMP "video_src_" -#define AUDIO_SINK_PAD_NAME_COMP AUDIO_SINK_PAD_PREFIX_COMP "%u" -#define VIDEO_SINK_PAD_NAME_COMP VIDEO_SINK_PAD_PREFIX_COMP "%u" -#define AUDIO_SRC_PAD_NAME_COMP AUDIO_SRC_PAD_PREFIX_COMP "%u" -#define VIDEO_SRC_PAD_NAME_COMP VIDEO_SRC_PAD_PREFIX_COMP "%u" - -static GstStaticPadTemplate audio_sink_factory = -GST_STATIC_PAD_TEMPLATE (AUDIO_SINK_PAD_NAME_COMP, - GST_PAD_SINK, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_AUDIO_CAPS) - ); - -static GstStaticPadTemplate video_sink_factory = -GST_STATIC_PAD_TEMPLATE (VIDEO_SINK_PAD_NAME_COMP, - GST_PAD_SINK, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_VIDEO_CAPS) - ); - -static GstStaticPadTemplate audio_src_factory = -GST_STATIC_PAD_TEMPLATE (AUDIO_SRC_PAD_NAME_COMP, - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_AUDIO_CAPS) - ); - -static GstStaticPadTemplate video_src_factory = -GST_STATIC_PAD_TEMPLATE (VIDEO_SRC_PAD_NAME_COMP, - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_RAW_VIDEO_CAPS) - ); - -struct _KmsCompositeMixerPrivate -{ - GstElement *videomixer; - GstElement *audiomixer; - GstElement *datamixer_sink; - GstElement *datamixer_src; - GstElement *videotestsrc; - GHashTable *ports; - GstElement *mixer_audio_agnostic; - GstElement *mixer_video_agnostic; - KmsLoop *loop; - GRecMutex mutex; - gint n_elems; - gint output_width, output_height, output_framerate; -}; - -/* class initialization */ - -G_DEFINE_TYPE_WITH_CODE (KmsCompositeMixer, kms_composite_mixer, - KMS_TYPE_BASE_HUB, - GST_DEBUG_CATEGORY_INIT (kms_composite_mixer_debug_category, PLUGIN_NAME, - 0, "debug category for compositemixer element")); - -typedef struct _KmsCompositeMixerData -{ - KmsRefStruct parent; - gint id; - KmsCompositeMixer *mixer; - GstElement *capsfilter; - GstElement *tee; - GstElement *fakesink; - gboolean input; - gboolean removing; - gboolean eos_managed; - gulong probe_id; - gulong link_probe_id; - gulong latency_probe_id; - GstPad *video_mixer_pad; - GstPad *tee_sink_pad; -} KmsCompositeMixerData; - -#define KMS_COMPOSITE_MIXER_REF(data) \ - kms_ref_struct_ref (KMS_REF_STRUCT_CAST (data)) -#define KMS_COMPOSITE_MIXER_UNREF(data) \ - kms_ref_struct_unref (KMS_REF_STRUCT_CAST (data)) - -static void -kms_destroy_composite_mixer_data (KmsCompositeMixerData *data) -{ - g_slice_free (KmsCompositeMixerData, data); -} - -static KmsCompositeMixerData * -kms_create_composite_mixer_data () -{ - KmsCompositeMixerData *data; - - data = g_slice_new0 (KmsCompositeMixerData); - kms_ref_struct_init (KMS_REF_STRUCT_CAST (data), - (GDestroyNotify) kms_destroy_composite_mixer_data); - - return data; -} - -static gint -compare_port_data (gconstpointer a, gconstpointer b) -{ - KmsCompositeMixerData *port_data_a = (KmsCompositeMixerData *) a; - KmsCompositeMixerData *port_data_b = (KmsCompositeMixerData *) b; - - return port_data_a->id - port_data_b->id; -} - -static void -kms_composite_mixer_recalculate_sizes (gpointer data) -{ - KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); - GstCaps *filtercaps; - gint width, height, top, left, counter, n_columns, n_rows; - GList *l; - GList *values = g_hash_table_get_values (self->priv->ports); - - if (self->priv->n_elems <= 0) { - return; - } - - counter = 0; - values = g_list_sort (values, compare_port_data); - - n_columns = (gint) ceil (sqrt (self->priv->n_elems)); - n_rows = (gint) ceil ((float) self->priv->n_elems / (float) n_columns); - - GST_DEBUG_OBJECT (self, "columns %d rows %d", n_columns, n_rows); - - width = self->priv->output_width / n_columns; - height = self->priv->output_height / n_rows; - - for (l = values; l != NULL; l = l->next) { - KmsCompositeMixerData *port_data = l->data; - - if (port_data->input == FALSE) { - continue; - } - - filtercaps = - gst_caps_new_simple ("video/x-raw", - "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, - "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); - g_object_set (port_data->capsfilter, "caps", filtercaps, NULL); - gst_caps_unref (filtercaps); - - top = ((counter / n_columns) * height); - left = ((counter % n_columns) * width); - - g_object_set (port_data->video_mixer_pad, "xpos", left, "ypos", top, - "alpha", 1.0, NULL); - counter++; - - GST_DEBUG_OBJECT (self, "counter %d id_port %d ", counter, port_data->id); - GST_DEBUG_OBJECT (self, "top %d left %d width %d height %d", top, left, - width, height); - } - - g_list_free (values); -} - -static gboolean -remove_elements_from_pipeline (KmsCompositeMixerData *port_data) -{ - KmsCompositeMixer *self = port_data->mixer; - - KMS_COMPOSITE_MIXER_LOCK (self); - - gst_element_unlink (port_data->capsfilter, self->priv->videomixer); - - if (port_data->latency_probe_id > 0) { - gst_pad_remove_probe (port_data->video_mixer_pad, - port_data->latency_probe_id); - port_data->latency_probe_id = 0; - } - - if (port_data->video_mixer_pad != NULL) { - gst_element_release_request_pad (self->priv->videomixer, - port_data->video_mixer_pad); - g_object_unref (port_data->video_mixer_pad); - port_data->video_mixer_pad = NULL; - } - - gst_bin_remove_many (GST_BIN (self), - g_object_ref (port_data->capsfilter), - g_object_ref (port_data->tee), g_object_ref (port_data->fakesink), NULL); - - kms_base_hub_unlink_video_src (KMS_BASE_HUB (self), port_data->id); - kms_base_hub_unlink_data_src (KMS_BASE_HUB (self), port_data->id); - - KMS_COMPOSITE_MIXER_UNLOCK (self); - - gst_element_set_state (port_data->capsfilter, GST_STATE_NULL); - gst_element_set_state (port_data->tee, GST_STATE_NULL); - gst_element_set_state (port_data->fakesink, GST_STATE_NULL); - - g_object_unref (port_data->capsfilter); - g_object_unref (port_data->tee); - g_object_unref (port_data->fakesink); - g_object_unref (port_data->tee_sink_pad); - - port_data->tee_sink_pad = NULL; - port_data->capsfilter = NULL; - port_data->tee = NULL; - port_data->fakesink = NULL; - - return G_SOURCE_REMOVE; -} - -static GstPadProbeReturn -cb_EOS_received (GstPad *pad, GstPadProbeInfo *info, gpointer data) -{ - KmsCompositeMixerData *port_data = (KmsCompositeMixerData *) data; - KmsCompositeMixer *self = port_data->mixer; - GstEvent *event; - - if (GST_EVENT_TYPE (gst_pad_probe_info_get_event (info)) != GST_EVENT_EOS) { - return GST_PAD_PROBE_OK; - } - - KMS_COMPOSITE_MIXER_LOCK (self); - - if (!port_data->removing) { - port_data->eos_managed = TRUE; - KMS_COMPOSITE_MIXER_UNLOCK (self); - return GST_PAD_PROBE_OK; - } - - if (port_data->probe_id > 0) { - gst_pad_remove_probe (pad, port_data->probe_id); - port_data->probe_id = 0; - } - - KMS_COMPOSITE_MIXER_UNLOCK (self); - - event = gst_event_new_eos (); - gst_pad_send_event (pad, event); - - kms_loop_idle_add_full (self->priv->loop, G_PRIORITY_DEFAULT, - (GSourceFunc) remove_elements_from_pipeline, - KMS_COMPOSITE_MIXER_REF (port_data), - (GDestroyNotify) kms_ref_struct_unref); - - return GST_PAD_PROBE_OK; -} - -static GstPadProbeReturn -cb_latency (GstPad *pad, GstPadProbeInfo *info, gpointer data) -{ - if (GST_QUERY_TYPE (GST_PAD_PROBE_INFO_QUERY (info)) != GST_QUERY_LATENCY) { - return GST_PAD_PROBE_OK; - } - - GST_LOG_OBJECT (pad, "Modifing latency query. New latency %" G_GUINT64_FORMAT, - (guint64) (LATENCY * GST_MSECOND)); - - gst_query_set_latency (GST_PAD_PROBE_INFO_QUERY (info), - TRUE, 0, LATENCY * GST_MSECOND); - - return GST_PAD_PROBE_HANDLED; -} - -static void -kms_composite_mixer_port_data_destroy (gpointer data) -{ - KmsCompositeMixerData *port_data = (KmsCompositeMixerData *) data; - KmsCompositeMixer *self = port_data->mixer; - GstPad *audiosink; - gchar *padname; - - KMS_COMPOSITE_MIXER_LOCK (self); - - port_data->removing = TRUE; - - kms_base_hub_unlink_video_sink (KMS_BASE_HUB (self), port_data->id); - kms_base_hub_unlink_audio_sink (KMS_BASE_HUB (self), port_data->id); - kms_base_hub_unlink_data_sink (KMS_BASE_HUB (self), port_data->id); - - if (port_data->input) { - GstEvent *event; - gboolean result; - GstPad *pad; - - if (port_data->capsfilter == NULL) { - KMS_COMPOSITE_MIXER_UNLOCK (self); - return; - } - - pad = gst_element_get_static_pad (port_data->capsfilter, "sink"); - - if (pad == NULL) { - KMS_COMPOSITE_MIXER_UNLOCK (self); - return; - } - - if (!GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_EOS)) { - - if (GST_PAD_IS_FLUSHING (pad)) { - gst_pad_send_event (pad, gst_event_new_flush_stop (FALSE)); - } - - event = gst_event_new_eos (); - result = gst_pad_send_event (pad, event); - - if (port_data->input && self->priv->n_elems > 0) { - port_data->input = FALSE; - self->priv->n_elems--; - kms_composite_mixer_recalculate_sizes (self); - } - - KMS_COMPOSITE_MIXER_UNLOCK (self); - - if (!result) { - GST_WARNING ("EOS event did not send"); - } - } else { - gboolean remove = FALSE; - - /* EOS callback was triggered before we could remove the port data */ - /* so we have to remove elements to avoid memory leaks. */ - remove = port_data->eos_managed; - KMS_COMPOSITE_MIXER_UNLOCK (self); - - if (remove) { - /* Remove pipeline without helding the mutex */ - kms_loop_idle_add_full (self->priv->loop, G_PRIORITY_DEFAULT, - (GSourceFunc) remove_elements_from_pipeline, - KMS_COMPOSITE_MIXER_REF (port_data), - (GDestroyNotify) kms_ref_struct_unref); - } - } - - gst_element_unlink (port_data->capsfilter, port_data->tee); - g_object_unref (pad); - } else { - if (port_data->probe_id > 0) { - gst_pad_remove_probe (port_data->video_mixer_pad, port_data->probe_id); - } - - if (port_data->latency_probe_id > 0) { - gst_pad_remove_probe (port_data->video_mixer_pad, - port_data->latency_probe_id); - } - - if (port_data->link_probe_id > 0) { - gst_pad_remove_probe (port_data->tee_sink_pad, port_data->link_probe_id); - } - - KMS_COMPOSITE_MIXER_UNLOCK (self); - - gst_element_unlink (port_data->capsfilter, port_data->tee); - gst_element_unlink (port_data->tee, port_data->fakesink); - - gst_bin_remove (GST_BIN (self), g_object_ref (port_data->capsfilter)); - gst_element_set_state (port_data->capsfilter, GST_STATE_NULL); - g_object_unref (port_data->capsfilter); - port_data->capsfilter = NULL; - - gst_bin_remove (GST_BIN (self), g_object_ref (port_data->tee)); - gst_element_set_state (port_data->tee, GST_STATE_NULL); - g_object_unref (port_data->tee); - port_data->tee = NULL; - - gst_bin_remove (GST_BIN (self), g_object_ref (port_data->fakesink)); - gst_element_set_state (port_data->fakesink, GST_STATE_NULL); - g_object_unref (port_data->fakesink); - port_data->fakesink = NULL; - } - - padname = g_strdup_printf (AUDIO_SINK_PAD, port_data->id); - audiosink = gst_element_get_static_pad (self->priv->audiomixer, padname); - gst_element_release_request_pad (self->priv->audiomixer, audiosink); - gst_object_unref (audiosink); - g_free (padname); -} - -static GstPadProbeReturn -link_to_videomixer (GstPad *pad, GstPadProbeInfo *info, - KmsCompositeMixerData *data) -{ - GstPadTemplate *sink_pad_template; - KmsCompositeMixer *mixer; - GstPad *tee_src; - - if (GST_EVENT_TYPE (gst_pad_probe_info_get_event (info)) != - GST_EVENT_STREAM_START) { - return GST_PAD_PROBE_PASS; - } - - mixer = KMS_COMPOSITE_MIXER (data->mixer); - GST_DEBUG ("stream start detected %d", data->id); - KMS_COMPOSITE_MIXER_LOCK (mixer); - - data->link_probe_id = 0; - data->latency_probe_id = 0; - - sink_pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer->priv-> - videomixer), "sink_%u"); - - if (G_UNLIKELY (sink_pad_template == NULL)) { - GST_ERROR_OBJECT (mixer, "Error taking a new pad from videomixer"); - KMS_COMPOSITE_MIXER_UNLOCK (mixer); - return GST_PAD_PROBE_DROP; - } - - data->input = TRUE; - - /*link tee -> videomixer */ - data->video_mixer_pad = - gst_element_request_pad (mixer->priv->videomixer, - sink_pad_template, NULL, NULL); - - tee_src = gst_element_request_pad_simple (data->tee, "src_%u"); - - gst_element_link_pads (data->tee, GST_OBJECT_NAME (tee_src), - mixer->priv->videomixer, GST_OBJECT_NAME (data->video_mixer_pad)); - g_object_unref (tee_src); - - data->probe_id = gst_pad_add_probe (data->video_mixer_pad, - GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, - (GstPadProbeCallback) cb_EOS_received, - KMS_COMPOSITE_MIXER_REF (data), (GDestroyNotify) kms_ref_struct_unref); - - data->latency_probe_id = gst_pad_add_probe (data->video_mixer_pad, - GST_PAD_PROBE_TYPE_QUERY_UPSTREAM, - (GstPadProbeCallback) cb_latency, NULL, NULL); - - /*recalculate the output sizes */ - mixer->priv->n_elems++; - kms_composite_mixer_recalculate_sizes (mixer); - - //Recalculate latency to avoid video freezes when an element stops to send media. - gst_bin_recalculate_latency (GST_BIN (mixer)); - - KMS_COMPOSITE_MIXER_UNLOCK (mixer); - - return GST_PAD_PROBE_REMOVE; -} - -static void -release_gint (gpointer data) -{ - g_slice_free (gint, data); -} - -static gint * -create_gint (gint value) -{ - gint *p = g_slice_new (gint); - - *p = value; - return p; -} - -static void -kms_composite_mixer_unhandle_port (KmsBaseHub *mixer, gint id) -{ - KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer); - - GST_DEBUG ("unhandle id %d", id); - - KMS_COMPOSITE_MIXER_LOCK (self); - - g_hash_table_remove (self->priv->ports, &id); - - KMS_COMPOSITE_MIXER_UNLOCK (self); - - KMS_BASE_HUB_CLASS (G_OBJECT_CLASS - (kms_composite_mixer_parent_class))->unhandle_port (mixer, id); -} - -static KmsCompositeMixerData * -kms_composite_mixer_port_data_create (KmsCompositeMixer *mixer, gint id) -{ - KmsCompositeMixerData *data; - GstPad *tee_src; - GstCaps *filtercaps; - gchar *padname; - - data = kms_create_composite_mixer_data (); - data->mixer = mixer; - data->id = id; - data->input = FALSE; - data->removing = FALSE; - data->eos_managed = FALSE; - - // Link AUDIO input - - padname = g_strdup_printf (AUDIO_SINK_PAD, data->id); - kms_base_hub_link_audio_sink (KMS_BASE_HUB (mixer), data->id, - mixer->priv->audiomixer, padname, FALSE); - g_free (padname); - - // Link VIDEO input - - data->tee = kms_utils_element_factory_make ("tee", PLUGIN_NAME); - data->fakesink = kms_utils_element_factory_make ("fakesink", PLUGIN_NAME); - data->capsfilter = kms_utils_element_factory_make ("capsfilter", PLUGIN_NAME); - - g_object_set (G_OBJECT (data->capsfilter), "caps-change-mode", - 1 /*delayed */ , NULL); - - g_object_set (G_OBJECT (data->fakesink), "async", FALSE, "sync", FALSE, NULL); - - gst_bin_add_many (GST_BIN (mixer), data->capsfilter, data->tee, - data->fakesink, NULL); - - gst_element_sync_state_with_parent (data->capsfilter); - gst_element_sync_state_with_parent (data->tee); - gst_element_sync_state_with_parent (data->fakesink); - - filtercaps = - gst_caps_new_simple ("video/x-raw", - "width", G_TYPE_INT, mixer->priv->output_width, - "height", G_TYPE_INT, mixer->priv->output_height, - "framerate", GST_TYPE_FRACTION, mixer->priv->output_framerate, 1, - "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); - g_object_set (data->capsfilter, "caps", filtercaps, NULL); - gst_caps_unref (filtercaps); - - /*link basemixer -> video_agnostic */ - kms_base_hub_link_video_sink (KMS_BASE_HUB (mixer), data->id, - data->capsfilter, "sink", FALSE); - - data->tee_sink_pad = gst_element_get_static_pad (data->tee, "sink"); - gst_element_link_pads (data->capsfilter, NULL, data->tee, - GST_OBJECT_NAME (data->tee_sink_pad)); - - tee_src = gst_element_request_pad_simple (data->tee, "src_%u"); - gst_element_link_pads (data->tee, GST_OBJECT_NAME (tee_src), data->fakesink, - "sink"); - g_object_unref (tee_src); - - data->link_probe_id = gst_pad_add_probe (data->tee_sink_pad, - GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_BLOCK, - (GstPadProbeCallback) link_to_videomixer, - KMS_COMPOSITE_MIXER_REF (data), (GDestroyNotify) kms_ref_struct_unref); - - // Link DATA input - - kms_base_hub_link_data_sink (KMS_BASE_HUB (mixer), data->id, - mixer->priv->datamixer_sink, "sink_%u", TRUE); - - return data; -} - -static gint -get_stream_id_from_padname (const gchar *name) -{ - gint64 id; - - if (name == NULL) { - return -1; - } - - if (!g_str_has_prefix (name, AUDIO_SRC_PAD_PREFIX)) { - return -1; - } - - id = g_ascii_strtoll (name + LENGTH_AUDIO_SRC_PAD_PREFIX, NULL, 10); - - if (id > G_MAXINT) { - return -1; - } - - return id; -} - -static void -pad_added_cb (GstElement *element, GstPad *pad, gpointer data) -{ - gint id; - KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (data); - - if (gst_pad_get_direction (pad) != GST_PAD_SRC) { - return; - } - - id = get_stream_id_from_padname (GST_OBJECT_NAME (pad)); - - if (id < 0) { - GST_ERROR_OBJECT (self, "Invalid HubPort for %" GST_PTR_FORMAT, pad); - return; - } - - kms_base_hub_link_audio_src (KMS_BASE_HUB (self), id, - self->priv->audiomixer, GST_OBJECT_NAME (pad), TRUE); -} - -static void -pad_removed_cb (GstElement *element, GstPad *pad, gpointer data) -{ - GST_DEBUG ("Removed pad %" GST_PTR_FORMAT, pad); -} - -static gint -kms_composite_mixer_handle_port (KmsBaseHub *mixer, GstElement *mixer_end_point) -{ - KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer); - KmsCompositeMixerData *port_data; - gint port_id; - - GST_DEBUG ("Handle new HubPort"); - port_id = KMS_BASE_HUB_CLASS (G_OBJECT_CLASS - (kms_composite_mixer_parent_class))->handle_port (mixer, mixer_end_point); - - if (port_id < 0) { - return port_id; - } - - KMS_COMPOSITE_MIXER_LOCK (self); - - if (self->priv->videomixer == NULL) { - self->priv->videomixer = - kms_utils_element_factory_make ("compositor", PLUGIN_NAME); - g_object_set (G_OBJECT (self->priv->videomixer), "background", - 1 /*black */ , "start-time-selection", 1 /*first */ , - "latency", LATENCY * GST_MSECOND, NULL); - self->priv->mixer_video_agnostic = - kms_utils_element_factory_make ("agnosticbin", PLUGIN_NAME); - - gst_bin_add_many (GST_BIN (mixer), self->priv->videomixer, - self->priv->mixer_video_agnostic, NULL); - - if (self->priv->videotestsrc == NULL) { - GstElement *capsfilter; - GstCaps *filtercaps; - GstPad *pad; - GstPadTemplate *sink_pad_template; - - sink_pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS - (self->priv->videomixer), "sink_%u"); - - if (G_UNLIKELY (sink_pad_template == NULL)) { - GST_ERROR_OBJECT (self, "Error taking a new pad from videomixer"); - } - - self->priv->videotestsrc = - kms_utils_element_factory_make ("videotestsrc", PLUGIN_NAME); - capsfilter = kms_utils_element_factory_make ("capsfilter", PLUGIN_NAME); - g_object_set (G_OBJECT (capsfilter), "caps-change-mode", 1, NULL); - - g_object_set (self->priv->videotestsrc, "is-live", TRUE, "pattern", - /*black */ 2, NULL); - - filtercaps = - gst_caps_new_simple ("video/x-raw", - "width", G_TYPE_INT, self->priv->output_width, - "height", G_TYPE_INT, self->priv->output_height, - "framerate", GST_TYPE_FRACTION, self->priv->output_framerate, 1, - NULL); - g_object_set (G_OBJECT (capsfilter), "caps", filtercaps, NULL); - gst_caps_unref (filtercaps); - - gst_bin_add_many (GST_BIN (self), self->priv->videotestsrc, - capsfilter, NULL); - - gst_element_link (self->priv->videotestsrc, capsfilter); - - /*link capsfilter -> videomixer */ - pad = gst_element_request_pad (self->priv->videomixer, sink_pad_template, - NULL, NULL); - - gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_QUERY_UPSTREAM, - (GstPadProbeCallback) cb_latency, NULL, NULL); - - gst_element_link_pads (capsfilter, NULL, - self->priv->videomixer, GST_OBJECT_NAME (pad)); - g_object_set (pad, "xpos", 0, "ypos", 0, "alpha", 0.0, NULL); - g_object_unref (pad); - - gst_element_sync_state_with_parent (capsfilter); - gst_element_sync_state_with_parent (self->priv->videotestsrc); - } - - gst_element_sync_state_with_parent (self->priv->videomixer); - gst_element_sync_state_with_parent (self->priv->mixer_video_agnostic); - - gst_element_link (self->priv->videomixer, self->priv->mixer_video_agnostic); - } - - if (self->priv->audiomixer == NULL) { - self->priv->audiomixer = - kms_utils_element_factory_make ("kmsaudiomixer", PLUGIN_NAME); - - gst_bin_add (GST_BIN (mixer), self->priv->audiomixer); - - gst_element_sync_state_with_parent (self->priv->audiomixer); - g_signal_connect (self->priv->audiomixer, "pad-added", - G_CALLBACK (pad_added_cb), self); - g_signal_connect (self->priv->audiomixer, "pad-removed", - G_CALLBACK (pad_removed_cb), self); - } - - if (self->priv->datamixer_sink == NULL) { - self->priv->datamixer_sink = - kms_utils_element_factory_make ("funnel", PLUGIN_NAME); - self->priv->datamixer_src = - kms_utils_element_factory_make ("tee", PLUGIN_NAME); - - gst_bin_add_many (GST_BIN (mixer), self->priv->datamixer_sink, - self->priv->datamixer_src, NULL); - - gst_element_sync_state_with_parent (self->priv->datamixer_sink); - gst_element_sync_state_with_parent (self->priv->datamixer_src); - - gst_element_link (self->priv->datamixer_sink, self->priv->datamixer_src); - } - - kms_base_hub_link_video_src (KMS_BASE_HUB (self), port_id, - self->priv->mixer_video_agnostic, "src_%u", TRUE); - - kms_base_hub_link_data_src (KMS_BASE_HUB (self), port_id, - self->priv->datamixer_src, "src_%u", TRUE); - - port_data = kms_composite_mixer_port_data_create (self, port_id); - g_hash_table_insert (self->priv->ports, create_gint (port_id), port_data); - - KMS_COMPOSITE_MIXER_UNLOCK (self); - - return port_id; -} - -static void -kms_composite_mixer_dispose (GObject *object) -{ - KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (object); - - KMS_COMPOSITE_MIXER_LOCK (self); - g_hash_table_remove_all (self->priv->ports); - KMS_COMPOSITE_MIXER_UNLOCK (self); - g_clear_object (&self->priv->loop); - - G_OBJECT_CLASS (kms_composite_mixer_parent_class)->dispose (object); -} - -static void -kms_composite_mixer_finalize (GObject *object) -{ - KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (object); - - g_rec_mutex_clear (&self->priv->mutex); - - if (self->priv->ports != NULL) { - g_hash_table_unref (self->priv->ports); - self->priv->ports = NULL; - } - - G_OBJECT_CLASS (kms_composite_mixer_parent_class)->finalize (object); -} -void -kms_composite_mixer_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER (object); - - switch (property_id) { - case PROP_WIDTH:{ - compositeMixer->priv->output_width = g_value_get_int (value); - break; - } - case PROP_HEIGHT: - compositeMixer->priv->output_height = g_value_get_int (value); - break; - case PROP_FRAMERATE: - compositeMixer->priv->output_framerate = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -void -kms_composite_mixer_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - KmsCompositeMixer *compositeMixer = KMS_COMPOSITE_MIXER(object); - - switch (property_id) { - case PROP_WIDTH: - g_value_set_int (value, compositeMixer->priv->output_width); - break; - case PROP_HEIGHT:{ - g_value_set_int (value, compositeMixer->priv->output_height); - break; - } - case PROP_FRAMERATE:{ - g_value_set_int (value, compositeMixer->priv->output_framerate); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} -static void -kms_composite_mixer_class_init (KmsCompositeMixerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - KmsBaseHubClass *base_hub_class = KMS_BASE_HUB_CLASS (klass); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), - "CompositeMixer", "Generic", "Mixer element that composes n input flows" - " in one output flow", "David Fernandez "); - - gobject_class->dispose = GST_DEBUG_FUNCPTR (kms_composite_mixer_dispose); - gobject_class->finalize = GST_DEBUG_FUNCPTR (kms_composite_mixer_finalize); - - gobject_class->set_property = kms_composite_mixer_set_property; - gobject_class->get_property = kms_composite_mixer_get_property; - - g_object_class_install_property (gobject_class, PROP_WIDTH, - g_param_spec_int ("width", "width", - "Width of the screen", - 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); - g_object_class_install_property (gobject_class, PROP_HEIGHT, - g_param_spec_int ("height", "height", - "Height of the screen", - 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); - g_object_class_install_property (gobject_class, PROP_FRAMERATE, - g_param_spec_int ("framerate", "framerate", - "Framerate of the screen", - 0, G_MAXINT, 0, G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY)); - base_hub_class->handle_port = - GST_DEBUG_FUNCPTR (kms_composite_mixer_handle_port); - base_hub_class->unhandle_port = - GST_DEBUG_FUNCPTR (kms_composite_mixer_unhandle_port); - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&audio_src_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&video_src_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&audio_sink_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&video_sink_factory)); - - /* Registers a private structure for the instantiatable type */ - g_type_class_add_private (klass, sizeof (KmsCompositeMixerPrivate)); -} - -static void -kms_composite_mixer_init (KmsCompositeMixer *self) -{ - self->priv = KMS_COMPOSITE_MIXER_GET_PRIVATE (self); - - g_rec_mutex_init (&self->priv->mutex); - - self->priv->ports = g_hash_table_new_full (g_int_hash, g_int_equal, - release_gint, kms_composite_mixer_port_data_destroy); - //TODO:Obtain the dimensions of the bigger input stream - self->priv->output_height = 600; - self->priv->output_width = 800; - self->priv->output_framerate = 15; - self->priv->n_elems = 0; - - self->priv->loop = kms_loop_new (); -} - -gboolean -kms_composite_mixer_plugin_init (GstPlugin *plugin) -{ - return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, - KMS_TYPE_COMPOSITE_MIXER); -} - diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig b/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig deleted file mode 100644 index 1bae88de0..000000000 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.cpp.orig +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) Copyright 2016 Kurento (http://kurento.org/) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include -#include "MediaPipeline.hpp" -#include -#include "CompositeImpl.hpp" -#include -#include -#include - -#define GST_CAT_DEFAULT kurento_composite_impl -GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); -#define GST_DEFAULT_NAME "KurentoCompositeImpl" - -#define FACTORY_NAME "compositemixer" - -#define WIDTH_PROPERTY "width" -#define HEIGHT_PROPERTY "height" -#define FRAMERATE_PROPERTY "framerate" - -namespace kurento -{ - -CompositeImpl::CompositeImpl (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline, - int width, - int height, - int framerate) - : HubImpl (conf, - std::dynamic_pointer_cast (mediaPipeline), - FACTORY_NAME), - width (width), height (height), framerate (framerate) -{ - if (this->width == 0) { - kurento::MediaObjectImpl::getConfigValue (&this->width, WIDTH_PROPERTY, conf); - } - if (this->width != 0) { - g_object_set (G_OBJECT (element), WIDTH_PROPERTY, this->width, NULL); - } - - if (this->height == 0) { - kurento::MediaObjectImpl::getConfigValue (&this->height, HEIGHT_PROPERTY, conf); - } - if (this->height != 0) { - g_object_set (G_OBJECT (element), HEIGHT_PROPERTY, this->height, NULL); - } - - if (this->framerate == 0) { - kurento::MediaObjectImpl::getConfigValue (&this->framerate, FRAMERATE_PROPERTY, - conf); - } - if (this->framerate != 0) { - g_object_set (G_OBJECT (element), FRAMERATE_PROPERTY, this->framerate, - NULL); - } -} - -MediaObjectImpl * -CompositeImplFactory::createObject (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline, - int width = DEFAULT_WIDTH, - int height = DEFAULT_HEIGHT, - int framerate = DEFAULT_FRAMERATE) const -{ - return new CompositeImpl (conf, mediaPipeline, width, height, framerate); -} - -CompositeImpl::StaticConstructor CompositeImpl::staticConstructor; - -CompositeImpl::StaticConstructor::StaticConstructor () -{ - GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, - GST_DEFAULT_NAME); -} - -} // namespace kurento diff --git a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig b/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig deleted file mode 100644 index 108c4112a..000000000 --- a/server/module-elements/src/server/implementation/objects/CompositeImpl.hpp.orig +++ /dev/null @@ -1,72 +0,0 @@ -/* - * (C) Copyright 2016 Kurento (http://kurento.org/) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef __COMPOSITE_IMPL_HPP__ -#define __COMPOSITE_IMPL_HPP__ - -#include "HubImpl.hpp" -#include "Composite.hpp" -#include - -namespace kurento -{ - -class MediaPipeline; -class CompositeImpl; - -const int64_t DEFAULT_WIDTH = 800; -const int64_t DEFAULT_HEIGHT = 600; -const int64_t DEFAULT_FRAMERATE = 15; - -void Serialize (std::shared_ptr &object, - JsonSerializer &serializer); - -class CompositeImpl : public HubImpl, public virtual Composite -{ - -public: - - CompositeImpl (const boost::property_tree::ptree &conf, - std::shared_ptr mediaPipeline, - int width = DEFAULT_WIDTH, int height = DEFAULT_HEIGHT, int framerate = DEFAULT_FRAMERATE); - - virtual ~CompositeImpl () {}; - - /* Next methods are automatically implemented by code generator */ - virtual bool connect (const std::string &eventType, - std::shared_ptr handler); - - virtual void invoke (std::shared_ptr obj, - const std::string &methodName, const Json::Value ¶ms, - Json::Value &response); - - virtual void Serialize (JsonSerializer &serializer); - -private: - int width, height, framerate; - class StaticConstructor - { - public: - StaticConstructor(); - }; - - static StaticConstructor staticConstructor; - -}; - -} /* kurento */ - -#endif /* __COMPOSITE_IMPL_HPP__ */