blob: bb34f5e58d3e5fe461e826d7ea4148bc33ff38fd [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 {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000220 case 8000:
221 CNGpos = 0;
222 /*
223 * The 8 kHz CNG payload type is the one associated with the regular codec DB
224 * should override any other setting.
225 * Overwrite if this isn't the first CNG
226 */
227 overwriteCNGcodec = !insertCNGcodec;
228 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000229#ifdef NETEQ_WIDEBAND
230 case 16000:
231 CNGpos = 1;
232 break;
233#endif
234#ifdef NETEQ_32KHZ_WIDEBAND
235 case 32000:
236 CNGpos = 2;
237 break;
238#endif
239#ifdef NETEQ_48KHZ_WIDEBAND
240 case 48000:
241 CNGpos = 3;
242 break;
243#endif
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000244 default:
245 /* If we get to this point, the inserted codec is not supported */
246 return CODEC_DB_UNSUPPORTED_CODEC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000247 }
248
249 /* insert CNG payload type */
250 inst->CNGpayloadType[CNGpos] = payloadType;
251
252 }
253
254 if ((codec != kDecoderCNG) || (insertCNGcodec == 1) || (overwriteCNGcodec == 1))
255 {
256 /* Check if we have reached the maximum numbers of simultaneous codecs */
257 if (inst->nrOfCodecs == NUM_CODECS) return CODEC_DB_FULL;
258
259 /* Check that codec has not already been initialized to DB =>
260 remove it and reinitialize according to new spec */
261 if ((inst->position[codec] != -1) && (overwriteCNGcodec != 1))
262 { /* if registering multiple CNG codecs, don't remove, just overwrite */
263 WebRtcNetEQ_DbRemove(inst, codec);
264 }
265
266 if (overwriteCNGcodec == 1)
267 {
268 temp = inst->position[codec];
269 }
270 else
271 {
272 temp = inst->nrOfCodecs; /* Store this codecs position */
273 inst->position[codec] = temp;
274 inst->nrOfCodecs++;
275 }
276
277 inst->payloadType[temp] = payloadType;
278
279 /* Copy to database */
280 inst->codec_state[temp] = codec_state;
281 inst->funcDecode[temp] = funcDecode;
282 inst->funcDecodeRCU[temp] = funcDecodeRCU;
283 inst->funcAddLatePkt[temp] = funcAddLatePkt;
284 inst->funcDecodeInit[temp] = funcDecodeInit;
285 inst->funcDecodePLC[temp] = funcDecodePLC;
286 inst->funcGetMDinfo[temp] = funcGetMDinfo;
287 inst->funcGetPitch[temp] = funcGetPitch;
288 inst->funcUpdBWEst[temp] = funcUpdBWEst;
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000289 inst->funcDurationEst[temp] = funcDurationEst;
niklase@google.com470e71d2011-07-07 08:21:25 +0000290 inst->funcGetErrorCode[temp] = funcGetErrorCode;
291 inst->codec_fs[temp] = codec_fs;
292
293 }
294
295 return 0;
296}
297
298/*
299 * Removes a codec from the database.
300 */
301
302int WebRtcNetEQ_DbRemove(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec)
303{
304 int i;
305 int pos = -1;
306
307#ifndef NETEQ_RED_CODEC
308 if (codec == kDecoderRED)
309 {
310 return CODEC_DB_UNSUPPORTED_CODEC;
311 }
312#endif
313 if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec
314 >= (int) kDecoderReservedEnd))
315 {
316 return CODEC_DB_UNSUPPORTED_CODEC;
317 }
318
319 pos = inst->position[codec];
320 if (pos == -1)
321 {
322 return CODEC_DB_NOT_EXIST4;
323 }
324 else
325 {
326 /* Remove this codec */
327 inst->position[codec] = -1;
328 for (i = pos; i < (inst->nrOfCodecs - 1); i++)
329 {
330 inst->payloadType[i] = inst->payloadType[i + 1];
331 inst->codec_state[i] = inst->codec_state[i + 1];
332 inst->funcDecode[i] = inst->funcDecode[i + 1];
333 inst->funcDecodeRCU[i] = inst->funcDecodeRCU[i + 1];
334 inst->funcAddLatePkt[i] = inst->funcAddLatePkt[i + 1];
335 inst->funcDecodeInit[i] = inst->funcDecodeInit[i + 1];
336 inst->funcDecodePLC[i] = inst->funcDecodePLC[i + 1];
337 inst->funcGetMDinfo[i] = inst->funcGetMDinfo[i + 1];
338 inst->funcGetPitch[i] = inst->funcGetPitch[i + 1];
turaj@webrtc.org763faea2013-01-31 18:21:58 +0000339 inst->funcDurationEst[i] = inst->funcDurationEst[i + 1];
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 inst->funcUpdBWEst[i] = inst->funcUpdBWEst[i + 1];
341 inst->funcGetErrorCode[i] = inst->funcGetErrorCode[i + 1];
342 inst->codec_fs[i] = inst->codec_fs[i + 1];
343 }
344 inst->payloadType[i] = -1;
345 inst->codec_state[i] = NULL;
346 inst->funcDecode[i] = NULL;
347 inst->funcDecodeRCU[i] = NULL;
348 inst->funcAddLatePkt[i] = NULL;
349 inst->funcDecodeInit[i] = NULL;
350 inst->funcDecodePLC[i] = NULL;
351 inst->funcGetMDinfo[i] = NULL;
352 inst->funcGetPitch[i] = NULL;
turaj@webrtc.org763faea2013-01-31 18:21:58 +0000353 inst->funcDurationEst[i] = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 inst->funcUpdBWEst[i] = NULL;
355 inst->funcGetErrorCode[i] = NULL;
356 inst->codec_fs[i] = 0;
357 /* Move down all the codecs above this one */
358 for (i = 0; i < NUM_TOTAL_CODECS; i++)
359 {
360 if (inst->position[i] >= pos)
361 {
362 inst->position[i] = inst->position[i] - 1;
363 }
364 }
365 inst->nrOfCodecs--;
366
367 if (codec == kDecoderCNG)
368 {
369 /* also remove all registered CNG payload types */
370 for (i = 0; i < NUM_CNG_CODECS; i++)
371 {
372 inst->CNGpayloadType[i] = -1;
373 }
374 }
375 }
376 return 0;
377}
378
379/*
380 * Get the decoder function pointers for a codec.
381 */
382
383int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
384 CodecFuncInst_t *ptr_inst)
385{
386
387 int pos = inst->position[codec];
388 if ((codec <= kDecoderReservedStart) || (codec >= kDecoderReservedEnd) || (codec
389 > NUM_TOTAL_CODECS))
390 {
391 /* ERROR */
392 pos = -1;
393 }
394 if (pos >= 0)
395 {
396 ptr_inst->codec_state = inst->codec_state[pos];
397 ptr_inst->funcAddLatePkt = inst->funcAddLatePkt[pos];
398 ptr_inst->funcDecode = inst->funcDecode[pos];
399 ptr_inst->funcDecodeRCU = inst->funcDecodeRCU[pos];
400 ptr_inst->funcDecodeInit = inst->funcDecodeInit[pos];
401 ptr_inst->funcDecodePLC = inst->funcDecodePLC[pos];
402 ptr_inst->funcGetMDinfo = inst->funcGetMDinfo[pos];
403 ptr_inst->funcUpdBWEst = inst->funcUpdBWEst[pos];
404 ptr_inst->funcGetErrorCode = inst->funcGetErrorCode[pos];
405 ptr_inst->codec_fs = inst->codec_fs[pos];
406 return 0;
407 }
408 else
409 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000410 WebRtcSpl_MemSetW16((int16_t*) ptr_inst, 0,
411 sizeof(CodecFuncInst_t) / sizeof(int16_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 return CODEC_DB_NOT_EXIST1;
413 }
414}
415
416/*
417 * Returns payload number given a codec identifier.
418 */
419
420int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecID)
421{
422 if (inst->position[codecID] == -1)
423 return CODEC_DB_NOT_EXIST2;
424 else
425 return (inst->payloadType[inst->position[codecID]]);
426
427}
428
429/*
430 * Returns codec identifier given a payload number.
431 * Returns -1 if the payload type does not exist.
432 */
433
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000434int WebRtcNetEQ_DbGetCodec(const CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000435{
436 int i, pos;
437
438 for (i = 0; i < NUM_TOTAL_CODECS; i++)
439 {
440 pos = inst->position[i];
441 if (pos != -1)
442 {
443 if (inst->payloadType[pos] == payloadType) return i;
444 }
445 }
446
447 /* did not find payload type */
448 /* check if it's a CNG codec */
449 if (WebRtcNetEQ_DbIsCNGPayload(inst, payloadType))
450 {
451 return kDecoderCNG;
452 }
453
454 /* found no match */
455 return CODEC_DB_NOT_EXIST3;
456}
457
458/*
459 * Extracts the Payload Split information of the codec with the specified payloadType.
460 */
461
462int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecID,
463 int codedsize)
464{
465
466 switch (codecID)
467 {
468#ifdef NETEQ_ISAC_CODEC
469 case kDecoderISAC:
470#endif
471#ifdef NETEQ_ISAC_SWB_CODEC
472 case kDecoderISACswb:
473#endif
turaj@webrtc.orgb0dff122012-12-03 17:43:52 +0000474#ifdef NETEQ_ISAC_FB_CODEC
475 case kDecoderISACfb:
476#endif
tina.legrand@webrtc.orga7d83872012-10-18 10:00:52 +0000477#ifdef NETEQ_OPUS_CODEC
478 case kDecoderOpus:
479#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000480#ifdef NETEQ_ARBITRARY_CODEC
481 case kDecoderArbitrary:
482#endif
483#ifdef NETEQ_AMR_CODEC
484 case kDecoderAMR:
485#endif
486#ifdef NETEQ_AMRWB_CODEC
487 case kDecoderAMRWB:
488#endif
489#ifdef NETEQ_G726_CODEC
490 /* Treat G726 as non-splittable to simplify the implementation */
491 case kDecoderG726_16:
492 case kDecoderG726_24:
493 case kDecoderG726_32:
494 case kDecoderG726_40:
495#endif
496#ifdef NETEQ_SPEEX_CODEC
497 case kDecoderSPEEX_8:
498 case kDecoderSPEEX_16:
499#endif
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000500#ifdef NETEQ_CELT_CODEC
501 case kDecoderCELT_32 :
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000502 case kDecoderCELT_32_2ch :
tina.legrand@webrtc.orgdf697752012-02-08 10:22:21 +0000503#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000504#ifdef NETEQ_G729_1_CODEC
505 case kDecoderG729_1:
506#endif
507 {
508 /* These codecs' payloads are not splittable */
509 inst->deltaBytes = NO_SPLIT;
510 return 0;
511 }
512
513 /*
514 * Sample based coders are a special case.
515 * In this case, deltaTime signals the number of bytes per timestamp unit times 2
516 * in log2 domain.
517 */
518#if (defined NETEQ_G711_CODEC)
519 case kDecoderPCMu:
520 case kDecoderPCMa:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000521 case kDecoderPCMu_2ch:
522 case kDecoderPCMa_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000523 {
524 inst->deltaBytes = -12;
525 inst->deltaTime = 1;
526 return 0;
527 }
528#endif
529#if (defined NETEQ_G722_CODEC)
530 case kDecoderG722:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000531 case kDecoderG722_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000532 {
533 inst->deltaBytes = -14;
534 inst->deltaTime = 0;
535 return 0;
536 }
537#endif
538#if (defined NETEQ_PCM16B_CODEC)
539 case kDecoderPCM16B:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000540 case kDecoderPCM16B_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 {
542 inst->deltaBytes = -12;
543 inst->deltaTime = 2;
544 return 0;
545 }
546#endif
547#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND))
548 case kDecoderPCM16Bwb:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000549 case kDecoderPCM16Bwb_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000550 {
551 inst->deltaBytes = -14;
552 inst->deltaTime = 2;
553 return 0;
554 }
555#endif
556#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND))
557 case kDecoderPCM16Bswb32kHz:
tina.legrand@webrtc.org45175852012-06-01 09:27:35 +0000558 case kDecoderPCM16Bswb32kHz_2ch:
niklase@google.com470e71d2011-07-07 08:21:25 +0000559 {
560 inst->deltaBytes = -18;
561 inst->deltaTime = 2;
562 return 0;
563 }
564#endif
565#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_48KHZ_WIDEBAND))
566 case kDecoderPCM16Bswb48kHz:
567 {
568 inst->deltaBytes = -22;
569 inst->deltaTime = 2;
570 return 0;
571 }
572#endif
573
574 /* Splittable payloads */
575#ifdef NETEQ_G722_1_CODEC
576 case kDecoderG722_1_16:
577 {
578 inst->deltaBytes = 40;
579 inst->deltaTime = 320;
580 return 0;
581 }
582 case kDecoderG722_1_24:
583 {
584 inst->deltaBytes = 60;
585 inst->deltaTime = 320;
586 return 0;
587 }
588 case kDecoderG722_1_32:
589 {
590 inst->deltaBytes = 80;
591 inst->deltaTime = 320;
592 return 0;
593 }
594#endif
595#ifdef NETEQ_G722_1C_CODEC
596 case kDecoderG722_1C_24:
597 {
598 inst->deltaBytes = 60;
599 inst->deltaTime = 640;
600 return 0;
601 }
602 case kDecoderG722_1C_32:
603 {
604 inst->deltaBytes = 80;
605 inst->deltaTime = 640;
606 return 0;
607 }
608 case kDecoderG722_1C_48:
609 {
610 inst->deltaBytes = 120;
611 inst->deltaTime = 640;
612 return 0;
613 }
614#endif
615#ifdef NETEQ_G729_CODEC
616 case kDecoderG729:
617 {
618 inst->deltaBytes = 10;
619 inst->deltaTime = 80;
620 return 0;
621 }
622#endif
623#ifdef NETEQ_ILBC_CODEC
624 case kDecoderILBC:
625 {
626 /* Check for splitting of iLBC packets.
627 * If payload size is a multiple of 50 bytes it should be split into 30ms frames.
628 * If payload size is a multiple of 38 bytes it should be split into 20ms frames.
629 * Least common multiplier between 38 and 50 is 950, so the payload size must be less than
630 * 950 bytes in order to resolve the frames unambiguously.
631 * Currently max 12 frames in one bundle.
632 */
633 switch (codedsize)
634 {
635 case 50:
636 case 100:
637 case 150:
638 case 200:
639 case 250:
640 case 300:
641 case 350:
642 case 400:
643 case 450:
644 case 500:
645 case 550:
646 case 600:
647 {
648 inst->deltaBytes = 50;
649 inst->deltaTime = 240;
650 break;
651 }
652 case 38:
653 case 76:
654 case 114:
655 case 152:
656 case 190:
657 case 228:
658 case 266:
659 case 304:
660 case 342:
661 case 380:
662 case 418:
663 case 456:
664 {
665 inst->deltaBytes = 38;
666 inst->deltaTime = 160;
667 break;
668 }
669 default:
670 {
671 return AMBIGUOUS_ILBC_FRAME_SIZE; /* Something not supported... */
672 }
673 }
674 return 0;
675 }
676#endif
677#ifdef NETEQ_GSMFR_CODEC
678 case kDecoderGSMFR:
679 {
680 inst->deltaBytes = 33;
681 inst->deltaTime = 160;
682 return 0;
683 }
684#endif
685 default:
686 { /*Unknown codec */
687 inst->deltaBytes = NO_SPLIT;
688 return CODEC_DB_UNKNOWN_CODEC;
689 }
690 } /* end of switch */
691}
692
693/*
694 * Returns 1 if codec is multiple description, 0 otherwise.
695 * NOTE: This function is a stub, since there currently are no MD codecs.
696 */
697int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID)
698{
699 if (0) /* Add test for MD codecs here */
700 return 1;
701 else
702 return 0;
703}
704
705/*
706 * Returns 1 if payload type is registered as a CNG codec, 0 otherwise
707 */
tina.legrand@webrtc.org5ac387c2012-11-19 08:02:55 +0000708int WebRtcNetEQ_DbIsCNGPayload(const CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000709{
710#ifdef NETEQ_CNG_CODEC
711 int i;
712
713 for(i=0; i<NUM_CNG_CODECS; i++)
714 {
715 if( (inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType) )
716 {
717 return 1;
718 }
719 }
720#endif
721
722 return 0;
723
724}
725
726/*
727 * Return the sample rate for the codec with the given payload type, 0 if error
728 */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000729uint16_t WebRtcNetEQ_DbGetSampleRate(CodecDbInst_t *inst, int payloadType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000730{
731 int i;
732 CodecFuncInst_t codecInst;
733
734 /* Sanity */
735 if (inst == NULL)
736 {
737 /* return 0 Hz */
738 return 0;
739 }
740
741 /* Check among CNG payloads */
742 for (i = 0; i < NUM_CNG_CODECS; i++)
743 {
744 if ((inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType))
745 {
746 switch (i)
747 {
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000748#ifdef NETEQ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000749 case 1:
750 return 16000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000751#endif
752#ifdef NETEQ_32KHZ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000753 case 2:
754 return 32000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000755#endif
756#ifdef NETEQ_48KHZ_WIDEBAND
niklase@google.com470e71d2011-07-07 08:21:25 +0000757 case 3:
758 return 48000;
henrik.lundin@webrtc.orgf0effa12012-09-11 12:44:06 +0000759#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000760 default:
761 return 8000;
762 }
763 }
764 }
765
766 /* Not a CNG payload, check the other payloads */
767 i = WebRtcNetEQ_DbGetCodec(inst, payloadType);
768 if (i >= 0)
769 {
770 if (WebRtcNetEQ_DbGetPtrs(inst, (enum WebRtcNetEQDecoder) i, &codecInst) != 0)
771 {
772 /* Unexpected error, return 0 Hz */
773 return 0;
774 }
775 return codecInst.codec_fs;
776 }
777
778 /* If we end up here, we got an error, return 0 Hz */
779 return 0;
780
781}
782