blob: 27d72692d783209d794984a96918ef3a0d3f17e4 [file] [log] [blame]
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +02001#include <stdlib.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <string.h>
5#include <err.h>
6
7#include <osmocom/core/talloc.h>
8#include <osmocom/core/application.h>
9
10#include <openbsc/debug.h>
11#include <openbsc/gsm_data.h>
12#include <openbsc/mgcp.h>
13#include <openbsc/mgcp_internal.h>
Holger Hans Peter Freyther91eeeae2014-07-04 20:55:20 +020014#include <openbsc/rtp.h>
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +020015
16#include "bscconfig.h"
17#ifndef BUILD_MGCP_TRANSCODING
18#error "Requires MGCP transcoding enabled (see --enable-mgcp-transcoding)"
19#endif
20
Jacob Erlbeck909fac62014-05-08 14:08:37 +020021#include "openbsc/mgcp_transcode.h"
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +020022
23uint8_t *audio_frame_l16[] = {
24};
25
26struct rtp_packets {
27 float t;
28 int len;
29 char *data;
30};
31
32struct rtp_packets audio_packets_l16[] = {
33 /* RTP: SeqNo=1, TS=160 */
34 {0.020000, 332,
35 "\x80\x0B\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
36 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
37 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
38 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
39 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
40 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
41 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
42 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
43 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
44 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
45 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
46 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
47 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
48 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
49 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
50 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
51 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
52 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
53 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
54 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
55 "\x00\x00\x40\x13\x5A\x9E\x40\x13\x00\x00\xBF\xED\xA5\x62\xBF\xED"
56 },
57};
58
59struct rtp_packets audio_packets_gsm[] = {
60 /* RTP: SeqNo=1, TS=160 */
61 {0.020000, 45,
62 "\x80\x03\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
63 "\xD4\x7C\xE3\xE9\x62\x50\x39\xF0\xF8\xB4\x68\xEA\x6C\x0E\x81\x1B"
64 "\x56\x2A\xD5\xBC\x69\x9C\xD1\xF0\x66\x7A\xEC\x49\x7A\x33\x3D\x0A"
65 "\xDE"
66 },
67};
68
69struct rtp_packets audio_packets_gsm_invalid_size[] = {
70 /* RTP: SeqNo=1, TS=160 */
71 {0.020000, 41,
72 "\x80\x03\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
73 "\xD4\x7C\xE3\xE9\x62\x50\x39\xF0\xF8\xB4\x68\xEA\x6C\x0E\x81\x1B"
74 "\x56\x2A\xD5\xBC\x69\x9C\xD1\xF0\x66\x7A\xEC\x49\x7A\x33\x3D\x0A"
75 "\xDE"
76 },
77};
78
79struct rtp_packets audio_packets_gsm_invalid_data[] = {
80 /* RTP: SeqNo=1, TS=160 */
81 {0.020000, 45,
82 "\x80\x03\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
83 "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
84 "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
85 "\xEE"
86 },
87};
88
89struct rtp_packets audio_packets_gsm_invalid_ptype[] = {
90 /* RTP: SeqNo=1, TS=160 */
91 {0.020000, 45,
92 "\x80\x08\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
93 "\xD4\x7C\xE3\xE9\x62\x50\x39\xF0\xF8\xB4\x68\xEA\x6C\x0E\x81\x1B"
94 "\x56\x2A\xD5\xBC\x69\x9C\xD1\xF0\x66\x7A\xEC\x49\x7A\x33\x3D\x0A"
95 "\xDE"
96 },
97};
98
99struct rtp_packets audio_packets_g729[] = {
100 /* RTP: SeqNo=1, TS=160 */
101 {0.020000, 32,
102 "\x80\x12\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
103 "\xAF\xC2\x81\x40\x00\xFA\xCE\xA4\x21\x7C\xC5\xC3\x4F\xA5\x98\xF5"
104 "\xB2\x95\xC4\xAD"
105 },
106};
107
108struct rtp_packets audio_packets_pcma[] = {
109 /* RTP: SeqNo=1, TS=160 */
110 {0.020000, 172,
111 "\x80\x08\x00\x01\x00\x00\x00\xA0\x11\x22\x33\x44"
112 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
113 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
114 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
115 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
116 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
117 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
118 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
119 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
120 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
121 "\xD5\xA5\xA3\xA5\xD5\x25\x23\x25\xD5\xA5\xA3\xA5\xD5\x25\x23\x25"
122 },
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200123 /* RTP: SeqNo=26527, TS=0 */
124 {0.020000, 92,
125 "\x80\x08\x67\x9f\x00\x00\x00\x00\x04\xaa\x67\x9f\xd5\xd5\xd5\xd5"
126 "\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5"
127 "\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5"
128 "\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5"
129 "\xd5\xd5\xd5\xd5\xd5\xd5\x55\x55\xd5\xd5\x55\x55\xd5\xd5\x55\x55"
130 "\xd5\xd5\xd5\x55\x55\xd5\xd5\xd5\x55\x55\xd5\xd5"
131 },
132 /* RTP: SeqNo=26528, TS=80 */
133 {0.020000, 92,
134 "\x80\x08\x67\xa0\x00\x00\x00\x50\x04\xaa\x67\x9f\x55\xd5\xd5\x55"
135 "\xd5\x55\xd5\xd5\xd5\x55\xd5\x55\xd5\xd5\x55\xd5\x55\xd5\x55\xd5"
136 "\x55\x55\xd5\x55\xd5\xd5\x55\x55\x55\x55\x55\xd5\xd5\x55\xd5\xd5"
137 "\xd5\x55\xd5\xd5\xd5\x55\x54\x55\xd5\xd5\x55\xd5\xd5\xd5\xd5\x55"
138 "\x54\x55\xd5\x55\xd5\x55\x55\x55\x55\x55\xd5\xd5\xd5\xd5\xd5\xd4"
139 "\xd5\x54\x55\xd5\xd4\xd5\x54\xd5\x55\xd5\xd5\xd5"
140 },
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200141};
142
143
144
145static int audio_name_to_type(const char *name)
146{
147 if (!strcasecmp(name, "gsm"))
148 return 3;
149#ifdef HAVE_BCG729
150 else if (!strcasecmp(name, "g729"))
151 return 18;
152#endif
153 else if (!strcasecmp(name, "pcma"))
154 return 8;
155 else if (!strcasecmp(name, "l16"))
156 return 11;
157 return -1;
158}
159
160int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
161
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200162static int given_configured_endpoint(int in_samples, int out_samples,
163 const char *srcfmt, const char *dstfmt,
164 void **out_ctx, struct mgcp_endpoint **out_endp)
165{
166 int rc;
167 struct mgcp_rtp_end *dst_end;
168 struct mgcp_rtp_end *src_end;
169 struct mgcp_config *cfg;
170 struct mgcp_trunk_config *tcfg;
171 struct mgcp_endpoint *endp;
172
173 cfg = mgcp_config_alloc();
174 tcfg = talloc_zero(cfg, struct mgcp_trunk_config);
175 endp = talloc_zero(tcfg, struct mgcp_endpoint);
176
177
178 tcfg->endpoints = endp;
179 tcfg->number_endpoints = 1;
180 tcfg->cfg = cfg;
181 endp->tcfg = tcfg;
182 endp->cfg = cfg;
183 mgcp_free_endp(endp);
184
185 dst_end = &endp->bts_end;
186 dst_end->payload_type = audio_name_to_type(dstfmt);
187
188 src_end = &endp->net_end;
189 src_end->payload_type = audio_name_to_type(srcfmt);
190
191 if (out_samples) {
192 dst_end->frame_duration_den = dst_end->rate;
193 dst_end->frame_duration_num = out_samples;
194 dst_end->frames_per_packet = 1;
195 dst_end->force_output_ptime = 1;
196 }
197
198 rc = mgcp_transcoding_setup(endp, dst_end, src_end);
Holger Hans Peter Freyther6041c8d2014-06-28 13:24:36 +0200199 if (rc < 0) {
200 printf("setup failed: %s", strerror(-rc));
201 abort();
202 }
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200203
204 *out_ctx = cfg;
205 *out_endp = endp;
206 return 0;
207}
208
209
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200210static int transcode_test(const char *srcfmt, const char *dstfmt,
211 uint8_t *src_pkts, size_t src_pkt_size)
212{
213 char buf[4096] = {0x80, 0};
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200214 void *ctx;
215
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200216 struct mgcp_rtp_end *dst_end;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200217 struct mgcp_process_rtp_state *state;
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200218 struct mgcp_endpoint *endp;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200219 int in_size;
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200220 const int in_samples = 160;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200221 int len, cont;
222
223 printf("== Transcoding test ==\n");
224 printf("converting %s -> %s\n", srcfmt, dstfmt);
225
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200226 given_configured_endpoint(in_samples, 0, srcfmt, dstfmt, &ctx, &endp);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200227
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200228 dst_end = &endp->bts_end;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200229 state = dst_end->rtp_process_data;
230 OSMO_ASSERT(state != NULL);
231
232 in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
233 OSMO_ASSERT(sizeof(buf) >= in_size + 12);
234
235 memcpy(buf, src_pkts, src_pkt_size);
236
237 len = src_pkt_size;
238
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200239 cont = mgcp_transcoding_process_rtp(endp, dst_end,
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200240 buf, &len, sizeof(buf));
Holger Hans Peter Freyther6041c8d2014-06-28 13:24:36 +0200241 if (cont < 0) {
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200242 printf("Nothing encoded due: %s\n", strerror(-cont));
243 talloc_free(ctx);
244 return -1;
Holger Hans Peter Freyther6041c8d2014-06-28 13:24:36 +0200245 }
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200246
247 if (len < 24) {
248 printf("encoded: %s\n", osmo_hexdump((unsigned char *)buf, len));
249 } else {
250 const char *str = osmo_hexdump((unsigned char *)buf, len);
251 int i = 0;
252 const int prefix = 4;
253 const int cutlen = 48;
254 int nchars = 0;
255
256 printf("encoded:\n");
257 do {
258 nchars = printf("%*s%-.*s", prefix, "", cutlen, str + i);
259 i += nchars - prefix;
260 printf("\n");
261 } while (nchars - prefix >= cutlen);
262 }
Holger Hans Peter Freyther4fb7e642014-06-28 00:10:10 +0200263 printf("counted: %d\n", cont);
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200264 talloc_free(ctx);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200265 return 0;
266}
267
Holger Hans Peter Freyther91eeeae2014-07-04 20:55:20 +0200268static void test_rtp_seq_state(void)
269{
270 char buf[4096];
271 int len;
272 int cont;
273 void *ctx;
274 struct mgcp_endpoint *endp;
275 struct mgcp_process_rtp_state *state;
276 struct rtp_hdr *hdr;
277 uint32_t ts_no;
278 uint16_t seq_no;
279
280 given_configured_endpoint(160, 0, "pcma", "l16", &ctx, &endp);
281 state = endp->bts_end.rtp_process_data;
282 OSMO_ASSERT(!state->is_running);
283 OSMO_ASSERT(state->next_seq == 0);
284 OSMO_ASSERT(state->next_time == 0);
285
286 /* initialize packet */
287 len = audio_packets_pcma[0].len;
288 memcpy(buf, audio_packets_pcma[0].data, len);
289 cont = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, len);
290 OSMO_ASSERT(cont >= 0);
291 OSMO_ASSERT(state->is_running);
292 OSMO_ASSERT(state->next_seq == 2);
293 OSMO_ASSERT(state->next_time = 240);
294
295 /* verify that the right timestamp was written */
296 OSMO_ASSERT(len == audio_packets_pcma[0].len);
297 hdr = (struct rtp_hdr *) &buf[0];
298
299 memcpy(&ts_no, &hdr->timestamp, sizeof(ts_no));
300 OSMO_ASSERT(htonl(ts_no) == 160);
301 memcpy(&seq_no, &hdr->sequence, sizeof(seq_no));
302 OSMO_ASSERT(htons(seq_no) == 1);
303 /* Check the right sequence number is written */
304 state->next_seq = 1234;
305 len = audio_packets_pcma[0].len;
306 memcpy(buf, audio_packets_pcma[0].data, len);
307 cont = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, len);
308 OSMO_ASSERT(cont >= 0);
309 OSMO_ASSERT(len == audio_packets_pcma[0].len);
310 hdr = (struct rtp_hdr *) &buf[0];
311
312 memcpy(&seq_no, &hdr->sequence, sizeof(seq_no));
313 OSMO_ASSERT(htons(seq_no) == 1234);
314
315 talloc_free(ctx);
316}
317
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200318static void test_transcode_result(void)
319{
320 char buf[4096];
321 int len, res;
322 void *ctx;
323 struct mgcp_endpoint *endp;
324 struct mgcp_process_rtp_state *state;
325
326 {
327 /* from GSM to PCMA and same ptime */
328 given_configured_endpoint(160, 0, "gsm", "pcma", &ctx, &endp);
329 state = endp->bts_end.rtp_process_data;
330
331 /* result */
332 len = audio_packets_gsm[0].len;
333 memcpy(buf, audio_packets_gsm[0].data, len);
334 res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
335 OSMO_ASSERT(res == sizeof(struct rtp_hdr));
336 OSMO_ASSERT(state->sample_cnt == 0);
337
338 len = res;
339 res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
340 OSMO_ASSERT(res == -ENOMSG);
341
342 talloc_free(ctx);
343 }
344
345 {
346 /* from PCMA to GSM and wrong different ptime */
347 given_configured_endpoint(80, 160, "pcma", "gsm", &ctx, &endp);
348 state = endp->bts_end.rtp_process_data;
349
350 /* Add the first sample */
351 len = audio_packets_pcma[1].len;
352 memcpy(buf, audio_packets_pcma[1].data, len);
353 res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
354 OSMO_ASSERT(state->sample_cnt == 80);
355 OSMO_ASSERT(res < 0);
356
357 /* Add the second sample and it should be consumable */
358 len = audio_packets_pcma[2].len;
359 memcpy(buf, audio_packets_pcma[2].data, len);
360 res = mgcp_transcoding_process_rtp(endp, &endp->bts_end, buf, &len, ARRAY_SIZE(buf));
361 OSMO_ASSERT(state->sample_cnt == 0);
362 OSMO_ASSERT(res == sizeof(struct rtp_hdr));
363
364 talloc_free(ctx);
365 }
366}
367
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200368static int test_repacking(int in_samples, int out_samples, int no_transcode)
369{
370 char buf[4096] = {0x80, 0};
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200371 int cc;
372 struct mgcp_endpoint *endp;
373 void *ctx;
374
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200375 struct mgcp_process_rtp_state *state;
376 int in_cnt;
377 int out_size;
378 int in_size;
379 uint32_t ts = 0;
380 uint16_t seq = 0;
381 const char *srcfmt = "pcma";
382 const char *dstfmt = no_transcode ? "pcma" : "l16";
383
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200384 printf("== Transcoding test ==\n");
385 printf("converting %s -> %s\n", srcfmt, dstfmt);
386
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200387 given_configured_endpoint(in_samples, out_samples, srcfmt, dstfmt, &ctx, &endp);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200388
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200389 state = endp->bts_end.rtp_process_data;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200390 OSMO_ASSERT(state != NULL);
391
392 in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
393 OSMO_ASSERT(sizeof(buf) >= in_size + 12);
394
395 out_size = mgcp_transcoding_get_frame_size(state, -1, 1);
396 OSMO_ASSERT(sizeof(buf) >= out_size + 12);
397
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200398 buf[1] = endp->net_end.payload_type;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200399 *(uint16_t*)(buf+2) = htons(1);
400 *(uint32_t*)(buf+4) = htonl(0);
401 *(uint32_t*)(buf+8) = htonl(0xaabbccdd);
402
403 for (in_cnt = 0; in_cnt < 16; in_cnt++) {
404 int cont;
405 int len;
406
407 /* fake PCMA data */
408 printf("generating %d %s input samples\n", in_samples, srcfmt);
409 for (cc = 0; cc < in_samples; cc++)
410 buf[12+cc] = cc;
411
412 *(uint16_t*)(buf+2) = htonl(seq);
413 *(uint32_t*)(buf+4) = htonl(ts);
414
415 seq += 1;
416 ts += in_samples;
417
418 cc += 12; /* include RTP header */
419
420 len = cc;
421
422 do {
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200423 cont = mgcp_transcoding_process_rtp(endp, &endp->bts_end,
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200424 buf, &len, sizeof(buf));
425 if (cont == -EAGAIN) {
426 fprintf(stderr, "Got EAGAIN\n");
427 break;
428 }
429
Holger Hans Peter Freyther6041c8d2014-06-28 13:24:36 +0200430 if (cont < 0) {
431 printf("processing failed: %s", strerror(-cont));
432 abort();
433 }
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200434
435 len -= 12; /* ignore RTP header */
436
Holger Hans Peter Freyther4fb7e642014-06-28 00:10:10 +0200437 printf("got %d %s output frames (%d octets) count=%d\n",
438 len / out_size, dstfmt, len, cont);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200439
440 len = cont;
441 } while (len > 0);
442 }
Holger Hans Peter Freyther83cbac22014-06-22 21:55:50 +0200443
444 talloc_free(ctx);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200445 return 0;
446}
447
448int main(int argc, char **argv)
449{
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200450 int rc;
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200451 osmo_init_logging(&log_info);
452
453 printf("=== Transcoding Good Cases ===\n");
454
455 transcode_test("l16", "l16",
456 (uint8_t *)audio_packets_l16[0].data,
457 audio_packets_l16[0].len);
458 transcode_test("l16", "gsm",
459 (uint8_t *)audio_packets_l16[0].data,
460 audio_packets_l16[0].len);
461 transcode_test("l16", "pcma",
462 (uint8_t *)audio_packets_l16[0].data,
463 audio_packets_l16[0].len);
464 transcode_test("gsm", "l16",
465 (uint8_t *)audio_packets_gsm[0].data,
466 audio_packets_gsm[0].len);
467 transcode_test("gsm", "gsm",
468 (uint8_t *)audio_packets_gsm[0].data,
469 audio_packets_gsm[0].len);
470 transcode_test("gsm", "pcma",
471 (uint8_t *)audio_packets_gsm[0].data,
472 audio_packets_gsm[0].len);
473 transcode_test("pcma", "l16",
474 (uint8_t *)audio_packets_pcma[0].data,
475 audio_packets_pcma[0].len);
476 transcode_test("pcma", "gsm",
477 (uint8_t *)audio_packets_pcma[0].data,
478 audio_packets_pcma[0].len);
479 transcode_test("pcma", "pcma",
480 (uint8_t *)audio_packets_pcma[0].data,
481 audio_packets_pcma[0].len);
482
483 printf("=== Transcoding Bad Cases ===\n");
484
485 printf("Invalid size:\n");
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200486 rc = transcode_test("gsm", "pcma",
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200487 (uint8_t *)audio_packets_gsm_invalid_size[0].data,
488 audio_packets_gsm_invalid_size[0].len);
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200489 OSMO_ASSERT(rc < 0);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200490
491 printf("Invalid data:\n");
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200492 rc = transcode_test("gsm", "pcma",
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200493 (uint8_t *)audio_packets_gsm_invalid_data[0].data,
494 audio_packets_gsm_invalid_data[0].len);
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200495 OSMO_ASSERT(rc < 0);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200496
497 printf("Invalid payload type:\n");
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200498 rc = transcode_test("gsm", "pcma",
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200499 (uint8_t *)audio_packets_gsm_invalid_ptype[0].data,
500 audio_packets_gsm_invalid_ptype[0].len);
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200501 OSMO_ASSERT(rc == 0);
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200502
503 printf("=== Repacking ===\n");
504
505 test_repacking(160, 160, 0);
506 test_repacking(160, 160, 1);
507 test_repacking(160, 80, 0);
508 test_repacking(160, 80, 1);
509 test_repacking(160, 320, 0);
510 test_repacking(160, 320, 1);
511 test_repacking(160, 240, 0);
512 test_repacking(160, 240, 1);
513 test_repacking(160, 100, 0);
514 test_repacking(160, 100, 1);
Holger Hans Peter Freyther91eeeae2014-07-04 20:55:20 +0200515 test_rtp_seq_state();
Holger Hans Peter Freytherbd4109b2014-06-27 19:27:38 +0200516 test_transcode_result();
Jacob Erlbeck84a45cb2014-04-08 16:10:04 +0200517
518 return 0;
519}
520