static GstElement * fs_rtp_dtmf_sound_source_build (FsRtpSpecialSource *source, GList *negotiated_codecs, FsCodec *selected_codec) { FsCodec *telephony_codec = NULL; GstCaps *caps = NULL; GstPad *pad = NULL; GstElement *dtmfsrc = NULL; GstElement *capsfilter = NULL; GstPad *ghostpad = NULL; GstElement *bin = NULL; GstElement *encoder = NULL; GstElement *payloader = NULL; gchar *encoder_name = NULL; gchar *payloader_name = NULL; telephony_codec = get_pcm_law_sound_codec (negotiated_codecs, &encoder_name, &payloader_name); g_return_val_if_fail (telephony_codec, NULL); source->codec = fs_codec_copy (telephony_codec); GST_DEBUG ("Creating dtmf sound source for " FS_CODEC_FORMAT, FS_CODEC_ARGS (telephony_codec)); bin = gst_bin_new (NULL); dtmfsrc = gst_element_factory_make ("dtmfsrc", NULL); if (!dtmfsrc) { GST_ERROR ("Could not make rtpdtmfsrc"); goto error; } if (!gst_bin_add (GST_BIN (bin), dtmfsrc)) { GST_ERROR ("Could not add rtpdtmfsrc to bin"); gst_object_unref (dtmfsrc); goto error; } encoder = gst_element_factory_make (encoder_name, NULL); if (!encoder) { GST_ERROR ("Could not make %s", encoder_name); goto error; } if (!gst_bin_add (GST_BIN (bin), encoder)) { GST_ERROR ("Could not add %s to bin", encoder_name); gst_object_unref (dtmfsrc); goto error; } if (!gst_element_link_pads (dtmfsrc, "src", encoder, "sink")) { GST_ERROR ("Could not link the rtpdtmfsrc and %s", encoder_name); goto error; } payloader = gst_element_factory_make (payloader_name, NULL); if (!payloader) { GST_ERROR ("Could not make %s", payloader_name); goto error; } if (!gst_bin_add (GST_BIN (bin), payloader)) { GST_ERROR ("Could not add %s to bin", payloader_name); gst_object_unref (dtmfsrc); goto error; } if (!gst_element_link_pads (encoder, "src", payloader, "sink")) { GST_ERROR ("Could not link the %s and %s", encoder_name, payloader_name); goto error; } capsfilter = gst_element_factory_make ("capsfilter", NULL); if (!capsfilter) { GST_ERROR ("Could not make capsfilter"); goto error; } if (!gst_bin_add (GST_BIN (bin), capsfilter)) { GST_ERROR ("Could not add capsfilter to bin"); gst_object_unref (capsfilter); goto error; } caps = fs_codec_to_gst_caps (telephony_codec); g_object_set (capsfilter, "caps", caps, NULL); { gchar *str = gst_caps_to_string (caps); GST_DEBUG ("Using caps %s for dtmf", str); g_free (str); } gst_caps_unref (caps); if (!gst_element_link_pads (payloader, "src", capsfilter, "sink")) { GST_ERROR ("Could not link the %s and its capsfilter", payloader_name); goto error; } pad = gst_element_get_static_pad (capsfilter, "src"); if (!pad) { GST_ERROR ("Could not get \"src\" pad from capsfilter"); goto error; } ghostpad = gst_ghost_pad_new ("src", pad); if (!ghostpad) { GST_ERROR ("Could not create a ghostpad for capsfilter src pad" " for dtmfsrc"); goto error; } if (!gst_element_add_pad (bin, ghostpad)) { GST_ERROR ("Could not get \"src\" ghostpad to dtmf sound source bin"); gst_object_unref (pad); goto error; } gst_object_unref (pad); return bin; error: gst_object_unref (bin); return NULL; }
gboolean fs_rtp_sub_stream_add_output_ghostpad_unlock (FsRtpSubStream *substream, GError **error) { GstPad *valve_srcpad; gchar *padname = NULL; GstPad *ghostpad = NULL; FsCodec *codec = NULL; if (fs_rtp_sub_stream_has_stopped_enter (substream)) { FS_RTP_SESSION_UNLOCK (substream->priv->session); return TRUE; } if (substream->priv->adding_output_ghostpad) { FS_RTP_SESSION_UNLOCK (substream->priv->session); goto out; } g_assert (substream->priv->output_ghostpad == NULL); substream->priv->adding_output_ghostpad = TRUE; padname = g_strdup_printf ("src_%u_%u_%d", substream->priv->session->id, substream->ssrc, substream->pt); FS_RTP_SESSION_UNLOCK (substream->priv->session); valve_srcpad = gst_element_get_static_pad (substream->priv->output_valve, "src"); g_assert (valve_srcpad); ghostpad = gst_ghost_pad_new_from_template (padname, valve_srcpad, gst_element_class_get_pad_template ( GST_ELEMENT_GET_CLASS (substream->priv->conference), "src_%d_%d_%d")); gst_object_unref (valve_srcpad); g_free (padname); if (!ghostpad) { g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION, "Could not build ghostpad src_%u_%u_%d", substream->priv->session->id, substream->ssrc, substream->pt); goto error; } if (!gst_pad_set_active (ghostpad, TRUE)) { g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION, "Could not activate the src_%u_%u_%d", substream->priv->session->id, substream->ssrc, substream->pt); gst_object_unref (ghostpad); goto error; } if (!gst_element_add_pad (GST_ELEMENT (substream->priv->conference), ghostpad)) { g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION, "Could add build ghostpad src_%u_%u_%d to the conference", substream->priv->session->id, substream->ssrc, substream->pt); gst_object_unref (ghostpad); goto error; } FS_RTP_SESSION_LOCK (substream->priv->session); substream->priv->output_ghostpad = ghostpad; GST_DEBUG ("Src pad added on substream for ssrc:%X pt:%u " FS_CODEC_FORMAT, substream->ssrc, substream->pt, FS_CODEC_ARGS (substream->codec)); codec = fs_codec_copy (substream->codec); FS_RTP_SESSION_UNLOCK (substream->priv->session); g_signal_emit (substream, signals[SRC_PAD_ADDED], 0, ghostpad, codec); g_signal_emit (substream, signals[CODEC_CHANGED], 0); fs_codec_destroy (codec); g_object_set (substream->priv->output_valve, "drop", FALSE, NULL); out: fs_rtp_sub_stream_has_stopped_exit (substream); return TRUE; error: substream->priv->adding_output_ghostpad = FALSE; fs_rtp_sub_stream_has_stopped_exit (substream); return FALSE; }
static GstElement * fs_rtp_dtmf_event_source_build (FsRtpSpecialSource *source, GList *negotiated_codec_associations, FsCodec *selected_codec) { FsCodec *telephony_codec = NULL; GstCaps *caps = NULL; GstPad *pad = NULL; GstElement *dtmfsrc = NULL; GstElement *capsfilter = NULL; GstPad *ghostpad = NULL; GstElement *bin = NULL; telephony_codec = fs_rtp_dtmf_event_source_get_codec ( FS_RTP_SPECIAL_SOURCE_GET_CLASS(source), negotiated_codec_associations, selected_codec); g_return_val_if_fail (telephony_codec, NULL); source->codec = fs_codec_copy (telephony_codec); bin = gst_bin_new (NULL); GST_DEBUG ("Creating telephone-event source for " FS_CODEC_FORMAT, FS_CODEC_ARGS (telephony_codec)); dtmfsrc = gst_element_factory_make ("rtpdtmfsrc", NULL); if (!dtmfsrc) { GST_ERROR ("Could not make rtpdtmfsrc"); goto error; } if (!gst_bin_add (GST_BIN (bin), dtmfsrc)) { GST_ERROR ("Could not add rtpdtmfsrc to bin"); gst_object_unref (dtmfsrc); goto error; } capsfilter = gst_element_factory_make ("capsfilter", NULL); if (!capsfilter) { GST_ERROR ("Could not make capsfilter"); goto error; } if (!gst_bin_add (GST_BIN (bin), capsfilter)) { GST_ERROR ("Could not add capsfilter to bin"); gst_object_unref (capsfilter); goto error; } caps = fs_codec_to_gst_caps (telephony_codec); g_object_set (capsfilter, "caps", caps, NULL); { gchar *str = gst_caps_to_string (caps); GST_DEBUG ("Using caps %s for dtmf", str); g_free (str); } gst_caps_unref (caps); if (!gst_element_link_pads (dtmfsrc, "src", capsfilter, "sink")) { GST_ERROR ("Could not link the rtpdtmfsrc and its capsfilter"); goto error; } pad = gst_element_get_static_pad (capsfilter, "src"); if (!pad) { GST_ERROR ("Could not get \"src\" pad from capsfilter"); goto error; } ghostpad = gst_ghost_pad_new ("src", pad); if (!ghostpad) { GST_ERROR ("Could not create a ghostpad for capsfilter src pad for" " rtpdtmfsrc"); goto error; } if (!gst_element_add_pad (bin, ghostpad)) { GST_ERROR ("Could not get \"src\" ghostpad to dtmf source bin"); gst_object_unref (pad); goto error; } gst_object_unref (pad); return bin; error: gst_object_unref (bin); return NULL; }