sdp_audio_codecs(): add 'once', 'pick_unused_pt_nr' args
So far the API is pivoting on the payload type numbers as the "primary key" for codec lists. However, working with variants of codecs, the payload type numbers are just incidental, and the API isn't helpful. - change the behavior to regard the subtype name and fmtp as the defining identity of a codec: use sdp_audio_codec_cmp() to match. - add argument 'once': flag to make sure a given subtype+fmtp exists only once, regardless of payload type nr. - add argument 'pick_unused_pt_nr': flag to make sure a new entry doesn't duplicate payload type numbers. This is preparation to properly match AMR variants, in order to fix the expected error currently visible in msc_vlr_test_call.c:875. Change-Id: I87db779dbab39dfdef2724488ccdb6959e6731ed
This commit is contained in:
parent
d5c45dc580
commit
314cc11a45
|
@ -56,9 +56,11 @@ int sdp_audio_codecs_cmp(const struct sdp_audio_codecs *a, const struct sdp_audi
|
|||
bool cmp_fmtp, bool cmp_payload_type);
|
||||
|
||||
struct sdp_audio_codec *sdp_audio_codecs_add(struct sdp_audio_codecs *ac, unsigned int payload_type,
|
||||
const char *subtype_name, unsigned int rate, const char *fmtp);
|
||||
const char *subtype_name, unsigned int rate, const char *fmtp,
|
||||
bool once, bool pick_unused_pt_nr);
|
||||
struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac,
|
||||
const struct sdp_audio_codec *codec);
|
||||
const struct sdp_audio_codec *codec,
|
||||
bool once, bool pick_unused_pt_nr);
|
||||
int sdp_audio_codecs_remove(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec);
|
||||
struct sdp_audio_codec *sdp_audio_codecs_by_payload_type(struct sdp_audio_codecs *ac,
|
||||
unsigned int payload_type, bool create);
|
||||
|
|
|
@ -494,7 +494,7 @@ struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs
|
|||
int i;
|
||||
for (i = 0; i < m->speech_ver_count; i++) {
|
||||
if (m->speech_ver[i] == speech_ver) {
|
||||
ret = sdp_audio_codecs_add_copy(ac, &m->sdp);
|
||||
ret = sdp_audio_codecs_add_copy(ac, &m->sdp, true, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs
|
|||
const struct codec_mapping *m = codec_mapping_by_mgcp_codec(mgcp_codec);
|
||||
if (!m)
|
||||
return NULL;
|
||||
return sdp_audio_codecs_add_copy(ac, &m->sdp);
|
||||
return sdp_audio_codecs_add_copy(ac, &m->sdp, true, true);
|
||||
}
|
||||
|
||||
void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc)
|
||||
|
@ -589,7 +589,7 @@ void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const
|
|||
codec_mapping_foreach (m) {
|
||||
if (!codec_mapping_matches_gsm0808_speech_codec(m, sc))
|
||||
continue;
|
||||
sdp_audio_codecs_add_copy(ac, &m->sdp);
|
||||
sdp_audio_codecs_add_copy(ac, &m->sdp, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,7 +449,7 @@ void rtp_stream_set_mode(struct rtp_stream *rtps, enum mgcp_connection_mode mode
|
|||
void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec)
|
||||
{
|
||||
struct sdp_audio_codecs codecs = {};
|
||||
sdp_audio_codecs_add_copy(&codecs, codec);
|
||||
sdp_audio_codecs_add_copy(&codecs, codec, false, false);
|
||||
rtp_stream_set_codecs(rtps, &codecs);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,51 +119,81 @@ int sdp_audio_codecs_cmp(const struct sdp_audio_codecs *a, const struct sdp_audi
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Given a predefined fixed payload_type number, add an SDP audio codec entry, if not present yet.
|
||||
* The payload_type must exist in sdp_msg_payload_type_names.
|
||||
* Return the audio codec created or already existing for this payload type number.
|
||||
/* Add an SDP audio codec entry.
|
||||
* If 'once' == true, do not add an entry if an identical entry (except for the payload_type number) already exists.
|
||||
* If 'pick_unused_pt_nr' == true, pick an unused PT nr in case 'payload_type' is already taken in 'ac'.
|
||||
* Return the new entry, or NULL if there is no more space in the list.
|
||||
*/
|
||||
struct sdp_audio_codec *sdp_audio_codecs_add(struct sdp_audio_codecs *ac, unsigned int payload_type,
|
||||
const char *subtype_name, unsigned int rate, const char *fmtp)
|
||||
const char *subtype_name, unsigned int rate, const char *fmtp,
|
||||
bool once, bool pick_unused_pt_nr)
|
||||
{
|
||||
struct sdp_audio_codec *codec;
|
||||
|
||||
/* Does an entry already exist? */
|
||||
codec = sdp_audio_codecs_by_payload_type(ac, payload_type, false);
|
||||
if (codec) {
|
||||
/* Already exists, sanity check */
|
||||
if (!codec->subtype_name[0])
|
||||
OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name);
|
||||
else if (strcmp(codec->subtype_name, subtype_name)) {
|
||||
/* There already is an entry with this payload_type number but a mismatching subtype_name. That is
|
||||
* weird, rather abort. */
|
||||
return NULL;
|
||||
}
|
||||
if (codec->rate != rate
|
||||
|| (fmtp && strcmp(fmtp, codec->fmtp))) {
|
||||
/* Mismatching details. Rather abort */
|
||||
return NULL;
|
||||
}
|
||||
return codec;
|
||||
}
|
||||
|
||||
/* None exists, create codec entry for this payload type number */
|
||||
codec = sdp_audio_codecs_by_payload_type(ac, payload_type, true);
|
||||
/* NULL means unable to add an entry */
|
||||
if (!codec)
|
||||
return NULL;
|
||||
|
||||
OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name);
|
||||
if (fmtp)
|
||||
OSMO_STRLCPY_ARRAY(codec->fmtp, fmtp);
|
||||
codec->rate = rate;
|
||||
return codec;
|
||||
struct sdp_audio_codec c = {
|
||||
.payload_type = payload_type,
|
||||
.rate = rate,
|
||||
};
|
||||
OSMO_STRLCPY_ARRAY(c.subtype_name, subtype_name);
|
||||
if (fmtp && *fmtp)
|
||||
OSMO_STRLCPY_ARRAY(c.fmtp, fmtp);
|
||||
return sdp_audio_codecs_add_copy(ac, &c, once, pick_unused_pt_nr);
|
||||
}
|
||||
|
||||
struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec)
|
||||
struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac,
|
||||
const struct sdp_audio_codec *codec,
|
||||
bool once, bool pick_unused_pt_nr)
|
||||
{
|
||||
return sdp_audio_codecs_add(ac, codec->payload_type, codec->subtype_name, codec->rate,
|
||||
codec->fmtp[0] ? codec->fmtp : NULL);
|
||||
struct sdp_audio_codec *new_entry;
|
||||
|
||||
if (once) {
|
||||
struct sdp_audio_codec *exists;
|
||||
exists = sdp_audio_codecs_by_descr(ac, codec);
|
||||
if (exists)
|
||||
return exists;
|
||||
}
|
||||
|
||||
if (ac->count >= ARRAY_SIZE(ac->codec))
|
||||
return NULL;
|
||||
|
||||
/* Compose new_entry in an unused entry, and increment 'count' further below. */
|
||||
new_entry = &ac->codec[ac->count];
|
||||
|
||||
/* Take provided entry as-is. */
|
||||
*new_entry = *codec;
|
||||
|
||||
/* Adjust payload_type number? */
|
||||
if (pick_unused_pt_nr) {
|
||||
const struct sdp_audio_codec *c;
|
||||
bool exists = false;
|
||||
unsigned int existing_pt_max = 96;
|
||||
|
||||
sdp_audio_codecs_foreach(c, ac) {
|
||||
if (c->payload_type == new_entry->payload_type)
|
||||
exists = true;
|
||||
|
||||
existing_pt_max = OSMO_MAX(existing_pt_max, c->payload_type);
|
||||
|
||||
/* For dynamic allocations, skip these predefined numbers, taken from enum mgcp_codecs:
|
||||
* CODEC_GSMEFR_8000_1 = 110, 3GPP TS 48.103 table 5.4.2.2.1
|
||||
* CODEC_GSMHR_8000_1 = 111, 3GPP TS 48.103 table 5.4.2.2.1
|
||||
* CODEC_AMR_8000_1 = 112, 3GPP TS 48.103 table 5.4.2.2.1
|
||||
* CODEC_AMRWB_16000_1 = 113, 3GPP TS 48.103 table 5.4.2.2.1
|
||||
* CODEC_IUFP = 96,
|
||||
* CODEC_CLEARMODE = 120, 3GPP TS 48.103 table 5.4.2.2.1
|
||||
*/
|
||||
if (existing_pt_max >= 110 && existing_pt_max < 113)
|
||||
existing_pt_max = 113;
|
||||
else if (existing_pt_max == 120)
|
||||
existing_pt_max++;
|
||||
}
|
||||
|
||||
if (exists)
|
||||
new_entry->payload_type = existing_pt_max + 1;
|
||||
}
|
||||
|
||||
/* new_entry is complete, increment list count. */
|
||||
ac->count++;
|
||||
|
||||
return new_entry;
|
||||
}
|
||||
|
||||
/* Find or create an entry for the given payload_type number in the given list of codecs.
|
||||
|
|
|
@ -1340,7 +1340,7 @@ static struct sdp_msg *sdp_from_codec_strs(const char *const *codec_strs)
|
|||
BTW("ERROR: unknown codec_str: %s", *codec_str);
|
||||
abort();
|
||||
}
|
||||
if (!sdp_audio_codecs_add_copy(&sdp.audio_codecs, &c)) {
|
||||
if (!sdp_audio_codecs_add_copy(&sdp.audio_codecs, &c, false, false)) {
|
||||
BTW("ERROR: list full, cannot add %s", *codec_str);
|
||||
abort();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue