From 7d113d4180c70de174451583a8aaa56216f280be Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Wed, 31 Mar 2021 09:46:44 +0200 Subject: [PATCH] media: manager: support multiple codecs SDP wise static capabilities are now supporting multiple codecs and generate correct SDP messages. This only relates to SDP offers. When we are answering an offer we must take the offer from the other party into account when creating the answer. Hence why we differentiate between "static" and "dynamic" (not implemented yet) capability strings. --- plugins/sip/calls-sip-media-manager.c | 63 +++++++++++++++++---------- plugins/sip/gst-rfc3551.c | 26 +++++++++-- plugins/sip/gst-rfc3551.h | 1 + 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/plugins/sip/calls-sip-media-manager.c b/plugins/sip/calls-sip-media-manager.c index 978a731..d8c3cb5 100644 --- a/plugins/sip/calls-sip-media-manager.c +++ b/plugins/sip/calls-sip-media-manager.c @@ -33,6 +33,8 @@ typedef struct _CallsSipMediaManager { GObject parent; + + GList *supported_codecs; } CallsSipMediaManager; G_DEFINE_TYPE (CallsSipMediaManager, calls_sip_media_manager, G_TYPE_OBJECT); @@ -43,6 +45,8 @@ calls_sip_media_manager_finalize (GObject *object) { gst_deinit (); + g_list_free (CALLS_SIP_MEDIA_MANAGER (object)->supported_codecs); + G_OBJECT_CLASS (calls_sip_media_manager_parent_class)->finalize (object); } @@ -60,6 +64,8 @@ static void calls_sip_media_manager_init (CallsSipMediaManager *self) { gst_init (NULL, NULL); + + self->supported_codecs = media_codecs_get_candidates (); } @@ -93,34 +99,45 @@ calls_sip_media_manager_static_capabilities (CallsSipMediaManager *self, gboolean use_srtp) { char *payload_type = use_srtp ? "SAVP" : "AVP"; - g_autofree char *media_line = NULL; - g_autofree char *attribute_line = NULL; - MediaCodecInfo *codec; + g_autoptr (GString) media_line = NULL; + g_autoptr (GString) attribute_lines = NULL; + GList *node; g_return_val_if_fail (CALLS_IS_SIP_MEDIA_MANAGER (self), NULL); - codec = get_best_codec (self); - /* TODO support multiplice codecs: f.e. audio 31337 RTP/AVP 9 8 0 96 */ - media_line = g_strdup_printf ("audio %d RTP/%s %s", - port, payload_type, codec->payload_id); - attribute_line = g_strdup_printf ("rtpmap:%s %s/%s", - codec->payload_id, codec->name, codec->clock_rate); + media_line = g_string_new (NULL); + attribute_lines = g_string_new (NULL); - /* TODO add attribute describing RTCP stream */ + if (self->supported_codecs == NULL) { + g_warning ("No supported codecs found. Can't build meaningful SDP message"); + g_string_append_printf (media_line, "m=audio 0 RTP/AVP 0"); + goto done; + } + + /* media lines look f.e like "audio 31337 RTP/AVP 9 8 0" */ + g_string_append_printf (media_line, + "m=audio %d RTP/%s", port, payload_type); + + for (node = self->supported_codecs; node != NULL; node = node->next) { + MediaCodecInfo *codec = node->data; + + g_string_append_printf (media_line, " %s", codec->payload_id); + g_string_append_printf (attribute_lines, + "a=rtpmap:%s %s/%s%s", + codec->payload_id, + codec->name, + codec->clock_rate, + "\r\n"); + } + + g_string_append_printf (attribute_lines, "a=rtcp:%d\r\n", port + 1); + + done: return g_strdup_printf ("v=0\r\n" - "m=%s\r\n" - "a=%s\r\n", - media_line, - attribute_line); -} - - -/* TODO lookup plugins in GStreamer */ -gboolean -calls_sip_media_manager_supports_media (CallsSipMediaManager *self, - const char *media_type) -{ - return TRUE; + "%s\r\n" + "%s\r\n", + media_line->str, + attribute_lines->str); } diff --git a/plugins/sip/gst-rfc3551.c b/plugins/sip/gst-rfc3551.c index 2481359..80b20bb 100644 --- a/plugins/sip/gst-rfc3551.c +++ b/plugins/sip/gst-rfc3551.c @@ -26,16 +26,21 @@ #include -/* TODO check available codecs during runtime */ +/* Use the following codecs in order of preference */ static MediaCodecInfo gst_codecs[] = { + {"8", "PCMA", "8000", 1, "rtppcmapay", "rtppcmadepay", "alawenc", "alawdec"}, {"0", "PCMU", "8000", 1, "rtppcmupay", "rtppcmudepay", "mulawenc", "mulawdec"}, {"3", "GSM", "8000", 1, "rtpgsmpay", "rtpgsmdepay", "gsmenc", "gsmdec"}, - {"4", "G723", "8000", 1, "rtpg723pay", "rtpg723depay", "avenc_g723_1", "avdec_g723_1"}, // does not seem to work - {"8", "PCMA", "8000", 1, "rtppcmapay", "rtppcmadepay", "alawenc", "alawdec"}, {"9", "G722", "8000", 1, "rtpg722pay", "rtpg722depay", "avenc_g722", "avdec_g722"}, + {"4", "G723", "8000", 1, "rtpg723pay", "rtpg723depay", "avenc_g723_1", "avdec_g723_1"}, // does not seem to work }; +static gboolean +media_codec_available_in_gst (MediaCodecInfo *codec) { + /* TODO probe available plugins in GStreamer */ + return TRUE; +} MediaCodecInfo * media_codec_by_name (const char *name) @@ -59,3 +64,18 @@ media_codec_get_gst_capabilities (MediaCodecInfo *codec) codec->name, codec->payload_id); } + +GList * +media_codecs_get_candidates () +{ + GList *candidates = NULL; + + for (guint i = 0; i < G_N_ELEMENTS (gst_codecs); i++) { + if (media_codec_available_in_gst (&gst_codecs[i])) { + g_debug ("Adding %s to the codec candidates", gst_codecs[i].name); + candidates = g_list_append (candidates, &gst_codecs[i]); + } + } + + return candidates; +} diff --git a/plugins/sip/gst-rfc3551.h b/plugins/sip/gst-rfc3551.h index bd1cf29..eca0c03 100644 --- a/plugins/sip/gst-rfc3551.h +++ b/plugins/sip/gst-rfc3551.h @@ -45,3 +45,4 @@ typedef struct { MediaCodecInfo* media_codec_by_name (const char *name); gchar* media_codec_get_gst_capabilities (MediaCodecInfo *codec); +GList* media_codecs_get_candidates ();