static void _rtpbin_pad_added (GstElement *rtpbin, GstPad *new_pad, gpointer user_data) { FsRtpConference *self = FS_RTP_CONFERENCE (user_data); gchar *name; GST_DEBUG_OBJECT (self, "pad %s:%s added", GST_DEBUG_PAD_NAME (new_pad)); name = gst_pad_get_name (new_pad); if (g_str_has_prefix (name, "recv_rtp_src_")) { guint session_id, ssrc, pt; if (sscanf (name, "recv_rtp_src_%u_%u_%u", &session_id, &ssrc, &pt) == 3 && ssrc <= G_MAXUINT32) { FsRtpSession *session = fs_rtp_conference_get_session_by_id (self, session_id); if (session) { fs_rtp_session_new_recv_pad (session, new_pad, ssrc, pt); g_object_unref (session); } } } g_free (name); }
static void fs_rtp_conference_handle_message ( GstBin * bin, GstMessage * message) { FsRtpConference *self = FS_RTP_CONFERENCE (bin); if (!self->gstrtpbin) return; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); /* we change the structure name and add the session ID to it */ if (gst_structure_has_name (s, "GstRTPBinSDES") && gst_structure_has_field_typed (s, "session", G_TYPE_UINT) && gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT) && gst_structure_has_field_typed (s, "cname", G_TYPE_STRING)) { guint session_id; guint ssrc; const GValue *val; FsRtpSession *session; const gchar *cname; val = gst_structure_get_value (s, "session"); session_id = g_value_get_uint (val); val = gst_structure_get_value (s, "ssrc"); ssrc = g_value_get_uint (val); cname = gst_structure_get_string (s, "cname"); session = fs_rtp_conference_get_session_by_id (self, session_id); if (session) { fs_rtp_session_associate_ssrc_cname (session, ssrc, cname); g_object_unref (session); } else { GST_WARNING_OBJECT (self,"Our GstRtpBin announced a new association" "for non-existent session %u for ssrc: %u and cname %s", session_id, ssrc, cname); } } /* fallthrough to forward the modified message to the parent */ } default: { GST_BIN_CLASS (parent_class)->handle_message (bin, message); break; } } }
static void _rtpbin_on_ssrc_validated (GstElement *rtpbin, guint session_id, guint ssrc, gpointer user_data) { FsRtpConference *self = FS_RTP_CONFERENCE (user_data); FsRtpSession *session = fs_rtp_conference_get_session_by_id (self, session_id); if (session) { fs_rtp_session_ssrc_validated (session, ssrc); g_object_unref (session); } }
static GstCaps * _rtpbin_request_pt_map (GstElement *element, guint session_id, guint pt, gpointer user_data) { FsRtpConference *self = FS_RTP_CONFERENCE (user_data); FsRtpSession *session = NULL; GstCaps *caps = NULL; session = fs_rtp_conference_get_session_by_id (self, session_id); if (session) { caps = fs_rtp_session_request_pt_map (session, pt); g_object_unref (session); } else { GST_WARNING_OBJECT (self,"Rtpbin %p tried to request the caps for " " payload type %u for non-existent session %u", element, pt, session_id); } return caps; }
static void fs_rtp_conference_handle_message ( GstBin * bin, GstMessage * message) { FsRtpConference *self = FS_RTP_CONFERENCE (bin); if (!self->rtpbin) goto out; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); /* we change the structure name and add the session ID to it */ if (gst_structure_has_name (s, "application/x-rtp-source-sdes") && gst_structure_has_field_typed (s, "session", G_TYPE_UINT) && gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT) && gst_structure_has_field_typed (s, "cname", G_TYPE_STRING)) { guint session_id; guint ssrc; const GValue *val; FsRtpSession *session; const gchar *cname; val = gst_structure_get_value (s, "session"); session_id = g_value_get_uint (val); val = gst_structure_get_value (s, "ssrc"); ssrc = g_value_get_uint (val); cname = gst_structure_get_string (s, "cname"); if (!ssrc || !cname) { GST_WARNING_OBJECT (self, "Got GstRTPBinSDES without a ssrc or a cname (ssrc:%u cname:%p)", ssrc, cname); break; } session = fs_rtp_conference_get_session_by_id (self, session_id); if (session) { fs_rtp_session_associate_ssrc_cname (session, ssrc, cname); g_object_unref (session); } else { GST_WARNING_OBJECT (self,"Our RtpBin announced a new association" "for non-existent session %u for ssrc: %u and cname %s", session_id, ssrc, cname); } } else if (gst_structure_has_name (s, "dtmf-event-processed") || gst_structure_has_name (s, "dtmf-event-dropped")) { GList *item; guint cookie; GST_OBJECT_LOCK (self); restart: cookie = self->priv->sessions_cookie; for (item = self->priv->sessions; item; item = item->next) { GST_OBJECT_UNLOCK (self); if (fs_rtp_session_handle_dtmf_event_message (item->data, message)) { gst_message_unref (message); message = NULL; goto out; } GST_OBJECT_LOCK (self); if (cookie != self->priv->sessions_cookie) goto restart; } GST_OBJECT_UNLOCK (self); } } break; case GST_MESSAGE_STREAM_STATUS: { GstStreamStatusType type; guint i; gst_message_parse_stream_status (message, &type, NULL); switch (type) { case GST_STREAM_STATUS_TYPE_ENTER: GST_OBJECT_LOCK (self); for (i = 0; i < self->priv->threads->len; i++) { if (g_ptr_array_index (self->priv->threads, i) == g_thread_self ()) goto done; } g_ptr_array_add (self->priv->threads, g_thread_self ()); done: GST_OBJECT_UNLOCK (self); break; case GST_STREAM_STATUS_TYPE_LEAVE: GST_OBJECT_LOCK (self); while (g_ptr_array_remove_fast (self->priv->threads, g_thread_self ())); GST_OBJECT_UNLOCK (self); break; default: /* Do nothing */ break; } } break; default: break; } out: /* forward all messages to the parent */ if (message) GST_BIN_CLASS (fs_rtp_conference_parent_class)->handle_message (bin, message); }