aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/mgcp_transcode.h3
-rw-r--r--openbsc/src/libmgcp/mgcp_sdp.c8
-rw-r--r--openbsc/src/libmgcp/mgcp_transcode.c26
3 files changed, 36 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/mgcp_transcode.h b/openbsc/include/openbsc/mgcp_transcode.h
index cb11cb217..147e48bba 100644
--- a/openbsc/include/openbsc/mgcp_transcode.h
+++ b/openbsc/include/openbsc/mgcp_transcode.h
@@ -33,7 +33,8 @@ enum audio_format {
AF_L16,
AF_GSM,
AF_G729,
- AF_PCMA
+ AF_PCMA,
+ AF_PCMU
};
diff --git a/openbsc/src/libmgcp/mgcp_sdp.c b/openbsc/src/libmgcp/mgcp_sdp.c
index aa4ef3054..b64894496 100644
--- a/openbsc/src/libmgcp/mgcp_sdp.c
+++ b/openbsc/src/libmgcp/mgcp_sdp.c
@@ -54,6 +54,7 @@ int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
if (!audio_name) {
switch (payload_type) {
+ case 0: audio_name = "PCMU/8000/1"; break;
case 3: audio_name = "GSM/8000/1"; break;
case 8: audio_name = "PCMA/8000/1"; break;
case 18: audio_name = "G729/8000/1"; break;
@@ -89,6 +90,8 @@ int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
payload_type = 3;
else if (!strcmp(audio_codec, "PCMA"))
payload_type = 8;
+ else if (!strcmp(audio_codec, "PCMU"))
+ payload_type = 0;
else if (!strcmp(audio_codec, "G729"))
payload_type = 18;
}
@@ -109,6 +112,11 @@ void codecs_initialize(void *ctx, struct sdp_rtp_map *codecs, int used)
for (i = 0; i < used; ++i) {
switch (codecs[i].payload_type) {
+ case 0:
+ codecs[i].codec_name = "PCMU";
+ codecs[i].rate = 8000;
+ codecs[i].channels = 1;
+ break;
case 3:
codecs[i].codec_name = "GSM";
codecs[i].rate = 8000;
diff --git a/openbsc/src/libmgcp/mgcp_transcode.c b/openbsc/src/libmgcp/mgcp_transcode.c
index 12cce2616..c994d3291 100644
--- a/openbsc/src/libmgcp/mgcp_transcode.c
+++ b/openbsc/src/libmgcp/mgcp_transcode.c
@@ -52,6 +52,8 @@ static enum audio_format get_audio_format(const struct mgcp_rtp_codec *codec)
return AF_GSM;
if (!strcasecmp("PCMA", codec->subtype_name))
return AF_PCMA;
+ if (!strcasecmp("PCMU", codec->subtype_name))
+ return AF_PCMU;
#ifdef HAVE_BCG729
if (!strcasecmp("G729", codec->subtype_name))
return AF_G729;
@@ -61,6 +63,8 @@ static enum audio_format get_audio_format(const struct mgcp_rtp_codec *codec)
}
switch (codec->payload_type) {
+ case 0 /* PCMU */:
+ return AF_PCMU;
case 3 /* GSM */:
return AF_GSM;
case 8 /* PCMA */:
@@ -102,6 +106,18 @@ static void alaw_decode(unsigned char *buf, short *sample, size_t n)
*(sample++) = alaw_to_s16(*(buf++));
}
+static void ulaw_encode(short *sample, unsigned char *buf, size_t n)
+{
+ for (; n > 0; --n)
+ *(buf++) = s16_to_ulaw(*(sample++));
+}
+
+static void ulaw_decode(unsigned char *buf, short *sample, size_t n)
+{
+ for (; n > 0; --n)
+ *(sample++) = ulaw_to_s16(*(buf++));
+}
+
static int processing_state_destructor(struct mgcp_process_rtp_state *state)
{
switch (state->src_fmt) {
@@ -226,6 +242,7 @@ int mgcp_transcoding_setup(struct mgcp_endpoint *endp,
}
break;
#endif
+ case AF_PCMU:
case AF_PCMA:
state->src_frame_size = 80;
state->src_samples_per_frame = 80;
@@ -264,6 +281,7 @@ int mgcp_transcoding_setup(struct mgcp_endpoint *endp,
}
break;
#endif
+ case AF_PCMU:
case AF_PCMA:
state->dst_frame_size = 80;
state->dst_samples_per_frame = 80;
@@ -331,6 +349,10 @@ static int decode_audio(struct mgcp_process_rtp_state *state,
bcg729Decoder(state->src.g729_dec, *src, 0, state->samples + state->sample_cnt);
break;
#endif
+ case AF_PCMU:
+ ulaw_decode(*src, state->samples + state->sample_cnt,
+ state->src_samples_per_frame);
+ break;
case AF_PCMA:
alaw_decode(*src, state->samples + state->sample_cnt,
state->src_samples_per_frame);
@@ -381,6 +403,10 @@ static int encode_audio(struct mgcp_process_rtp_state *state,
state->samples + state->sample_offs, dst);
break;
#endif
+ case AF_PCMU:
+ ulaw_encode(state->samples + state->sample_offs, dst,
+ state->src_samples_per_frame);
+ break;
case AF_PCMA:
alaw_encode(state->samples + state->sample_offs, dst,
state->src_samples_per_frame);