mgcp: Store one more codec/payload type if it is present
In case of some RTP proxy from time to time we are offered both G729 and G711 but only one of them will work. I intend to adjust the codec at runtime in case we receive the wrong codec.
This commit is contained in:
parent
fa80d07de0
commit
e46bc2714d
|
@ -90,6 +90,7 @@ struct mgcp_rtp_end {
|
||||||
|
|
||||||
/* audio codec information */
|
/* audio codec information */
|
||||||
struct mgcp_rtp_codec codec;
|
struct mgcp_rtp_codec codec;
|
||||||
|
struct mgcp_rtp_codec alt_codec; /* TODO/XXX: make it generic */
|
||||||
|
|
||||||
/* per endpoint data */
|
/* per endpoint data */
|
||||||
int frames_per_packet;
|
int frames_per_packet;
|
||||||
|
|
|
@ -738,7 +738,9 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line;
|
||||||
int found_media = 0;
|
int found_media = 0;
|
||||||
|
/* TODO/XXX make it more generic */
|
||||||
int audio_payload = -1;
|
int audio_payload = -1;
|
||||||
|
int audio_payload_alt = -1;
|
||||||
|
|
||||||
for_each_line(line, p->save) {
|
for_each_line(line, p->save) {
|
||||||
switch (line[0]) {
|
switch (line[0]) {
|
||||||
|
@ -758,10 +760,12 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
|
||||||
|
|
||||||
if (sscanf(line, "a=rtpmap:%d %63s",
|
if (sscanf(line, "a=rtpmap:%d %63s",
|
||||||
&payload, audio_name) == 2) {
|
&payload, audio_name) == 2) {
|
||||||
if (payload != audio_payload)
|
if (payload == audio_payload)
|
||||||
break;
|
set_audio_info(p->cfg, &rtp->codec,
|
||||||
|
payload, audio_name);
|
||||||
set_audio_info(p->cfg, &rtp->codec, payload, audio_name);
|
else if (payload == audio_payload_alt)
|
||||||
|
set_audio_info(p->cfg, &rtp->alt_codec,
|
||||||
|
payload, audio_name);
|
||||||
} else if (sscanf(line, "a=ptime:%d-%d",
|
} else if (sscanf(line, "a=ptime:%d-%d",
|
||||||
&ptime, &ptime2) >= 1) {
|
&ptime, &ptime2) >= 1) {
|
||||||
if (ptime2 > 0 && ptime2 != ptime)
|
if (ptime2 > 0 && ptime2 != ptime)
|
||||||
|
@ -769,6 +773,7 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
|
||||||
else
|
else
|
||||||
rtp->packet_duration_ms = ptime;
|
rtp->packet_duration_ms = ptime;
|
||||||
} else if (sscanf(line, "a=maxptime:%d", &ptime2) == 1) {
|
} else if (sscanf(line, "a=maxptime:%d", &ptime2) == 1) {
|
||||||
|
/* TODO/XXX: Store this per codec and derive it on use */
|
||||||
if (ptime2 * rtp->codec.frame_duration_den >
|
if (ptime2 * rtp->codec.frame_duration_den >
|
||||||
rtp->codec.frame_duration_num * 1500)
|
rtp->codec.frame_duration_num * 1500)
|
||||||
/* more than 1 frame */
|
/* more than 1 frame */
|
||||||
|
@ -777,15 +782,20 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'm': {
|
case 'm': {
|
||||||
int port;
|
int port, rc;
|
||||||
audio_payload = -1;
|
audio_payload = -1;
|
||||||
|
audio_payload_alt = -1;
|
||||||
|
|
||||||
if (sscanf(line, "m=audio %d RTP/AVP %d",
|
rc = sscanf(line, "m=audio %d RTP/AVP %d %d",
|
||||||
&port, &audio_payload) == 2) {
|
&port, &audio_payload, &audio_payload_alt);
|
||||||
|
if (rc >= 2) {
|
||||||
rtp->rtp_port = htons(port);
|
rtp->rtp_port = htons(port);
|
||||||
rtp->rtcp_port = htons(port + 1);
|
rtp->rtcp_port = htons(port + 1);
|
||||||
found_media = 1;
|
found_media = 1;
|
||||||
set_audio_info(p->cfg, &rtp->codec, audio_payload, NULL);
|
set_audio_info(p->cfg, &rtp->codec, audio_payload, NULL);
|
||||||
|
if (rc == 3)
|
||||||
|
set_audio_info(p->cfg, &rtp->alt_codec,
|
||||||
|
audio_payload_alt, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1486,6 +1496,7 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
|
||||||
end->output_enabled = 0;
|
end->output_enabled = 0;
|
||||||
|
|
||||||
mgcp_rtp_codec_reset(&end->codec);
|
mgcp_rtp_codec_reset(&end->codec);
|
||||||
|
mgcp_rtp_codec_reset(&end->alt_codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
|
static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* (C) 2011-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
* (C) 2011-2012,2014 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||||
* (C) 2011-2012 by On-Waves
|
* (C) 2011-2012,2014 by On-Waves
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -268,6 +268,61 @@ static void test_strline(void)
|
||||||
#define PTYPE_NONE 128
|
#define PTYPE_NONE 128
|
||||||
#define PTYPE_NYI PTYPE_NONE
|
#define PTYPE_NYI PTYPE_NONE
|
||||||
|
|
||||||
|
#define CRCX_MULT_1 "CRCX 2 1@mgw MGCP 1.0\r\n" \
|
||||||
|
"M: recvonly\r\n" \
|
||||||
|
"C: 2\r\n" \
|
||||||
|
"X\r\n" \
|
||||||
|
"L: p:20\r\n" \
|
||||||
|
"\r\n" \
|
||||||
|
"v=0\r\n" \
|
||||||
|
"c=IN IP4 123.12.12.123\r\n" \
|
||||||
|
"m=audio 5904 RTP/AVP 18 97\r\n"\
|
||||||
|
"a=rtpmap:18 G729/8000\r\n" \
|
||||||
|
"a=rtpmap:97 GSM-EFR/8000\r\n" \
|
||||||
|
"a=ptime:40\r\n"
|
||||||
|
|
||||||
|
#define CRCX_MULT_2 "CRCX 2 2@mgw MGCP 1.0\r\n" \
|
||||||
|
"M: recvonly\r\n" \
|
||||||
|
"C: 2\r\n" \
|
||||||
|
"X\r\n" \
|
||||||
|
"L: p:20\r\n" \
|
||||||
|
"\r\n" \
|
||||||
|
"v=0\r\n" \
|
||||||
|
"c=IN IP4 123.12.12.123\r\n" \
|
||||||
|
"m=audio 5904 RTP/AVP 18 97 101\r\n"\
|
||||||
|
"a=rtpmap:18 G729/8000\r\n" \
|
||||||
|
"a=rtpmap:97 GSM-EFR/8000\r\n" \
|
||||||
|
"a=rtpmap:101 FOO/8000\r\n" \
|
||||||
|
"a=ptime:40\r\n"
|
||||||
|
|
||||||
|
#define CRCX_MULT_3 "CRCX 2 3@mgw MGCP 1.0\r\n" \
|
||||||
|
"M: recvonly\r\n" \
|
||||||
|
"C: 2\r\n" \
|
||||||
|
"X\r\n" \
|
||||||
|
"L: p:20\r\n" \
|
||||||
|
"\r\n" \
|
||||||
|
"v=0\r\n" \
|
||||||
|
"c=IN IP4 123.12.12.123\r\n" \
|
||||||
|
"m=audio 5904 RTP/AVP\r\n" \
|
||||||
|
"a=rtpmap:18 G729/8000\r\n" \
|
||||||
|
"a=rtpmap:97 GSM-EFR/8000\r\n" \
|
||||||
|
"a=rtpmap:101 FOO/8000\r\n" \
|
||||||
|
"a=ptime:40\r\n"
|
||||||
|
|
||||||
|
#define CRCX_MULT_4 "CRCX 2 4@mgw MGCP 1.0\r\n" \
|
||||||
|
"M: recvonly\r\n" \
|
||||||
|
"C: 2\r\n" \
|
||||||
|
"X\r\n" \
|
||||||
|
"L: p:20\r\n" \
|
||||||
|
"\r\n" \
|
||||||
|
"v=0\r\n" \
|
||||||
|
"c=IN IP4 123.12.12.123\r\n" \
|
||||||
|
"m=audio 5904 RTP/AVP 18\r\n" \
|
||||||
|
"a=rtpmap:18 G729/8000\r\n" \
|
||||||
|
"a=rtpmap:97 GSM-EFR/8000\r\n" \
|
||||||
|
"a=rtpmap:101 FOO/8000\r\n" \
|
||||||
|
"a=ptime:40\r\n"
|
||||||
|
|
||||||
struct mgcp_test {
|
struct mgcp_test {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *req;
|
const char *req;
|
||||||
|
@ -877,6 +932,72 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts)
|
||||||
force_monotonic_time_us = -1;
|
force_monotonic_time_us = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_multilple_codec(void)
|
||||||
|
{
|
||||||
|
struct mgcp_config *cfg;
|
||||||
|
struct mgcp_endpoint *endp;
|
||||||
|
struct msgb *inp, *resp;
|
||||||
|
|
||||||
|
printf("Testing multiple payload types\n");
|
||||||
|
|
||||||
|
cfg = mgcp_config_alloc();
|
||||||
|
cfg->trunk.number_endpoints = 64;
|
||||||
|
mgcp_endpoints_allocate(&cfg->trunk);
|
||||||
|
cfg->policy_cb = mgcp_test_policy_cb;
|
||||||
|
mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
|
||||||
|
|
||||||
|
/* Allocate endpoint 1@mgw with two codecs */
|
||||||
|
last_endpoint = -1;
|
||||||
|
inp = create_msg(CRCX_MULT_1);
|
||||||
|
resp = mgcp_handle_message(cfg, inp);
|
||||||
|
msgb_free(inp);
|
||||||
|
msgb_free(resp);
|
||||||
|
|
||||||
|
OSMO_ASSERT(last_endpoint == 1);
|
||||||
|
endp = &cfg->trunk.endpoints[last_endpoint];
|
||||||
|
OSMO_ASSERT(endp->net_end.codec.payload_type == 18);
|
||||||
|
OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 97);
|
||||||
|
|
||||||
|
/* Allocate 2@mgw with three codecs, last one ignored */
|
||||||
|
last_endpoint = -1;
|
||||||
|
inp = create_msg(CRCX_MULT_2);
|
||||||
|
resp = mgcp_handle_message(cfg, inp);
|
||||||
|
msgb_free(inp);
|
||||||
|
msgb_free(resp);
|
||||||
|
|
||||||
|
OSMO_ASSERT(last_endpoint == 2);
|
||||||
|
endp = &cfg->trunk.endpoints[last_endpoint];
|
||||||
|
OSMO_ASSERT(endp->net_end.codec.payload_type == 18);
|
||||||
|
OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 97);
|
||||||
|
|
||||||
|
/* Allocate 3@mgw with no codecs, check for PT == -1 */
|
||||||
|
last_endpoint = -1;
|
||||||
|
inp = create_msg(CRCX_MULT_3);
|
||||||
|
resp = mgcp_handle_message(cfg, inp);
|
||||||
|
msgb_free(inp);
|
||||||
|
msgb_free(resp);
|
||||||
|
|
||||||
|
OSMO_ASSERT(last_endpoint == 3);
|
||||||
|
endp = &cfg->trunk.endpoints[last_endpoint];
|
||||||
|
OSMO_ASSERT(endp->net_end.codec.payload_type == -1);
|
||||||
|
OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1);
|
||||||
|
|
||||||
|
/* Allocate 4@mgw with a single codec */
|
||||||
|
last_endpoint = -1;
|
||||||
|
inp = create_msg(CRCX_MULT_4);
|
||||||
|
resp = mgcp_handle_message(cfg, inp);
|
||||||
|
msgb_free(inp);
|
||||||
|
msgb_free(resp);
|
||||||
|
|
||||||
|
OSMO_ASSERT(last_endpoint == 4);
|
||||||
|
endp = &cfg->trunk.endpoints[last_endpoint];
|
||||||
|
OSMO_ASSERT(endp->net_end.codec.payload_type == 18);
|
||||||
|
OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1);
|
||||||
|
|
||||||
|
|
||||||
|
talloc_free(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
osmo_init_logging(&log_info);
|
osmo_init_logging(&log_info);
|
||||||
|
@ -892,6 +1013,7 @@ int main(int argc, char **argv)
|
||||||
test_packet_error_detection(0, 0);
|
test_packet_error_detection(0, 0);
|
||||||
test_packet_error_detection(0, 1);
|
test_packet_error_detection(0, 1);
|
||||||
test_packet_error_detection(1, 1);
|
test_packet_error_detection(1, 1);
|
||||||
|
test_multilple_codec();
|
||||||
|
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -474,4 +474,5 @@ Stats: Jitter = 0, Transit = -144000
|
||||||
In TS: 160320, dTS: 160, Seq: 1002
|
In TS: 160320, dTS: 160, Seq: 1002
|
||||||
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
|
||||||
Stats: Jitter = 0, Transit = -144000
|
Stats: Jitter = 0, Transit = -144000
|
||||||
|
Testing multiple payload types
|
||||||
Done
|
Done
|
||||||
|
|
Loading…
Reference in New Issue