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); 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 gint kms_alpha_blending_handle_port (KmsBaseHub * mixer, GstElement * mixer_end_point) { KmsAlphaBlending *self = KMS_ALPHA_BLENDING (mixer); KmsAlphaBlendingData *port_data; gint port_id; port_id = KMS_BASE_HUB_CLASS (G_OBJECT_CLASS (kms_alpha_blending_parent_class))->handle_port (mixer, mixer_end_point); if (port_id < 0) { return port_id; } KMS_ALPHA_BLENDING_LOCK (self); if (self->priv->videomixer == NULL) { GstElement *videorate_mixer; videorate_mixer = gst_element_factory_make ("videorate", NULL); self->priv->videomixer = gst_element_factory_make ("compositor", NULL); g_object_set (G_OBJECT (self->priv->videomixer), "background", 1, NULL); self->priv->mixer_video_agnostic = gst_element_factory_make ("agnosticbin", NULL); gst_bin_add_many (GST_BIN (mixer), self->priv->videomixer, videorate_mixer, self->priv->mixer_video_agnostic, NULL); gst_element_sync_state_with_parent (self->priv->videomixer); gst_element_sync_state_with_parent (videorate_mixer); gst_element_sync_state_with_parent (self->priv->mixer_video_agnostic); gst_element_link_many (self->priv->videomixer, videorate_mixer, self->priv->mixer_video_agnostic, NULL); } if (self->priv->audiomixer == NULL) { self->priv->audiomixer = gst_element_factory_make ("kmsaudiomixer", NULL); 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); } kms_base_hub_link_video_src (KMS_BASE_HUB (self), port_id, self->priv->mixer_video_agnostic, "src_%u", TRUE); port_data = kms_alpha_blending_port_data_create (self, port_id); g_hash_table_insert (self->priv->ports, GINT_TO_POINTER (port_id), port_data); KMS_ALPHA_BLENDING_UNLOCK (self); return port_id; }
static void kms_dispatcher_class_init (KmsDispatcherClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); KmsBaseHubClass *base_hub_class = KMS_BASE_HUB_CLASS (klass); gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), "Dispatcher", "Generic", "N to M dispatcher that makes dispatching of " "media flow", "Santiago Carot-Nemesio <sancane at gmail dot com>"); klass->connect = GST_DEBUG_FUNCPTR (kms_dispatcher_connect); gobject_class->dispose = GST_DEBUG_FUNCPTR (kms_dispatcher_dispose); gobject_class->finalize = GST_DEBUG_FUNCPTR (kms_dispatcher_finalize); base_hub_class->handle_port = GST_DEBUG_FUNCPTR (kms_dispatcher_handle_port); base_hub_class->unhandle_port = GST_DEBUG_FUNCPTR (kms_dispatcher_unhandle_port); /* Signals initialization */ obj_signals[SIGNAL_CONNECT] = g_signal_new ("connect", G_TYPE_FROM_CLASS (klass), G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (KmsDispatcherClass, connect), NULL, NULL, __kms_core_marshal_BOOLEAN__UINT_UINT, G_TYPE_BOOLEAN, 2, G_TYPE_UINT, G_TYPE_UINT); /* Registers a private structure for the instantiatable type */ g_type_class_add_private (klass, sizeof (KmsDispatcherPrivate)); }
gboolean kms_base_hub_unlink_audio_sink (KmsBaseHub * mixer, gint id) { g_return_val_if_fail (KMS_IS_BASE_HUB (mixer), FALSE); return KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (mixer))->unlink_audio_sink (mixer, id); }
gboolean kms_base_hub_link_audio_sink (KmsBaseHub * mixer, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { g_return_val_if_fail (KMS_IS_BASE_HUB (mixer), FALSE); return KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (mixer))->link_audio_sink (mixer, id, internal_element, pad_name, remove_on_unlink); }
static void kms_dispatcher_unhandle_port (KmsBaseHub * hub, gint id) { KmsDispatcher *self = KMS_DISPATCHER (hub); KMS_DISPATCHER_LOCK (self); g_hash_table_remove (self->priv->ports, &id); KMS_DISPATCHER_UNLOCK (self); KMS_BASE_HUB_CLASS (kms_dispatcher_parent_class)->unhandle_port (hub, id); }
static void kms_selectable_mixer_unhandle_port (KmsBaseHub * hub, gint id) { KmsSelectableMixer *self = KMS_SELECTABLE_MIXER (hub); KMS_SELECTABLE_MIXER_LOCK (self); g_hash_table_remove (self->priv->ports, &id); KMS_SELECTABLE_MIXER_LOCK (self); KMS_BASE_HUB_CLASS (kms_selectable_mixer_parent_class)->unhandle_port (hub, id); }
static void kms_alpha_blending_class_init (KmsAlphaBlendingClass * 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), "AlphaBlending", "Generic", "Mixer element using the alpha channel " " in one output flow", "David Fernandez <*****@*****.**>"); klass->set_port_properties = GST_DEBUG_FUNCPTR (kms_alpha_blending_set_port_properties); gobject_class->set_property = kms_alpha_blending_set_property; gobject_class->get_property = kms_alpha_blending_get_property; gobject_class->dispose = GST_DEBUG_FUNCPTR (kms_alpha_blending_dispose); gobject_class->finalize = GST_DEBUG_FUNCPTR (kms_alpha_blending_finalize); base_hub_class->handle_port = GST_DEBUG_FUNCPTR (kms_alpha_blending_handle_port); base_hub_class->unhandle_port = GST_DEBUG_FUNCPTR (kms_alpha_blending_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)); g_object_class_install_property (gobject_class, PROP_SET_MASTER, g_param_spec_boxed ("set-master", "set master", "Set the master port", GST_TYPE_STRUCTURE, (GParamFlags) G_PARAM_READWRITE)); /* Signals initialization */ kms_alpha_blending_signals[SIGNAL_SET_PORT_PROPERTIES] = g_signal_new ("set-port-properties", G_TYPE_FROM_CLASS (klass), G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (KmsAlphaBlendingClass, set_port_properties), NULL, NULL, __kms_core_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_STRUCTURE); /* Registers a private structure for the instantiatable type */ g_type_class_add_private (klass, sizeof (KmsAlphaBlendingPrivate)); }
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 void kms_alpha_blending_unhandle_port (KmsBaseHub * mixer, gint id) { KmsAlphaBlending *self = KMS_ALPHA_BLENDING (mixer); GST_DEBUG ("unhandle id %d", id); KMS_ALPHA_BLENDING_LOCK (self); g_hash_table_remove (self->priv->ports, GINT_TO_POINTER (id)); KMS_ALPHA_BLENDING_UNLOCK (self); KMS_BASE_HUB_CLASS (G_OBJECT_CLASS (kms_alpha_blending_parent_class))->unhandle_port (mixer, id); GST_DEBUG ("end unhandle port id %d", id); }
static gint kms_dispatcher_handle_port (KmsBaseHub * hub, GstElement * mixer_port) { KmsDispatcher *self = KMS_DISPATCHER (hub); KmsDispatcherPortData *port_data; gint port_id; port_id = KMS_BASE_HUB_CLASS (kms_dispatcher_parent_class)->handle_port (hub, mixer_port); if (port_id < 0) return -1; port_data = kms_dispatcher_port_data_create (self, port_id); KMS_DISPATCHER_LOCK (self); g_hash_table_insert (self->priv->ports, create_gint (port_id), port_data); KMS_DISPATCHER_UNLOCK (self); return port_id; }
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 port"); 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 = gst_element_factory_make ("compositor", NULL); 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 = gst_element_factory_make ("agnosticbin", NULL); 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 = gst_element_factory_make ("videotestsrc", NULL); capsfilter = gst_element_factory_make ("capsfilter", NULL); 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, 15, 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 = gst_element_factory_make ("kmsaudiomixer", NULL); 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); } kms_base_hub_link_video_src (KMS_BASE_HUB (self), port_id, self->priv->mixer_video_agnostic, "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; }