fix sdp_audio_codec_to_speech_codec_list() for multiple AMR

Instead of returning multiple occurences of AMR as duplicated
gsm0808_speech_codec_type entries, combine their cfg bits to form a
single entry listing all AMR rate combinations that are allowed.

Prepare for AMR mode-set negotiation: soon we'll have multiple AMR
variants in codec_mapping.c, and then these must produce correct
gsm0808_speech_codec_list.

Change-Id: Ibeffb6c1325abebb904a14f00e6a0818870b119e
This commit is contained in:
Neels Hofmeyr 2024-02-01 05:42:59 +01:00
parent efd374a03e
commit e3059a74f7
1 changed files with 36 additions and 9 deletions

View File

@ -402,16 +402,43 @@ void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct
* sdp_audio_codec, and -ENOSPC when scl is full and nothing could be added. */
int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec)
{
const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
if (!m)
const struct codec_mapping *m;
int added = 0;
int i;
codec_mapping_foreach (m) {
if (sdp_audio_codec_cmp(&m->sdp, codec, true, false))
continue;
if (!m->has_gsm0808_speech_codec)
continue;
/* If there already is an entry for this gsm0808_speech_codec_type, don't add another one. */
for (i = 0; i < scl->len; i++) {
if (scl->codec[i].type == m->gsm0808_speech_codec.type)
break;
}
/* If i is a valid index now, it means this gsm0808_speech_codec_type is already listed. */
if (i < scl->len) {
/* In case of FR3 and HR3 == AMR, bitwise-or the gsm0808_speech_codec.cfg to accumulate Sn.
* The cfg represents a bitmask of Sn bits. codec_mapping.c lists each of these bits separately,
* but on the A-interface, send a combined mask. */
if (m->gsm0808_speech_codec.type == GSM0808_SCT_FR3
|| m->gsm0808_speech_codec.type == GSM0808_SCT_HR3)
scl->codec[i].cfg |= m->gsm0808_speech_codec.cfg;
/* We found and possibly enriched an existing entry. Nothing left to do for this codec. */
continue;
}
/* Not listed yet. Create a new entry. */
if (scl->len >= ARRAY_SIZE(scl->codec))
return -ENOSPC;
scl->codec[scl->len] = m->gsm0808_speech_codec;
scl->len++;
added++;
}
if (!added)
return -ENOENT;
if (!m->has_gsm0808_speech_codec)
return -ENOENT;
if (scl->len >= ARRAY_SIZE(scl->codec))
return -ENOSPC;
scl->codec[scl->len] = m->gsm0808_speech_codec;
/* FIXME: apply AMR configuration according to codec->fmtp */
scl->len++;
return 0;
}