blob: 8d8389ac0ccfd1c84f384a9087ee7acfe7248670 [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
pbos@webrtc.org0946a562013-04-09 00:28:06 +000031 WebRtcSpl_MemSetW16((int16_t*) inst, 0,
32 sizeof(CodecDbInst_t) / sizeof(int16_t));
niklase@google.com470e71d2011-07-07 08:21:25 +000033
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,
pbos@webrtc.org0946a562013-04-09 00:28:06 +000057 int16_t payloadType, FuncDecode funcDecode,
niklase@google.com470e71d2011-07-07 08:21:25 +000058 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,
pbos@webrtc.org0946a562013-04-09 00:28:06 +000063 uint16_t 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
turaj@webrtc.orgb0dff122012-12-03 17:43:52 +0000118#ifdef NETEQ_ISAC_FB_CODEC
119 case kDecoderISACfb :
120#endif
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000121#ifdef NETEQ_OPUS_CODEC
122 case kDecoderOpus :
123#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000124#ifdef NETEQ_G722_CODEC
125 case kDecoderG722 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000126 case kDecoderG722_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000127#endif
128#ifdef NETEQ_WIDEBAND
129 case kDecoderPCM16Bwb :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000130 case kDecoderPCM16Bwb_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000131#endif
132#ifdef NETEQ_32KHZ_WIDEBAND
133 case kDecoderPCM16Bswb32kHz :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000134 case kDecoderPCM16Bswb32kHz_2ch :
niklase@google.com470e71d2011-07-07 08:21:25 +0000135#endif
136#ifdef NETEQ_CNG_CODEC
137 case kDecoderCNG :
138#endif
139#ifdef NETEQ_ATEVENT_DECODE
140 case kDecoderAVT :
141#endif
142#ifdef NETEQ_RED_CODEC
143 case kDecoderRED :
144#endif
145#ifdef NETEQ_48KHZ_WIDEBAND
146 case kDecoderPCM16Bswb48kHz :
147#endif
148#ifdef NETEQ_ARBITRARY_CODEC
149 case kDecoderArbitrary:
150#endif
151#ifdef NETEQ_G729_CODEC
152 case kDecoderG729:
153#endif
154#ifdef NETEQ_G729_1_CODEC
155 case kDecoderG729_1 :
156#endif
157#ifdef NETEQ_G726_CODEC
158 case kDecoderG726_16 :
159 case kDecoderG726_24 :
160 case kDecoderG726_32 :
161 case kDecoderG726_40 :
162#endif
163#ifdef NETEQ_G722_1_CODEC
164 case kDecoderG722_1_16 :
165 case kDecoderG722_1_24 :
166 case kDecoderG722_1_32 :
167#endif
168#ifdef NETEQ_G722_1C_CODEC
169 case kDecoderG722_1C_24 :
170 case kDecoderG722_1C_32 :
171 case kDecoderG722_1C_48 :
172#endif
173#ifdef NETEQ_SPEEX_CODEC
174 case kDecoderSPEEX_8 :
175 case kDecoderSPEEX_16 :
176#endif
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000177#ifdef NETEQ_CELT_CODEC
178 case kDecoderCELT_32 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000179 case kDecoderCELT_32_2ch :
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000180#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000181#ifdef NETEQ_GSMFR_CODEC
182 case kDecoderGSMFR :
183#endif
184#ifdef NETEQ_AMR_CODEC
185 case kDecoderAMR :
186#endif
187#ifdef NETEQ_AMRWB_CODEC
188 case kDecoderAMRWB :
189#endif
190 {
191 /* If we end up here, the inserted codec is supported => Do nothing */
192 break;
193 }
194 default:
195 {
196 /* If we get to this point, the inserted codec is not supported */
197 return CODEC_DB_UNSUPPORTED_CODEC;
198 }
199 }
200
201 /* Check to see if payload type is taken */
202 if (WebRtcNetEQ_DbGetCodec(inst, payloadType) > 0)
203 {
204 return CODEC_DB_PAYLOAD_TAKEN;
205 }
206
207 /* Special case for CNG codecs */
208 if (codec == kDecoderCNG)
209 {
210 /* check if this is first CNG codec to be registered */
211 if (WebRtcNetEQ_DbGetPayload(inst, codec) == CODEC_DB_NOT_EXIST2)
212 {
213 /* no other CNG codec found */
214 insertCNGcodec = 1;
215 }
216
217 /* find the appropriate insert position in CNG payload vector */
218 switch (codec_fs)
219 {
220#ifdef NETEQ_WIDEBAND
221 case 16000:
222 CNGpos = 1;
223 break;
224#endif
225#ifdef NETEQ_32KHZ_WIDEBAND
226 case 32000:
227 CNGpos = 2;
228 break;
229#endif
230#ifdef NETEQ_48KHZ_WIDEBAND
231 case 48000:
232 CNGpos = 3;
233 break;
234#endif
235 default: /* 8000 Hz case */
236 CNGpos = 0;
237 /*
238 * The 8 kHz CNG payload type is the one associated with the regular codec DB
239 * should override any other setting.
240 * Overwrite if this isn't the first CNG
241 */
242 overwriteCNGcodec = !insertCNGcodec;
243 break;
244 }
245
246 /* insert CNG payload type */
247 inst->CNGpayloadType[CNGpos] = payloadType;
248
249 }
250
251 if ((codec != kDecoderCNG) || (insertCNGcodec == 1) || (overwriteCNGcodec == 1))
252 {
253 /* Check if we have reached the maximum numbers of simultaneous codecs */
254 if (inst->nrOfCodecs == NUM_CODECS) return CODEC_DB_FULL;
255
256 /* Check that codec has not already been initialized to DB =>
257 remove it and reinitialize according to new spec */
258 if ((inst->position[codec] != -1) && (overwriteCNGcodec != 1))
259 { /* if registering multiple CNG codecs, don't remove, just overwrite */
260 WebRtcNetEQ_DbRemove(inst, codec);
261 }
262
263 if (overwriteCNGcodec == 1)
264 {
265 temp = inst->position[codec];
266 }
267 else
268 {
269 temp = inst->nrOfCodecs; /* Store this codecs position */
270 inst->position[codec] = temp;
271 inst->nrOfCodecs++;
272 }
273
274 inst->payloadType[temp] = payloadType;
275
276 /* Copy to database */
277 inst->codec_state[temp] = codec_state;
278 inst->funcDecode[temp] = funcDecode;
279 inst->funcDecodeRCU[temp] = funcDecodeRCU;
280 inst->funcAddLatePkt[temp] = funcAddLatePkt;
281 inst->funcDecodeInit[temp] = funcDecodeInit;
282 inst->funcDecodePLC[temp] = funcDecodePLC;
283 inst->funcGetMDinfo[temp] = funcGetMDinfo;
284 inst->funcGetPitch[temp] = funcGetPitch;
285 inst->funcUpdBWEst[temp] = funcUpdBWEst;
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000286 inst->funcDurationEst[temp] = funcDurationEst;
niklase@google.com470e71d2011-07-07 08:21:25 +0000287 inst->funcGetErrorCode[temp] = funcGetErrorCode;
288 inst->codec_fs[temp] = codec_fs;
289
290 }
291
292 return 0;
293}
294
295/*
296 * Removes a codec from the database.
297 */
298
299int WebRtcNetEQ_DbRemove(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec)
300{
301 int i;
302 int pos = -1;
303
304#ifndef NETEQ_RED_CODEC
305 if (codec == kDecoderRED)
306 {
307 return CODEC_DB_UNSUPPORTED_CODEC;
308 }
309#endif
310 if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec
311 >= (int) kDecoderReservedEnd))
312 {
313 return CODEC_DB_UNSUPPORTED_CODEC;
314 }
315
316 pos = inst->position[codec];
317 if (pos == -1)
318 {
319 return CODEC_DB_NOT_EXIST4;
320 }
321 else
322 {
323 /* Remove this codec */
324 inst->position[codec] = -1;
325 for (i = pos; i < (inst->nrOfCodecs - 1); i++)
326 {
327 inst->payloadType[i] = inst->payloadType[i + 1];
328 inst->codec_state[i] = inst->codec_state[i + 1];
329 inst->funcDecode[i] = inst->funcDecode[i + 1];
330 inst->funcDecodeRCU[i] = inst->funcDecodeRCU[i + 1];
331 inst->funcAddLatePkt[i] = inst->funcAddLatePkt[i + 1];
332 inst->funcDecodeInit[i] = inst->funcDecodeInit[i + 1];
333 inst->funcDecodePLC[i] = inst->funcDecodePLC[i + 1];
334 inst->funcGetMDinfo[i] = inst->funcGetMDinfo[i + 1];
335 inst->funcGetPitch[i] = inst->funcGetPitch[i + 1];
turaj@webrtc.org763faea2013-01-31 18:21:58 +0000336 inst->funcDurationEst[i] = inst->funcDurationEst[i + 1];
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 inst->funcUpdBWEst[i] = inst->funcUpdBWEst[i + 1];
338 inst->funcGetErrorCode[i] = inst->funcGetErrorCode[i + 1];
339 inst->codec_fs[i] = inst->codec_fs[i + 1];
340 }
341 inst->payloadType[i] = -1;
342 inst->codec_state[i] = NULL;
343 inst->funcDecode[i] = NULL;
344 inst->funcDecodeRCU[i] = NULL;
345 inst->funcAddLatePkt[i] = NULL;
346 inst->funcDecodeInit[i] = NULL;
347 inst->funcDecodePLC[i] = NULL;
348 inst->funcGetMDinfo[i] = NULL;
349 inst->funcGetPitch[i] = NULL;
turaj@webrtc.org763faea2013-01-31 18:21:58 +0000350 inst->funcDurationEst[i] = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 inst->funcUpdBWEst[i] = NULL;
352 inst->funcGetErrorCode[i] = NULL;
353 inst->codec_fs[i] = 0;
354 /* Move down all the codecs above this one */
355 for (i = 0; i < NUM_TOTAL_CODECS; i++)
356 {
357 if (inst->position[i] >= pos)
358 {
359 inst->position[i] = inst->position[i] - 1;
360 }
361 }
362 inst->nrOfCodecs--;
363
364 if (codec == kDecoderCNG)
365 {
366 /* also remove all registered CNG payload types */
367 for (i = 0; i < NUM_CNG_CODECS; i++)
368 {
369 inst->CNGpayloadType[i] = -1;
370 }
371 }
372 }
373 return 0;
374}
375
376/*
377 * Get the decoder function pointers for a codec.
378 */
379
380int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
381 CodecFuncInst_t *ptr_inst)
382{
383
384 int pos = inst->position[codec];
385 if ((codec <= kDecoderReservedStart) || (codec >= kDecoderReservedEnd) || (codec
386 > NUM_TOTAL_CODECS))
387 {
388 /* ERROR */
389 pos = -1;
390 }
391 if (pos >= 0)
392 {
393 ptr_inst->codec_state = inst->codec_state[pos];
394 ptr_inst->funcAddLatePkt = inst->funcAddLatePkt[pos];
395 ptr_inst->funcDecode = inst->funcDecode[pos];
396 ptr_inst->funcDecodeRCU = inst->funcDecodeRCU[pos];
397 ptr_inst->funcDecodeInit = inst->funcDecodeInit[pos];
398 ptr_inst->funcDecodePLC = inst->funcDecodePLC[pos];
399 ptr_inst->funcGetMDinfo = inst->funcGetMDinfo[pos];
400 ptr_inst->funcUpdBWEst = inst->funcUpdBWEst[pos];
401 ptr_inst->funcGetErrorCode = inst->funcGetErrorCode[pos];
402 ptr_inst->codec_fs = inst->codec_fs[pos];
403 return 0;
404 }
405 else
406 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000407 WebRtcSpl_MemSetW16((int16_t*) ptr_inst, 0,
408 sizeof(CodecFuncInst_t) / sizeof(int16_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000409 return CODEC_DB_NOT_EXIST1;
410 }
411}
412
413/*
414 * Returns payload number given a codec identifier.
415 */
416
417int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecID)
418{
419 if (inst->position[codecID] == -1)
420 return CODEC_DB_NOT_EXIST2;
421 else
422 return (inst->payloadType[inst->position[codecID]]);
423
424}
425
426/*
427 * Returns codec identifier given a payload number.
428 * Returns -1 if the payload type does not exist.
429 */
430
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000431int WebRtcNetEQ_DbGetCodec(const CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000432{
433 int i, pos;
434
435 for (i = 0; i < NUM_TOTAL_CODECS; i++)
436 {
437 pos = inst->position[i];
438 if (pos != -1)
439 {
440 if (inst->payloadType[pos] == payloadType) return i;
441 }
442 }
443
444 /* did not find payload type */
445 /* check if it's a CNG codec */
446 if (WebRtcNetEQ_DbIsCNGPayload(inst, payloadType))
447 {
448 return kDecoderCNG;
449 }
450
451 /* found no match */
452 return CODEC_DB_NOT_EXIST3;
453}
454
455/*
456 * Extracts the Payload Split information of the codec with the specified payloadType.
457 */
458
459int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecID,
460 int codedsize)
461{
462
463 switch (codecID)
464 {
465#ifdef NETEQ_ISAC_CODEC
466 case kDecoderISAC:
467#endif
468#ifdef NETEQ_ISAC_SWB_CODEC
469 case kDecoderISACswb:
470#endif
turaj@webrtc.orgb0dff122012-12-03 17:43:52 +0000471#ifdef NETEQ_ISAC_FB_CODEC
472 case kDecoderISACfb:
473#endif
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000474#ifdef NETEQ_OPUS_CODEC
475 case kDecoderOpus:
476#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000477#ifdef NETEQ_ARBITRARY_CODEC
478 case kDecoderArbitrary:
479#endif
480#ifdef NETEQ_AMR_CODEC
481 case kDecoderAMR:
482#endif
483#ifdef NETEQ_AMRWB_CODEC
484 case kDecoderAMRWB:
485#endif
486#ifdef NETEQ_G726_CODEC
487 /* Treat G726 as non-splittable to simplify the implementation */
488 case kDecoderG726_16:
489 case kDecoderG726_24:
490 case kDecoderG726_32:
491 case kDecoderG726_40:
492#endif
493#ifdef NETEQ_SPEEX_CODEC
494 case kDecoderSPEEX_8:
495 case kDecoderSPEEX_16:
496#endif
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000497#ifdef NETEQ_CELT_CODEC
498 case kDecoderCELT_32 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000499 case kDecoderCELT_32_2ch :
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000500#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000501#ifdef NETEQ_G729_1_CODEC
502 case kDecoderG729_1:
503#endif
504 {
505 /* These codecs' payloads are not splittable */
506 inst->deltaBytes = NO_SPLIT;
507 return 0;
508 }
509
510 /*
511 * Sample based coders are a special case.
512 * In this case, deltaTime signals the number of bytes per timestamp unit times 2
513 * in log2 domain.
514 */
515#if (defined NETEQ_G711_CODEC)
516 case kDecoderPCMu:
517 case kDecoderPCMa:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000518 case kDecoderPCMu_2ch:
519 case kDecoderPCMa_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000520 {
521 inst->deltaBytes = -12;
522 inst->deltaTime = 1;
523 return 0;
524 }
525#endif
526#if (defined NETEQ_G722_CODEC)
527 case kDecoderG722:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000528 case kDecoderG722_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000529 {
530 inst->deltaBytes = -14;
531 inst->deltaTime = 0;
532 return 0;
533 }
534#endif
535#if (defined NETEQ_PCM16B_CODEC)
536 case kDecoderPCM16B:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000537 case kDecoderPCM16B_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000538 {
539 inst->deltaBytes = -12;
540 inst->deltaTime = 2;
541 return 0;
542 }
543#endif
544#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND))
545 case kDecoderPCM16Bwb:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000546 case kDecoderPCM16Bwb_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 {
548 inst->deltaBytes = -14;
549 inst->deltaTime = 2;
550 return 0;
551 }
552#endif
553#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND))
554 case kDecoderPCM16Bswb32kHz:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000555 case kDecoderPCM16Bswb32kHz_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000556 {
557 inst->deltaBytes = -18;
558 inst->deltaTime = 2;
559 return 0;
560 }
561#endif
562#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_48KHZ_WIDEBAND))
563 case kDecoderPCM16Bswb48kHz:
564 {
565 inst->deltaBytes = -22;
566 inst->deltaTime = 2;
567 return 0;
568 }
569#endif
570
571 /* Splittable payloads */
572#ifdef NETEQ_G722_1_CODEC
573 case kDecoderG722_1_16:
574 {
575 inst->deltaBytes = 40;
576 inst->deltaTime = 320;
577 return 0;
578 }
579 case kDecoderG722_1_24:
580 {
581 inst->deltaBytes = 60;
582 inst->deltaTime = 320;
583 return 0;
584 }
585 case kDecoderG722_1_32:
586 {
587 inst->deltaBytes = 80;
588 inst->deltaTime = 320;
589 return 0;
590 }
591#endif
592#ifdef NETEQ_G722_1C_CODEC
593 case kDecoderG722_1C_24:
594 {
595 inst->deltaBytes = 60;
596 inst->deltaTime = 640;
597 return 0;
598 }
599 case kDecoderG722_1C_32:
600 {
601 inst->deltaBytes = 80;
602 inst->deltaTime = 640;
603 return 0;
604 }
605 case kDecoderG722_1C_48:
606 {
607 inst->deltaBytes = 120;
608 inst->deltaTime = 640;
609 return 0;
610 }
611#endif
612#ifdef NETEQ_G729_CODEC
613 case kDecoderG729:
614 {
615 inst->deltaBytes = 10;
616 inst->deltaTime = 80;
617 return 0;
618 }
619#endif
620#ifdef NETEQ_ILBC_CODEC
621 case kDecoderILBC:
622 {
623 /* Check for splitting of iLBC packets.
624 * If payload size is a multiple of 50 bytes it should be split into 30ms frames.
625 * If payload size is a multiple of 38 bytes it should be split into 20ms frames.
626 * Least common multiplier between 38 and 50 is 950, so the payload size must be less than
627 * 950 bytes in order to resolve the frames unambiguously.
628 * Currently max 12 frames in one bundle.
629 */
630 switch (codedsize)
631 {
632 case 50:
633 case 100:
634 case 150:
635 case 200:
636 case 250:
637 case 300:
638 case 350:
639 case 400:
640 case 450:
641 case 500:
642 case 550:
643 case 600:
644 {
645 inst->deltaBytes = 50;
646 inst->deltaTime = 240;
647 break;
648 }
649 case 38:
650 case 76:
651 case 114:
652 case 152:
653 case 190:
654 case 228:
655 case 266:
656 case 304:
657 case 342:
658 case 380:
659 case 418:
660 case 456:
661 {
662 inst->deltaBytes = 38;
663 inst->deltaTime = 160;
664 break;
665 }
666 default:
667 {
668 return AMBIGUOUS_ILBC_FRAME_SIZE; /* Something not supported... */
669 }
670 }
671 return 0;
672 }
673#endif
674#ifdef NETEQ_GSMFR_CODEC
675 case kDecoderGSMFR:
676 {
677 inst->deltaBytes = 33;
678 inst->deltaTime = 160;
679 return 0;
680 }
681#endif
682 default:
683 { /*Unknown codec */
684 inst->deltaBytes = NO_SPLIT;
685 return CODEC_DB_UNKNOWN_CODEC;
686 }
687 } /* end of switch */
688}
689
690/*
691 * Returns 1 if codec is multiple description, 0 otherwise.
692 * NOTE: This function is a stub, since there currently are no MD codecs.
693 */
694int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID)
695{
696 if (0) /* Add test for MD codecs here */
697 return 1;
698 else
699 return 0;
700}
701
702/*
703 * Returns 1 if payload type is registered as a CNG codec, 0 otherwise
704 */
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000705int WebRtcNetEQ_DbIsCNGPayload(const CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000706{
707#ifdef NETEQ_CNG_CODEC
708 int i;
709
710 for(i=0; i<NUM_CNG_CODECS; i++)
711 {
712 if( (inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType) )
713 {
714 return 1;
715 }
716 }
717#endif
718
719 return 0;
720
721}
722
723/*
724 * Return the sample rate for the codec with the given payload type, 0 if error
725 */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000726uint16_t WebRtcNetEQ_DbGetSampleRate(CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000727{
728 int i;
729 CodecFuncInst_t codecInst;
730
731 /* Sanity */
732 if (inst == NULL)
733 {
734 /* return 0 Hz */
735 return 0;
736 }
737
738 /* Check among CNG payloads */
739 for (i = 0; i < NUM_CNG_CODECS; i++)
740 {
741 if ((inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType))
742 {
743 switch (i)
744 {
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000745#ifdef NETEQ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000746 case 1:
747 return 16000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000748#endif
749#ifdef NETEQ_32KHZ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000750 case 2:
751 return 32000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000752#endif
753#ifdef NETEQ_48KHZ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000754 case 3:
755 return 48000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000756#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000757 default:
758 return 8000;
759 }
760 }
761 }
762
763 /* Not a CNG payload, check the other payloads */
764 i = WebRtcNetEQ_DbGetCodec(inst, payloadType);
765 if (i >= 0)
766 {
767 if (WebRtcNetEQ_DbGetPtrs(inst, (enum WebRtcNetEQDecoder) i, &codecInst) != 0)
768 {
769 /* Unexpected error, return 0 Hz */
770 return 0;
771 }
772 return codecInst.codec_fs;
773 }
774
775 /* If we end up here, we got an error, return 0 Hz */
776 return 0;
777
778}
779