blob: fd598869901175982989d89d00a282820c265ef1 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11/*
12 * Implementation of the codec database.
13 */
14
15#include "codec_db.h"
16
17#include <string.h> /* to define NULL */
18
19#include "signal_processing_library.h"
20
21#include "neteq_error_codes.h"
22
23/*
24 * Resets the codec database.
25 */
26
27int WebRtcNetEQ_DbReset(CodecDbInst_t *inst)
28{
29 int i;
30
31 WebRtcSpl_MemSetW16((WebRtc_Word16*) inst, 0,
32 sizeof(CodecDbInst_t) / sizeof(WebRtc_Word16));
33
34 for (i = 0; i < NUM_TOTAL_CODECS; i++)
35 {
36 inst->position[i] = -1;
37 }
38
39 for (i = 0; i < NUM_CODECS; i++)
40 {
41 inst->payloadType[i] = -1;
42 }
43
44 for (i = 0; i < NUM_CNG_CODECS; i++)
45 {
46 inst->CNGpayloadType[i] = -1;
47 }
48
49 return 0;
50}
51
52/*
53 * Adds a new codec to the database.
54 */
55
56int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
57 WebRtc_Word16 payloadType, FuncDecode funcDecode,
58 FuncDecode funcDecodeRCU, FuncDecodePLC funcDecodePLC,
59 FuncDecodeInit funcDecodeInit, FuncAddLatePkt funcAddLatePkt,
60 FuncGetMDinfo funcGetMDinfo, FuncGetPitchInfo funcGetPitch,
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +000061 FuncUpdBWEst funcUpdBWEst, FuncDurationEst funcDurationEst,
62 FuncGetErrorCode funcGetErrorCode, void* codec_state,
63 WebRtc_UWord16 codec_fs)
niklase@google.com470e71d2011-07-07 08:21:25 +000064{
65
66 int temp;
67 int insertCNGcodec = 0, overwriteCNGcodec = 0, CNGpos = -1;
68
69#ifndef NETEQ_RED_CODEC
70 if (codec == kDecoderRED)
71 {
72 return CODEC_DB_UNSUPPORTED_CODEC;
73 }
74#endif
75 if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec
76 >= (int) kDecoderReservedEnd))
77 {
78 return CODEC_DB_UNSUPPORTED_CODEC;
79 }
80
81 if ((codec_fs != 8000)
82#ifdef NETEQ_WIDEBAND
83 &&(codec_fs!=16000)
84#endif
85#ifdef NETEQ_32KHZ_WIDEBAND
86 &&(codec_fs!=32000)
87#endif
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +000088#if defined(NETEQ_48KHZ_WIDEBAND) || defined(NETEQ_OPUS_CODEC)
niklase@google.com470e71d2011-07-07 08:21:25 +000089 &&(codec_fs!=48000)
90#endif
91 )
92 {
93 return CODEC_DB_UNSUPPORTED_FS;
94 }
95
96 /* Ensure that the codec type is supported */
97 switch (codec)
98 {
99#ifdef NETEQ_PCM16B_CODEC
100 case kDecoderPCM16B :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000101 case kDecoderPCM16B_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000102#endif
103#ifdef NETEQ_G711_CODEC
104 case kDecoderPCMu :
105 case kDecoderPCMa :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000106 case kDecoderPCMu_2ch :
107 case kDecoderPCMa_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000108#endif
109#ifdef NETEQ_ILBC_CODEC
110 case kDecoderILBC :
111#endif
112#ifdef NETEQ_ISAC_CODEC
113 case kDecoderISAC :
114#endif
115#ifdef NETEQ_ISAC_SWB_CODEC
116 case kDecoderISACswb :
117#endif
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000118#ifdef NETEQ_OPUS_CODEC
119 case kDecoderOpus :
tina.legrand@webrtc.org0ad3c1a2012-11-07 08:07:29 +0000120 case kDecoderOpus_2ch :
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000121#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000122#ifdef NETEQ_G722_CODEC
123 case kDecoderG722 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000124 case kDecoderG722_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000125#endif
126#ifdef NETEQ_WIDEBAND
127 case kDecoderPCM16Bwb :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000128 case kDecoderPCM16Bwb_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000129#endif
130#ifdef NETEQ_32KHZ_WIDEBAND
131 case kDecoderPCM16Bswb32kHz :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000132 case kDecoderPCM16Bswb32kHz_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000133#endif
134#ifdef NETEQ_CNG_CODEC
135 case kDecoderCNG :
136#endif
137#ifdef NETEQ_ATEVENT_DECODE
138 case kDecoderAVT :
139#endif
140#ifdef NETEQ_RED_CODEC
141 case kDecoderRED :
142#endif
143#ifdef NETEQ_48KHZ_WIDEBAND
144 case kDecoderPCM16Bswb48kHz :
145#endif
146#ifdef NETEQ_ARBITRARY_CODEC
147 case kDecoderArbitrary:
148#endif
149#ifdef NETEQ_G729_CODEC
150 case kDecoderG729:
151#endif
152#ifdef NETEQ_G729_1_CODEC
153 case kDecoderG729_1 :
154#endif
155#ifdef NETEQ_G726_CODEC
156 case kDecoderG726_16 :
157 case kDecoderG726_24 :
158 case kDecoderG726_32 :
159 case kDecoderG726_40 :
160#endif
161#ifdef NETEQ_G722_1_CODEC
162 case kDecoderG722_1_16 :
163 case kDecoderG722_1_24 :
164 case kDecoderG722_1_32 :
165#endif
166#ifdef NETEQ_G722_1C_CODEC
167 case kDecoderG722_1C_24 :
168 case kDecoderG722_1C_32 :
169 case kDecoderG722_1C_48 :
170#endif
171#ifdef NETEQ_SPEEX_CODEC
172 case kDecoderSPEEX_8 :
173 case kDecoderSPEEX_16 :
174#endif
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000175#ifdef NETEQ_CELT_CODEC
176 case kDecoderCELT_32 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000177 case kDecoderCELT_32_2ch :
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000178#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000179#ifdef NETEQ_GSMFR_CODEC
180 case kDecoderGSMFR :
181#endif
182#ifdef NETEQ_AMR_CODEC
183 case kDecoderAMR :
184#endif
185#ifdef NETEQ_AMRWB_CODEC
186 case kDecoderAMRWB :
187#endif
188 {
189 /* If we end up here, the inserted codec is supported => Do nothing */
190 break;
191 }
192 default:
193 {
194 /* If we get to this point, the inserted codec is not supported */
195 return CODEC_DB_UNSUPPORTED_CODEC;
196 }
197 }
198
199 /* Check to see if payload type is taken */
200 if (WebRtcNetEQ_DbGetCodec(inst, payloadType) > 0)
201 {
202 return CODEC_DB_PAYLOAD_TAKEN;
203 }
204
205 /* Special case for CNG codecs */
206 if (codec == kDecoderCNG)
207 {
208 /* check if this is first CNG codec to be registered */
209 if (WebRtcNetEQ_DbGetPayload(inst, codec) == CODEC_DB_NOT_EXIST2)
210 {
211 /* no other CNG codec found */
212 insertCNGcodec = 1;
213 }
214
215 /* find the appropriate insert position in CNG payload vector */
216 switch (codec_fs)
217 {
218#ifdef NETEQ_WIDEBAND
219 case 16000:
220 CNGpos = 1;
221 break;
222#endif
223#ifdef NETEQ_32KHZ_WIDEBAND
224 case 32000:
225 CNGpos = 2;
226 break;
227#endif
228#ifdef NETEQ_48KHZ_WIDEBAND
229 case 48000:
230 CNGpos = 3;
231 break;
232#endif
233 default: /* 8000 Hz case */
234 CNGpos = 0;
235 /*
236 * The 8 kHz CNG payload type is the one associated with the regular codec DB
237 * should override any other setting.
238 * Overwrite if this isn't the first CNG
239 */
240 overwriteCNGcodec = !insertCNGcodec;
241 break;
242 }
243
244 /* insert CNG payload type */
245 inst->CNGpayloadType[CNGpos] = payloadType;
246
247 }
248
249 if ((codec != kDecoderCNG) || (insertCNGcodec == 1) || (overwriteCNGcodec == 1))
250 {
251 /* Check if we have reached the maximum numbers of simultaneous codecs */
252 if (inst->nrOfCodecs == NUM_CODECS) return CODEC_DB_FULL;
253
254 /* Check that codec has not already been initialized to DB =>
255 remove it and reinitialize according to new spec */
256 if ((inst->position[codec] != -1) && (overwriteCNGcodec != 1))
257 { /* if registering multiple CNG codecs, don't remove, just overwrite */
258 WebRtcNetEQ_DbRemove(inst, codec);
259 }
260
261 if (overwriteCNGcodec == 1)
262 {
263 temp = inst->position[codec];
264 }
265 else
266 {
267 temp = inst->nrOfCodecs; /* Store this codecs position */
268 inst->position[codec] = temp;
269 inst->nrOfCodecs++;
270 }
271
272 inst->payloadType[temp] = payloadType;
273
274 /* Copy to database */
275 inst->codec_state[temp] = codec_state;
276 inst->funcDecode[temp] = funcDecode;
277 inst->funcDecodeRCU[temp] = funcDecodeRCU;
278 inst->funcAddLatePkt[temp] = funcAddLatePkt;
279 inst->funcDecodeInit[temp] = funcDecodeInit;
280 inst->funcDecodePLC[temp] = funcDecodePLC;
281 inst->funcGetMDinfo[temp] = funcGetMDinfo;
282 inst->funcGetPitch[temp] = funcGetPitch;
283 inst->funcUpdBWEst[temp] = funcUpdBWEst;
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000284 inst->funcDurationEst[temp] = funcDurationEst;
niklase@google.com470e71d2011-07-07 08:21:25 +0000285 inst->funcGetErrorCode[temp] = funcGetErrorCode;
286 inst->codec_fs[temp] = codec_fs;
287
288 }
289
290 return 0;
291}
292
293/*
294 * Removes a codec from the database.
295 */
296
297int WebRtcNetEQ_DbRemove(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec)
298{
299 int i;
300 int pos = -1;
301
302#ifndef NETEQ_RED_CODEC
303 if (codec == kDecoderRED)
304 {
305 return CODEC_DB_UNSUPPORTED_CODEC;
306 }
307#endif
308 if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec
309 >= (int) kDecoderReservedEnd))
310 {
311 return CODEC_DB_UNSUPPORTED_CODEC;
312 }
313
314 pos = inst->position[codec];
315 if (pos == -1)
316 {
317 return CODEC_DB_NOT_EXIST4;
318 }
319 else
320 {
321 /* Remove this codec */
322 inst->position[codec] = -1;
323 for (i = pos; i < (inst->nrOfCodecs - 1); i++)
324 {
325 inst->payloadType[i] = inst->payloadType[i + 1];
326 inst->codec_state[i] = inst->codec_state[i + 1];
327 inst->funcDecode[i] = inst->funcDecode[i + 1];
328 inst->funcDecodeRCU[i] = inst->funcDecodeRCU[i + 1];
329 inst->funcAddLatePkt[i] = inst->funcAddLatePkt[i + 1];
330 inst->funcDecodeInit[i] = inst->funcDecodeInit[i + 1];
331 inst->funcDecodePLC[i] = inst->funcDecodePLC[i + 1];
332 inst->funcGetMDinfo[i] = inst->funcGetMDinfo[i + 1];
333 inst->funcGetPitch[i] = inst->funcGetPitch[i + 1];
334 inst->funcUpdBWEst[i] = inst->funcUpdBWEst[i + 1];
335 inst->funcGetErrorCode[i] = inst->funcGetErrorCode[i + 1];
336 inst->codec_fs[i] = inst->codec_fs[i + 1];
337 }
338 inst->payloadType[i] = -1;
339 inst->codec_state[i] = NULL;
340 inst->funcDecode[i] = NULL;
341 inst->funcDecodeRCU[i] = NULL;
342 inst->funcAddLatePkt[i] = NULL;
343 inst->funcDecodeInit[i] = NULL;
344 inst->funcDecodePLC[i] = NULL;
345 inst->funcGetMDinfo[i] = NULL;
346 inst->funcGetPitch[i] = NULL;
347 inst->funcUpdBWEst[i] = NULL;
348 inst->funcGetErrorCode[i] = NULL;
349 inst->codec_fs[i] = 0;
350 /* Move down all the codecs above this one */
351 for (i = 0; i < NUM_TOTAL_CODECS; i++)
352 {
353 if (inst->position[i] >= pos)
354 {
355 inst->position[i] = inst->position[i] - 1;
356 }
357 }
358 inst->nrOfCodecs--;
359
360 if (codec == kDecoderCNG)
361 {
362 /* also remove all registered CNG payload types */
363 for (i = 0; i < NUM_CNG_CODECS; i++)
364 {
365 inst->CNGpayloadType[i] = -1;
366 }
367 }
368 }
369 return 0;
370}
371
372/*
373 * Get the decoder function pointers for a codec.
374 */
375
376int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
377 CodecFuncInst_t *ptr_inst)
378{
379
380 int pos = inst->position[codec];
381 if ((codec <= kDecoderReservedStart) || (codec >= kDecoderReservedEnd) || (codec
382 > NUM_TOTAL_CODECS))
383 {
384 /* ERROR */
385 pos = -1;
386 }
387 if (pos >= 0)
388 {
389 ptr_inst->codec_state = inst->codec_state[pos];
390 ptr_inst->funcAddLatePkt = inst->funcAddLatePkt[pos];
391 ptr_inst->funcDecode = inst->funcDecode[pos];
392 ptr_inst->funcDecodeRCU = inst->funcDecodeRCU[pos];
393 ptr_inst->funcDecodeInit = inst->funcDecodeInit[pos];
394 ptr_inst->funcDecodePLC = inst->funcDecodePLC[pos];
395 ptr_inst->funcGetMDinfo = inst->funcGetMDinfo[pos];
396 ptr_inst->funcUpdBWEst = inst->funcUpdBWEst[pos];
397 ptr_inst->funcGetErrorCode = inst->funcGetErrorCode[pos];
398 ptr_inst->codec_fs = inst->codec_fs[pos];
399 return 0;
400 }
401 else
402 {
403 WebRtcSpl_MemSetW16((WebRtc_Word16*) ptr_inst, 0,
404 sizeof(CodecFuncInst_t) / sizeof(WebRtc_Word16));
405 return CODEC_DB_NOT_EXIST1;
406 }
407}
408
409/*
410 * Returns payload number given a codec identifier.
411 */
412
413int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecID)
414{
415 if (inst->position[codecID] == -1)
416 return CODEC_DB_NOT_EXIST2;
417 else
418 return (inst->payloadType[inst->position[codecID]]);
419
420}
421
422/*
423 * Returns codec identifier given a payload number.
424 * Returns -1 if the payload type does not exist.
425 */
426
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000427int WebRtcNetEQ_DbGetCodec(const CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000428{
429 int i, pos;
430
431 for (i = 0; i < NUM_TOTAL_CODECS; i++)
432 {
433 pos = inst->position[i];
434 if (pos != -1)
435 {
436 if (inst->payloadType[pos] == payloadType) return i;
437 }
438 }
439
440 /* did not find payload type */
441 /* check if it's a CNG codec */
442 if (WebRtcNetEQ_DbIsCNGPayload(inst, payloadType))
443 {
444 return kDecoderCNG;
445 }
446
447 /* found no match */
448 return CODEC_DB_NOT_EXIST3;
449}
450
451/*
452 * Extracts the Payload Split information of the codec with the specified payloadType.
453 */
454
455int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecID,
456 int codedsize)
457{
458
459 switch (codecID)
460 {
461#ifdef NETEQ_ISAC_CODEC
462 case kDecoderISAC:
463#endif
464#ifdef NETEQ_ISAC_SWB_CODEC
465 case kDecoderISACswb:
466#endif
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000467#ifdef NETEQ_OPUS_CODEC
468 case kDecoderOpus:
tina.legrand@webrtc.org0ad3c1a2012-11-07 08:07:29 +0000469 case kDecoderOpus_2ch :
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000470#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000471#ifdef NETEQ_ARBITRARY_CODEC
472 case kDecoderArbitrary:
473#endif
474#ifdef NETEQ_AMR_CODEC
475 case kDecoderAMR:
476#endif
477#ifdef NETEQ_AMRWB_CODEC
478 case kDecoderAMRWB:
479#endif
480#ifdef NETEQ_G726_CODEC
481 /* Treat G726 as non-splittable to simplify the implementation */
482 case kDecoderG726_16:
483 case kDecoderG726_24:
484 case kDecoderG726_32:
485 case kDecoderG726_40:
486#endif
487#ifdef NETEQ_SPEEX_CODEC
488 case kDecoderSPEEX_8:
489 case kDecoderSPEEX_16:
490#endif
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000491#ifdef NETEQ_CELT_CODEC
492 case kDecoderCELT_32 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000493 case kDecoderCELT_32_2ch :
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000494#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000495#ifdef NETEQ_G729_1_CODEC
496 case kDecoderG729_1:
497#endif
498 {
499 /* These codecs' payloads are not splittable */
500 inst->deltaBytes = NO_SPLIT;
501 return 0;
502 }
503
504 /*
505 * Sample based coders are a special case.
506 * In this case, deltaTime signals the number of bytes per timestamp unit times 2
507 * in log2 domain.
508 */
509#if (defined NETEQ_G711_CODEC)
510 case kDecoderPCMu:
511 case kDecoderPCMa:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000512 case kDecoderPCMu_2ch:
513 case kDecoderPCMa_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000514 {
515 inst->deltaBytes = -12;
516 inst->deltaTime = 1;
517 return 0;
518 }
519#endif
520#if (defined NETEQ_G722_CODEC)
521 case kDecoderG722:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000522 case kDecoderG722_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000523 {
524 inst->deltaBytes = -14;
525 inst->deltaTime = 0;
526 return 0;
527 }
528#endif
529#if (defined NETEQ_PCM16B_CODEC)
530 case kDecoderPCM16B:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000531 case kDecoderPCM16B_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000532 {
533 inst->deltaBytes = -12;
534 inst->deltaTime = 2;
535 return 0;
536 }
537#endif
538#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND))
539 case kDecoderPCM16Bwb:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000540 case kDecoderPCM16Bwb_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 {
542 inst->deltaBytes = -14;
543 inst->deltaTime = 2;
544 return 0;
545 }
546#endif
547#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND))
548 case kDecoderPCM16Bswb32kHz:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000549 case kDecoderPCM16Bswb32kHz_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000550 {
551 inst->deltaBytes = -18;
552 inst->deltaTime = 2;
553 return 0;
554 }
555#endif
556#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_48KHZ_WIDEBAND))
557 case kDecoderPCM16Bswb48kHz:
558 {
559 inst->deltaBytes = -22;
560 inst->deltaTime = 2;
561 return 0;
562 }
563#endif
564
565 /* Splittable payloads */
566#ifdef NETEQ_G722_1_CODEC
567 case kDecoderG722_1_16:
568 {
569 inst->deltaBytes = 40;
570 inst->deltaTime = 320;
571 return 0;
572 }
573 case kDecoderG722_1_24:
574 {
575 inst->deltaBytes = 60;
576 inst->deltaTime = 320;
577 return 0;
578 }
579 case kDecoderG722_1_32:
580 {
581 inst->deltaBytes = 80;
582 inst->deltaTime = 320;
583 return 0;
584 }
585#endif
586#ifdef NETEQ_G722_1C_CODEC
587 case kDecoderG722_1C_24:
588 {
589 inst->deltaBytes = 60;
590 inst->deltaTime = 640;
591 return 0;
592 }
593 case kDecoderG722_1C_32:
594 {
595 inst->deltaBytes = 80;
596 inst->deltaTime = 640;
597 return 0;
598 }
599 case kDecoderG722_1C_48:
600 {
601 inst->deltaBytes = 120;
602 inst->deltaTime = 640;
603 return 0;
604 }
605#endif
606#ifdef NETEQ_G729_CODEC
607 case kDecoderG729:
608 {
609 inst->deltaBytes = 10;
610 inst->deltaTime = 80;
611 return 0;
612 }
613#endif
614#ifdef NETEQ_ILBC_CODEC
615 case kDecoderILBC:
616 {
617 /* Check for splitting of iLBC packets.
618 * If payload size is a multiple of 50 bytes it should be split into 30ms frames.
619 * If payload size is a multiple of 38 bytes it should be split into 20ms frames.
620 * Least common multiplier between 38 and 50 is 950, so the payload size must be less than
621 * 950 bytes in order to resolve the frames unambiguously.
622 * Currently max 12 frames in one bundle.
623 */
624 switch (codedsize)
625 {
626 case 50:
627 case 100:
628 case 150:
629 case 200:
630 case 250:
631 case 300:
632 case 350:
633 case 400:
634 case 450:
635 case 500:
636 case 550:
637 case 600:
638 {
639 inst->deltaBytes = 50;
640 inst->deltaTime = 240;
641 break;
642 }
643 case 38:
644 case 76:
645 case 114:
646 case 152:
647 case 190:
648 case 228:
649 case 266:
650 case 304:
651 case 342:
652 case 380:
653 case 418:
654 case 456:
655 {
656 inst->deltaBytes = 38;
657 inst->deltaTime = 160;
658 break;
659 }
660 default:
661 {
662 return AMBIGUOUS_ILBC_FRAME_SIZE; /* Something not supported... */
663 }
664 }
665 return 0;
666 }
667#endif
668#ifdef NETEQ_GSMFR_CODEC
669 case kDecoderGSMFR:
670 {
671 inst->deltaBytes = 33;
672 inst->deltaTime = 160;
673 return 0;
674 }
675#endif
676 default:
677 { /*Unknown codec */
678 inst->deltaBytes = NO_SPLIT;
679 return CODEC_DB_UNKNOWN_CODEC;
680 }
681 } /* end of switch */
682}
683
684/*
685 * Returns 1 if codec is multiple description, 0 otherwise.
686 * NOTE: This function is a stub, since there currently are no MD codecs.
687 */
688int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID)
689{
690 if (0) /* Add test for MD codecs here */
691 return 1;
692 else
693 return 0;
694}
695
696/*
697 * Returns 1 if payload type is registered as a CNG codec, 0 otherwise
698 */
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000699int WebRtcNetEQ_DbIsCNGPayload(const CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000700{
701#ifdef NETEQ_CNG_CODEC
702 int i;
703
704 for(i=0; i<NUM_CNG_CODECS; i++)
705 {
706 if( (inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType) )
707 {
708 return 1;
709 }
710 }
711#endif
712
713 return 0;
714
715}
716
717/*
718 * Return the sample rate for the codec with the given payload type, 0 if error
719 */
720WebRtc_UWord16 WebRtcNetEQ_DbGetSampleRate(CodecDbInst_t *inst, int payloadType)
721{
722 int i;
723 CodecFuncInst_t codecInst;
724
725 /* Sanity */
726 if (inst == NULL)
727 {
728 /* return 0 Hz */
729 return 0;
730 }
731
732 /* Check among CNG payloads */
733 for (i = 0; i < NUM_CNG_CODECS; i++)
734 {
735 if ((inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType))
736 {
737 switch (i)
738 {
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000739#ifdef NETEQ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000740 case 1:
741 return 16000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000742#endif
743#ifdef NETEQ_32KHZ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000744 case 2:
745 return 32000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000746#endif
747#ifdef NETEQ_48KHZ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000748 case 3:
749 return 48000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000750#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000751 default:
752 return 8000;
753 }
754 }
755 }
756
757 /* Not a CNG payload, check the other payloads */
758 i = WebRtcNetEQ_DbGetCodec(inst, payloadType);
759 if (i >= 0)
760 {
761 if (WebRtcNetEQ_DbGetPtrs(inst, (enum WebRtcNetEQDecoder) i, &codecInst) != 0)
762 {
763 /* Unexpected error, return 0 Hz */
764 return 0;
765 }
766 return codecInst.codec_fs;
767 }
768
769 /* If we end up here, we got an error, return 0 Hz */
770 return 0;
771
772}
773