blob: 91c0c383c7c242453ed3d66d6830add2f0362040 [file] [log] [blame]
Jacob Erlbeck239a8532014-03-13 14:25:51 +01001/*
2 * (C) 2014 by Sysmocom s.f.m.c. GmbH
3 * (C) 2014 by On-Waves
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <stdlib.h>
22#include <string.h>
23#include <errno.h>
24
25#include "bscconfig.h"
26
27#include "g711common.h"
28#include <gsm.h>
29#ifdef HAVE_BCG729
30#include <bcg729/decoder.h>
31#include <bcg729/encoder.h>
32#endif
33
34#include <openbsc/debug.h>
35#include <openbsc/mgcp.h>
36#include <openbsc/mgcp_internal.h>
37
38#include <osmocom/core/talloc.h>
39
40enum audio_format {
41 AF_INVALID,
42 AF_S16,
43 AF_L16,
44 AF_GSM,
45 AF_G729,
46 AF_PCMA
47};
48
49struct mgcp_process_rtp_state {
50 /* decoding */
51 enum audio_format src_fmt;
52 union {
53 gsm gsm_handle;
54#ifdef HAVE_BCG729
55 bcg729DecoderChannelContextStruct *g729_dec;
56#endif
57 } src;
58 size_t src_frame_size;
59 size_t src_samples_per_frame;
60
61 /* processing */
62
63 /* encoding */
64 enum audio_format dst_fmt;
65 union {
66 gsm gsm_handle;
67#ifdef HAVE_BCG729
68 bcg729EncoderChannelContextStruct *g729_enc;
69#endif
70 } dst;
71 size_t dst_frame_size;
72 size_t dst_samples_per_frame;
73};
74
Jacob Erlbeck136a3192014-03-13 14:33:37 +010075int mgcp_transcoding_get_frame_size(void *state_, int nsamples, int dst)
76{
77 struct mgcp_process_rtp_state *state = state_;
78 if (dst)
79 return (nsamples >= 0 ?
80 nsamples / state->dst_samples_per_frame :
81 1) * state->dst_frame_size;
82 else
83 return (nsamples >= 0 ?
84 nsamples / state->src_samples_per_frame :
85 1) * state->src_frame_size;
86}
87
Jacob Erlbeck239a8532014-03-13 14:25:51 +010088static enum audio_format get_audio_format(const struct mgcp_rtp_end *rtp_end)
89{
90 if (rtp_end->subtype_name) {
91 if (!strcmp("GSM", rtp_end->subtype_name))
92 return AF_GSM;
93 if (!strcmp("PCMA", rtp_end->subtype_name))
94 return AF_PCMA;
95#ifdef HAVE_BCG729
96 if (!strcmp("G729", rtp_end->subtype_name))
97 return AF_G729;
98#endif
99 if (!strcmp("L16", rtp_end->subtype_name))
100 return AF_L16;
101 }
102
103 switch (rtp_end->payload_type) {
104 case 3 /* GSM */:
105 return AF_GSM;
106 case 8 /* PCMA */:
107 return AF_PCMA;
108#ifdef HAVE_BCG729
109 case 18 /* G.729 */:
110 return AF_G729;
111#endif
112 case 11 /* L16 */:
113 return AF_L16;
114 default:
115 return AF_INVALID;
116 }
117}
118
119static void l16_encode(short *sample, unsigned char *buf, size_t n)
120{
121 for (; n > 0; --n, ++sample, buf += 2) {
122 buf[0] = sample[0] >> 8;
123 buf[1] = sample[0] & 0xff;
124 }
125}
126
127static void l16_decode(unsigned char *buf, short *sample, size_t n)
128{
129 for (; n > 0; --n, ++sample, buf += 2)
130 sample[0] = ((short)buf[0] << 8) | buf[1];
131}
132
133static void alaw_encode(short *sample, unsigned char *buf, size_t n)
134{
135 for (; n > 0; --n)
136 *(buf++) = s16_to_alaw(*(sample++));
137}
138
139static void alaw_decode(unsigned char *buf, short *sample, size_t n)
140{
141 for (; n > 0; --n)
142 *(sample++) = alaw_to_s16(*(buf++));
143}
144
145static int processing_state_destructor(struct mgcp_process_rtp_state *state)
146{
147 switch (state->src_fmt) {
148 case AF_GSM:
149 if (state->dst.gsm_handle)
150 gsm_destroy(state->src.gsm_handle);
151 break;
152#ifdef HAVE_BCG729
153 case AF_G729:
154 if (state->src.g729_dec)
155 closeBcg729DecoderChannel(state->src.g729_dec);
156 break;
157#endif
158 default:
159 break;
160 }
161 switch (state->dst_fmt) {
162 case AF_GSM:
163 if (state->dst.gsm_handle)
164 gsm_destroy(state->dst.gsm_handle);
165 break;
166#ifdef HAVE_BCG729
167 case AF_G729:
168 if (state->dst.g729_enc)
169 closeBcg729EncoderChannel(state->dst.g729_enc);
170 break;
171#endif
172 default:
173 break;
174 }
175 return 0;
176}
177
178int mgcp_transcoding_setup(struct mgcp_endpoint *endp,
179 struct mgcp_rtp_end *dst_end,
180 struct mgcp_rtp_end *src_end)
181{
182 struct mgcp_process_rtp_state *state;
183 enum audio_format src_fmt, dst_fmt;
184
185 /* cleanup first */
186 if (dst_end->rtp_process_data) {
187 talloc_free(dst_end->rtp_process_data);
188 dst_end->rtp_process_data = NULL;
189 }
190
191 if (!src_end)
192 return 0;
193
194 src_fmt = get_audio_format(src_end);
195 dst_fmt = get_audio_format(dst_end);
196
197 LOGP(DMGCP, LOGL_ERROR,
198 "Checking transcoding: %s (%d) -> %s (%d)\n",
199 src_end->subtype_name, src_end->payload_type,
200 dst_end->subtype_name, dst_end->payload_type);
201
202 if (src_fmt == AF_INVALID || dst_fmt == AF_INVALID) {
203 if (!src_end->subtype_name || !dst_end->subtype_name)
204 /* Not enough info, do nothing */
205 return 0;
206
207 if (strcmp(src_end->subtype_name, dst_end->subtype_name) == 0)
208 /* Nothing to do */
209 return 0;
210
211 LOGP(DMGCP, LOGL_ERROR,
212 "Cannot transcode: %s codec not supported (%s -> %s).\n",
213 src_fmt != AF_INVALID ? "destination" : "source",
214 src_end->audio_name, dst_end->audio_name);
215 return -EINVAL;
216 }
217
218 if (src_end->rate && dst_end->rate && src_end->rate != dst_end->rate) {
219 LOGP(DMGCP, LOGL_ERROR,
220 "Cannot transcode: rate conversion (%d -> %d) not supported.\n",
221 src_end->rate, dst_end->rate);
222 return -EINVAL;
223 }
224
225 state = talloc_zero(endp->tcfg->cfg, struct mgcp_process_rtp_state);
226 talloc_set_destructor(state, processing_state_destructor);
227 dst_end->rtp_process_data = state;
228
229 state->src_fmt = src_fmt;
230
231 switch (state->src_fmt) {
232 case AF_L16:
233 case AF_S16:
234 state->src_frame_size = 80 * sizeof(short);
235 state->src_samples_per_frame = 80;
236 break;
237 case AF_GSM:
238 state->src_frame_size = sizeof(gsm_frame);
239 state->src_samples_per_frame = 160;
240 state->src.gsm_handle = gsm_create();
241 if (!state->src.gsm_handle) {
242 LOGP(DMGCP, LOGL_ERROR,
243 "Failed to initialize GSM decoder.\n");
244 return -EINVAL;
245 }
246 break;
247#ifdef HAVE_BCG729
248 case AF_G729:
249 state->src_frame_size = 10;
250 state->src_samples_per_frame = 80;
251 state->src.g729_dec = initBcg729DecoderChannel();
252 if (!state->src.g729_dec) {
253 LOGP(DMGCP, LOGL_ERROR,
254 "Failed to initialize G.729 decoder.\n");
255 return -EINVAL;
256 }
257 break;
258#endif
259 case AF_PCMA:
260 state->src_frame_size = 80;
261 state->src_samples_per_frame = 80;
262 break;
263 default:
264 break;
265 }
266
267 state->dst_fmt = dst_fmt;
268
269 switch (state->dst_fmt) {
270 case AF_L16:
271 case AF_S16:
272 state->dst_frame_size = 80*sizeof(short);
273 state->dst_samples_per_frame = 80;
274 break;
275 case AF_GSM:
276 state->dst_frame_size = sizeof(gsm_frame);
277 state->dst_samples_per_frame = 160;
278 state->dst.gsm_handle = gsm_create();
279 if (!state->dst.gsm_handle) {
280 LOGP(DMGCP, LOGL_ERROR,
281 "Failed to initialize GSM encoder.\n");
282 return -EINVAL;
283 }
284 break;
285#ifdef HAVE_BCG729
286 case AF_G729:
287 state->dst_frame_size = 10;
288 state->dst_samples_per_frame = 80;
289 state->dst.g729_enc = initBcg729EncoderChannel();
290 if (!state->dst.g729_enc) {
291 LOGP(DMGCP, LOGL_ERROR,
292 "Failed to initialize G.729 decoder.\n");
293 return -EINVAL;
294 }
295 break;
296#endif
297 case AF_PCMA:
298 state->dst_frame_size = 80;
299 state->dst_samples_per_frame = 80;
300 break;
301 default:
302 break;
303 }
304
305 LOGP(DMGCP, LOGL_INFO,
306 "Initialized RTP processing on: 0x%x "
307 "conv: %d (%d, %d, %s) -> %d (%d, %d, %s)\n",
308 ENDPOINT_NUMBER(endp),
309 src_fmt, src_end->payload_type, src_end->rate, src_end->fmtp_extra,
310 dst_fmt, dst_end->payload_type, dst_end->rate, dst_end->fmtp_extra);
311
312 return 0;
313}
314
315void mgcp_transcoding_net_downlink_format(struct mgcp_endpoint *endp,
316 int *payload_type,
317 const char**audio_name,
318 const char**fmtp_extra)
319{
320 struct mgcp_process_rtp_state *state = endp->net_end.rtp_process_data;
321 if (!state || endp->net_end.payload_type < 0) {
322 *payload_type = endp->bts_end.payload_type;
323 *audio_name = endp->bts_end.audio_name;
324 *fmtp_extra = endp->bts_end.fmtp_extra;
325 return;
326 }
327
328 *payload_type = endp->net_end.payload_type;
329 *fmtp_extra = endp->net_end.fmtp_extra;
330 *audio_name = endp->net_end.audio_name;
331}
332
333
334int mgcp_transcoding_process_rtp(struct mgcp_endpoint *endp,
335 struct mgcp_rtp_end *dst_end,
336 char *data, int *len, int buf_size)
337{
338 struct mgcp_process_rtp_state *state = dst_end->rtp_process_data;
339 size_t rtp_hdr_size = 12;
340 char *payload_data = data + rtp_hdr_size;
341 int payload_len = *len - rtp_hdr_size;
342 size_t sample_cnt = 0;
343 size_t sample_idx;
344 int16_t samples[10*160];
345 uint8_t *src = (uint8_t *)payload_data;
346 uint8_t *dst = (uint8_t *)payload_data;
347 size_t nbytes = payload_len;
348 size_t frame_remainder;
349
350 if (!state)
351 return 0;
352
353 if (state->src_fmt == state->dst_fmt)
354 return 0;
355
356 /* TODO: check payload type (-> G.711 comfort noise) */
357
358 /* Decode src into samples */
359 while (nbytes >= state->src_frame_size) {
360 if (sample_cnt + state->src_samples_per_frame > ARRAY_SIZE(samples)) {
361 LOGP(DMGCP, LOGL_ERROR,
362 "Sample buffer too small: %d > %d.\n",
363 sample_cnt + state->src_samples_per_frame,
364 ARRAY_SIZE(samples));
365 return -ENOSPC;
366 }
367 switch (state->src_fmt) {
368 case AF_GSM:
369 if (gsm_decode(state->src.gsm_handle,
370 (gsm_byte *)src, samples + sample_cnt) < 0) {
371 LOGP(DMGCP, LOGL_ERROR,
372 "Failed to decode GSM.\n");
373 return -EINVAL;
374 }
375 break;
376#ifdef HAVE_BCG729
377 case AF_G729:
378 bcg729Decoder(state->src.g729_dec, src, 0, samples + sample_cnt);
379 break;
380#endif
381 case AF_PCMA:
382 alaw_decode(src, samples + sample_cnt,
383 state->src_samples_per_frame);
384 break;
385 case AF_S16:
386 memmove(samples + sample_cnt, src,
387 state->src_frame_size);
388 break;
389 case AF_L16:
390 l16_decode(src, samples + sample_cnt,
391 state->src_samples_per_frame);
392 break;
393 default:
394 break;
395 }
396 src += state->src_frame_size;
397 nbytes -= state->src_frame_size;
398 sample_cnt += state->src_samples_per_frame;
399 }
400
401 /* Add silence if necessary */
402 frame_remainder = sample_cnt % state->dst_samples_per_frame;
403 if (frame_remainder) {
404 size_t silence = state->dst_samples_per_frame - frame_remainder;
405 if (sample_cnt + silence > ARRAY_SIZE(samples)) {
406 LOGP(DMGCP, LOGL_ERROR,
407 "Sample buffer too small for silence: %d > %d.\n",
408 sample_cnt + silence,
409 ARRAY_SIZE(samples));
410 return -ENOSPC;
411 }
412
413 while (silence > 0) {
414 samples[sample_cnt] = 0;
415 sample_cnt += 1;
416 silence -= 1;
417 }
418 }
419
420 /* Encode samples into dst */
421 sample_idx = 0;
422 nbytes = 0;
423 while (sample_idx + state->dst_samples_per_frame <= sample_cnt) {
424 if (nbytes + state->dst_frame_size > buf_size) {
425 LOGP(DMGCP, LOGL_ERROR,
426 "Encoding (RTP) buffer too small: %d > %d.\n",
427 nbytes + state->dst_frame_size, buf_size);
428 return -ENOSPC;
429 }
430 switch (state->dst_fmt) {
431 case AF_GSM:
432 gsm_encode(state->dst.gsm_handle,
433 samples + sample_idx, dst);
434 break;
435#ifdef HAVE_BCG729
436 case AF_G729:
437 bcg729Encoder(state->dst.g729_enc,
438 samples + sample_idx, dst);
439 break;
440#endif
441 case AF_PCMA:
442 alaw_encode(samples + sample_idx, dst,
443 state->src_samples_per_frame);
444 break;
445 case AF_S16:
446 memmove(dst, samples + sample_idx, state->dst_frame_size);
447 break;
448 case AF_L16:
449 l16_encode(samples + sample_idx, dst,
450 state->src_samples_per_frame);
451 break;
452 default:
453 break;
454 }
455 dst += state->dst_frame_size;
456 nbytes += state->dst_frame_size;
457 sample_idx += state->dst_samples_per_frame;
458 }
459
460 *len = rtp_hdr_size + nbytes;
461 /* Patch payload type */
462 data[1] = (data[1] & 0x80) | (dst_end->payload_type & 0x7f);
463
464 return 0;
465}