mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2025-01-06 03:25:31 +00:00
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.
This commit is contained in:
parent
9fd43eaca8
commit
7d113d4180
3 changed files with 64 additions and 26 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,16 +26,21 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
|
|
Loading…
Reference in a new issue