codecs: Add Codec 2 mode 2400.
[asterisk/asterisk.git] / main / codec_builtin.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2014, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Built-in supported codecs
22  *
23  * \author Joshua Colp <jcolp@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_REGISTER_FILE()
33
34 #include "asterisk/logger.h"
35 #include "asterisk/astobj2.h"
36 #include "asterisk/codec.h"
37 #include "asterisk/format.h"
38 #include "asterisk/format_cache.h"
39 #include "asterisk/frame.h"
40
41 int __ast_codec_register_with_format(struct ast_codec *codec, const char *format_name,
42         struct ast_module *mod);
43
44 enum frame_type {
45         TYPE_HIGH,     /* 0x0 */
46         TYPE_LOW,      /* 0x1 */
47         TYPE_SILENCE,  /* 0x2 */
48         TYPE_DONTSEND  /* 0x3 */
49 };
50
51 #define TYPE_MASK 0x3
52
53 static int g723_len(unsigned char buf)
54 {
55         enum frame_type type = buf & TYPE_MASK;
56
57         switch(type) {
58         case TYPE_DONTSEND:
59                 return 0;
60                 break;
61         case TYPE_SILENCE:
62                 return 4;
63                 break;
64         case TYPE_HIGH:
65                 return 24;
66                 break;
67         case TYPE_LOW:
68                 return 20;
69                 break;
70         default:
71                 ast_log(LOG_WARNING, "Badly encoded frame (%u)\n", type);
72         }
73         return -1;
74 }
75
76 static int g723_samples(struct ast_frame *frame)
77 {
78         unsigned char *buf = frame->data.ptr;
79         int pos = 0, samples = 0, res;
80
81         while(pos < frame->datalen) {
82                 res = g723_len(buf[pos]);
83                 if (res <= 0)
84                         break;
85                 samples += 240;
86                 pos += res;
87         }
88
89         return samples;
90 }
91
92 static int g723_length(unsigned int samples)
93 {
94         return (samples / 240) * 20;
95 }
96
97 static struct ast_codec g723 = {
98         .name = "g723",
99         .description = "G.723.1",
100         .type = AST_MEDIA_TYPE_AUDIO,
101         .sample_rate = 8000,
102         .minimum_ms = 30,
103         .maximum_ms = 300,
104         .default_ms = 30,
105         .minimum_bytes = 20,
106         .samples_count = g723_samples,
107         .get_length = g723_length,
108 };
109
110 static int codec2_samples(struct ast_frame *frame)
111 {
112         return 160 * (frame->datalen / 6);
113 }
114
115 static int codec2_length(unsigned int samples)
116 {
117         return (samples / 160) * 6;
118 }
119
120 static struct ast_codec codec2 = {
121         .name = "codec2",
122         .description = "Codec 2",
123         .type = AST_MEDIA_TYPE_AUDIO,
124         .sample_rate = 8000,
125         .minimum_ms = 20,
126         .maximum_ms = 300,
127         .default_ms = 20,
128         .minimum_bytes = 6,
129         .samples_count = codec2_samples,
130         .get_length = codec2_length,
131         .smooth = 1,
132 };
133
134 static int none_samples(struct ast_frame *frame)
135 {
136         return frame->datalen;
137 }
138
139 static int none_length(unsigned int samples) {
140         return samples;
141 }
142
143 static struct ast_codec none = {
144         .name = "none",
145         .description = "<Null> codec",
146         .type = AST_MEDIA_TYPE_AUDIO,
147         .sample_rate = 8000, /* This must have some sample rate to prevent divide by 0 */
148         .minimum_ms = 10,
149         .maximum_ms = 150,
150         .default_ms = 20,
151         .minimum_bytes = 20,
152         .samples_count = none_samples,
153         .get_length = none_length,
154 };
155
156 static int ulaw_samples(struct ast_frame *frame)
157 {
158         return frame->datalen;
159 }
160
161 static int ulaw_length(unsigned int samples)
162 {
163         return samples;
164 }
165
166 static struct ast_codec ulaw = {
167         .name = "ulaw",
168         .description = "G.711 u-law",
169         .type = AST_MEDIA_TYPE_AUDIO,
170         .sample_rate = 8000,
171         .minimum_ms = 10,
172         .maximum_ms = 150,
173         .default_ms = 20,
174         .minimum_bytes = 80,
175         .samples_count = ulaw_samples,
176         .get_length = ulaw_length,
177         .smooth = 1,
178 };
179
180 static struct ast_codec alaw = {
181         .name = "alaw",
182         .description = "G.711 a-law",
183         .type = AST_MEDIA_TYPE_AUDIO,
184         .sample_rate = 8000,
185         .minimum_ms = 10,
186         .maximum_ms = 150,
187         .default_ms = 20,
188         .minimum_bytes = 80,
189         .samples_count = ulaw_samples,
190         .get_length = ulaw_length,
191         .smooth = 1,
192 };
193
194 static int gsm_samples(struct ast_frame *frame)
195 {
196         return 160 * (frame->datalen / 33);
197 }
198
199 static int gsm_length(unsigned int samples)
200 {
201         return (samples / 160) * 33;
202 }
203
204 static struct ast_codec gsm = {
205         .name = "gsm",
206         .description = "GSM",
207         .type = AST_MEDIA_TYPE_AUDIO,
208         .sample_rate = 8000,
209         .minimum_ms = 20,
210         .maximum_ms = 300,
211         .default_ms = 20,
212         .minimum_bytes = 33,
213         .samples_count = gsm_samples,
214         .get_length = gsm_length,
215         .smooth = 1,
216 };
217
218 static int g726_samples(struct ast_frame *frame)
219 {
220         return frame->datalen * 2;
221 }
222
223 static int g726_length(unsigned int samples)
224 {
225         return samples / 2;
226 }
227
228 static struct ast_codec g726rfc3551 = {
229         .name = "g726",
230         .description = "G.726 RFC3551",
231         .type = AST_MEDIA_TYPE_AUDIO,
232         .sample_rate = 8000,
233         .minimum_ms = 10,
234         .maximum_ms = 300,
235         .default_ms = 20,
236         .minimum_bytes = 40,
237         .samples_count = g726_samples,
238         .get_length = g726_length,
239         .smooth = 1,
240 };
241
242 static struct ast_codec g726aal2 = {
243         .name = "g726aal2",
244         .description = "G.726 AAL2",
245         .type = AST_MEDIA_TYPE_AUDIO,
246         .sample_rate = 8000,
247         .minimum_ms = 10,
248         .maximum_ms = 300,
249         .default_ms = 20,
250         .minimum_bytes = 40,
251         .samples_count = g726_samples,
252         .get_length = g726_length,
253         .smooth = 1,
254 };
255
256 static struct ast_codec adpcm = {
257         .name = "adpcm",
258         .description = "Dialogic ADPCM",
259         .type = AST_MEDIA_TYPE_AUDIO,
260         .sample_rate = 8000,
261         .minimum_ms = 10,
262         .maximum_ms = 300,
263         .default_ms = 20,
264         .minimum_bytes = 40,
265         .samples_count = g726_samples,
266         .get_length = g726_length,
267         .smooth = 1,
268 };
269
270 static int slin_samples(struct ast_frame *frame)
271 {
272         return frame->datalen / 2;
273 }
274
275 static int slin_length(unsigned int samples)
276 {
277         return samples * 2;
278 }
279
280 static struct ast_codec slin8 = {
281         .name = "slin",
282         .description = "16 bit Signed Linear PCM",
283         .type = AST_MEDIA_TYPE_AUDIO,
284         .sample_rate = 8000,
285         .minimum_ms = 10,
286         .maximum_ms = 70,
287         .default_ms = 20,
288         .minimum_bytes = 160,
289         .samples_count = slin_samples,
290         .get_length = slin_length,
291         .smooth = 1,
292 };
293
294 static struct ast_codec slin12 = {
295         .name = "slin",
296         .description = "16 bit Signed Linear PCM (12kHz)",
297         .type = AST_MEDIA_TYPE_AUDIO,
298         .sample_rate = 12000,
299         .minimum_ms = 10,
300         .maximum_ms = 70,
301         .default_ms = 20,
302         .minimum_bytes = 240,
303         .samples_count = slin_samples,
304         .get_length = slin_length,
305         .smooth = 1,
306 };
307
308 static struct ast_codec slin16 = {
309         .name = "slin",
310         .description = "16 bit Signed Linear PCM (16kHz)",
311         .type = AST_MEDIA_TYPE_AUDIO,
312         .sample_rate = 16000,
313         .minimum_ms = 10,
314         .maximum_ms = 70,
315         .default_ms = 20,
316         .minimum_bytes = 320,
317         .samples_count = slin_samples,
318         .get_length = slin_length,
319         .smooth = 1,
320 };
321
322 static struct ast_codec slin24 = {
323         .name = "slin",
324         .description = "16 bit Signed Linear PCM (24kHz)",
325         .type = AST_MEDIA_TYPE_AUDIO,
326         .sample_rate = 24000,
327         .minimum_ms = 10,
328         .maximum_ms = 70,
329         .default_ms = 20,
330         .minimum_bytes = 480,
331         .samples_count = slin_samples,
332         .get_length = slin_length,
333         .smooth = 1,
334 };
335
336 static struct ast_codec slin32 = {
337         .name = "slin",
338         .description = "16 bit Signed Linear PCM (32kHz)",
339         .type = AST_MEDIA_TYPE_AUDIO,
340         .sample_rate = 32000,
341         .minimum_ms = 10,
342         .maximum_ms = 70,
343         .default_ms = 20,
344         .minimum_bytes = 640,
345         .samples_count = slin_samples,
346         .get_length = slin_length,
347         .smooth = 1,
348 };
349
350 static struct ast_codec slin44 = {
351         .name = "slin",
352         .description = "16 bit Signed Linear PCM (44kHz)",
353         .type = AST_MEDIA_TYPE_AUDIO,
354         .sample_rate = 44100,
355         .minimum_ms = 10,
356         .maximum_ms = 70,
357         .default_ms = 20,
358         .minimum_bytes = 882,
359         .samples_count = slin_samples,
360         .get_length = slin_length,
361         .smooth = 1,
362 };
363
364 static struct ast_codec slin48 = {
365         .name = "slin",
366         .description = "16 bit Signed Linear PCM (48kHz)",
367         .type = AST_MEDIA_TYPE_AUDIO,
368         .sample_rate = 48000,
369         .minimum_ms = 10,
370         .maximum_ms = 70,
371         .default_ms = 20,
372         .minimum_bytes = 960,
373         .samples_count = slin_samples,
374         .get_length = slin_length,
375         .smooth = 1,
376 };
377
378 static struct ast_codec slin96 = {
379         .name = "slin",
380         .description = "16 bit Signed Linear PCM (96kHz)",
381         .type = AST_MEDIA_TYPE_AUDIO,
382         .sample_rate = 96000,
383         .minimum_ms = 10,
384         .maximum_ms = 70,
385         .default_ms = 20,
386         .minimum_bytes = 1920,
387         .samples_count = slin_samples,
388         .get_length = slin_length,
389         .smooth = 1,
390 };
391
392 static struct ast_codec slin192 = {
393         .name = "slin",
394         .description = "16 bit Signed Linear PCM (192kHz)",
395         .type = AST_MEDIA_TYPE_AUDIO,
396         .sample_rate = 192000,
397         .minimum_ms = 10,
398         .maximum_ms = 70,
399         .default_ms = 20,
400         .minimum_bytes = 3840,
401         .samples_count = slin_samples,
402         .get_length = slin_length,
403         .smooth = 1,
404 };
405
406 static int lpc10_samples(struct ast_frame *frame)
407 {
408         int samples = 22 * 8;
409
410         /* assumes that the RTP packet contains one LPC10 frame */
411         samples += (((char *)(frame->data.ptr))[7] & 0x1) * 8;
412
413         return samples;
414 }
415
416 static struct ast_codec lpc10 = {
417         .name = "lpc10",
418         .description = "LPC10",
419         .type = AST_MEDIA_TYPE_AUDIO,
420         .sample_rate = 8000,
421         .minimum_ms = 20,
422         .maximum_ms = 20,
423         .default_ms = 20,
424         .minimum_bytes = 7,
425         .samples_count = lpc10_samples,
426         .smooth = 1,
427 };
428
429 static int g729_samples(struct ast_frame *frame)
430 {
431         return frame->datalen * 8;
432 }
433
434 static int g729_length(unsigned int samples)
435 {
436         return samples / 8;
437 }
438
439 static struct ast_codec g729a = {
440         .name = "g729",
441         .description = "G.729A",
442         .type = AST_MEDIA_TYPE_AUDIO,
443         .sample_rate = 8000,
444         .minimum_ms = 10,
445         .maximum_ms = 230,
446         .default_ms = 20,
447         .minimum_bytes = 10,
448         .samples_count = g729_samples,
449         .get_length = g729_length,
450         .smooth = 1,
451 };
452
453 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
454 {
455         int byte = bit / 8;       /* byte containing first bit */
456         int rem = 8 - (bit % 8);  /* remaining bits in first byte */
457         unsigned char ret = 0;
458
459         if (n <= 0 || n > 8)
460                 return 0;
461
462         if (rem < n) {
463                 ret = (data[byte] << (n - rem));
464                 ret |= (data[byte + 1] >> (8 - n + rem));
465         } else {
466                 ret = (data[byte] >> (rem - n));
467         }
468
469         return (ret & (0xff >> (8 - n)));
470 }
471
472 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
473 {
474         static const int SpeexWBSubModeSz[] = {
475                 4, 36, 112, 192,
476                 352, 0, 0, 0 };
477         int off = bit;
478         unsigned char c;
479
480         /* skip up to two wideband frames */
481         if (((len * 8 - off) >= 5) &&
482                 get_n_bits_at(data, 1, off)) {
483                 c = get_n_bits_at(data, 3, off + 1);
484                 off += SpeexWBSubModeSz[c];
485
486                 if (((len * 8 - off) >= 5) &&
487                         get_n_bits_at(data, 1, off)) {
488                         c = get_n_bits_at(data, 3, off + 1);
489                         off += SpeexWBSubModeSz[c];
490
491                         if (((len * 8 - off) >= 5) &&
492                                 get_n_bits_at(data, 1, off)) {
493                                 ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
494                                 return -1;
495                         }
496                 }
497
498         }
499         return off - bit;
500 }
501
502 static int speex_samples(unsigned char *data, int len)
503 {
504         static const int SpeexSubModeSz[] = {
505                 5, 43, 119, 160,
506                 220, 300, 364, 492,
507                 79, 0, 0, 0,
508                 0, 0, 0, 0 };
509         static const int SpeexInBandSz[] = {
510                 1, 1, 4, 4,
511                 4, 4, 4, 4,
512                 8, 8, 16, 16,
513                 32, 32, 64, 64 };
514         int bit = 0;
515         int cnt = 0;
516         int off;
517         unsigned char c;
518
519         while ((len * 8 - bit) >= 5) {
520                 /* skip wideband frames */
521                 off = speex_get_wb_sz_at(data, len, bit);
522                 if (off < 0)  {
523                         ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
524                         break;
525                 }
526                 bit += off;
527
528                 if ((len * 8 - bit) < 5)
529                         break;
530
531                 /* get control bits */
532                 c = get_n_bits_at(data, 5, bit);
533                 bit += 5;
534
535                 if (c == 15) {
536                         /* terminator */
537                         break;
538                 } else if (c == 14) {
539                         /* in-band signal; next 4 bits contain signal id */
540                         c = get_n_bits_at(data, 4, bit);
541                         bit += 4;
542                         bit += SpeexInBandSz[c];
543                 } else if (c == 13) {
544                         /* user in-band; next 4 bits contain msg len */
545                         c = get_n_bits_at(data, 4, bit);
546                         bit += 4;
547                         /* after which it's 5-bit signal id + c bytes of data */
548                         bit += 5 + c * 8;
549                 } else if (c > 8) {
550                         /* unknown */
551                         ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
552                         break;
553                 } else {
554                         /* skip number bits for submode (less the 5 control bits) */
555                         bit += SpeexSubModeSz[c] - 5;
556                         cnt += 160; /* new frame */
557                 }
558         }
559         return cnt;
560 }
561
562 static int speex8_samples(struct ast_frame *frame)
563 {
564         return speex_samples(frame->data.ptr, frame->datalen);
565 }
566
567 static struct ast_codec speex8 = {
568         .name = "speex",
569         .description = "SpeeX",
570         .type = AST_MEDIA_TYPE_AUDIO,
571         .sample_rate = 8000,
572         .minimum_ms = 10,
573         .maximum_ms = 60,
574         .default_ms = 20,
575         .minimum_bytes = 10,
576         .samples_count = speex8_samples,
577 };
578
579 static int speex16_samples(struct ast_frame *frame)
580 {
581         return 2 * speex_samples(frame->data.ptr, frame->datalen);
582 }
583
584 static struct ast_codec speex16 = {
585         .name = "speex",
586         .description = "SpeeX 16khz",
587         .type = AST_MEDIA_TYPE_AUDIO,
588         .sample_rate = 16000,
589         .minimum_ms = 10,
590         .maximum_ms = 60,
591         .default_ms = 20,
592         .minimum_bytes = 10,
593         .samples_count = speex16_samples,
594 };
595
596 static int speex32_samples(struct ast_frame *frame)
597 {
598         return 4 * speex_samples(frame->data.ptr, frame->datalen);
599 }
600
601 static struct ast_codec speex32 = {
602         .name = "speex",
603         .description = "SpeeX 32khz",
604         .type = AST_MEDIA_TYPE_AUDIO,
605         .sample_rate = 32000,
606         .minimum_ms = 10,
607         .maximum_ms = 60,
608         .default_ms = 20,
609         .minimum_bytes = 10,
610         .samples_count = speex32_samples,
611 };
612
613 static int ilbc_samples(struct ast_frame *frame)
614 {
615         return 240 * (frame->datalen / 50);
616 }
617
618 static struct ast_codec ilbc = {
619         .name = "ilbc",
620         .description = "iLBC",
621         .type = AST_MEDIA_TYPE_AUDIO,
622         .sample_rate = 8000,
623         .minimum_ms = 30,
624         .maximum_ms = 300,
625         .default_ms = 30,
626         .minimum_bytes = 50,
627         .samples_count = ilbc_samples,
628         .smooth = 1,
629 };
630
631 static struct ast_codec g722 = {
632         .name = "g722",
633         .description = "G722",
634         .type = AST_MEDIA_TYPE_AUDIO,
635         .sample_rate = 16000,
636         .minimum_ms = 10,
637         .maximum_ms = 150,
638         .default_ms = 20,
639         .minimum_bytes = 80,
640         .samples_count = g726_samples,
641         .get_length = g726_length,
642         .smooth = 1,
643 };
644
645 static int siren7_samples(struct ast_frame *frame)
646 {
647         return frame->datalen * (16000 / 4000);
648 }
649
650 static int siren7_length(unsigned int samples)
651 {
652         return samples / (16000 / 4000);
653 }
654
655 static struct ast_codec siren7 = {
656         .name = "siren7",
657         .description = "ITU G.722.1 (Siren7, licensed from Polycom)",
658         .type = AST_MEDIA_TYPE_AUDIO,
659         .sample_rate = 16000,
660         .minimum_ms = 20,
661         .maximum_ms = 80,
662         .default_ms = 20,
663         .minimum_bytes = 80,
664         .samples_count = siren7_samples,
665         .get_length = siren7_length,
666 };
667
668 static int siren14_samples(struct ast_frame *frame)
669 {
670         return (int) frame->datalen * ((float) 32000 / 6000);
671 }
672
673 static int siren14_length(unsigned int samples)
674 {
675         return (int) samples / ((float) 32000 / 6000);;
676 }
677
678 static struct ast_codec siren14 = {
679         .name = "siren14",
680         .description = "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)",
681         .type = AST_MEDIA_TYPE_AUDIO,
682         .sample_rate = 32000,
683         .minimum_ms = 20,
684         .maximum_ms = 80,
685         .default_ms = 20,
686         .minimum_bytes = 120,
687         .samples_count = siren14_samples,
688         .get_length = siren14_length,
689 };
690
691 static struct ast_codec testlaw = {
692         .name = "testlaw",
693         .description = "G.711 test-law",
694         .type = AST_MEDIA_TYPE_AUDIO,
695         .sample_rate = 8000,
696         .minimum_ms = 10,
697         .maximum_ms = 150,
698         .default_ms = 20,
699         .minimum_bytes = 80,
700         .samples_count = ulaw_samples,
701         .get_length = ulaw_length,
702         .smooth = 1,
703 };
704
705 static int g719_samples(struct ast_frame *frame)
706 {
707         return (int) frame->datalen * ((float) 48000 / 8000);
708 }
709
710 static int g719_length(unsigned int samples)
711 {
712         return (int) samples / ((float) 48000 / 8000);
713 }
714
715 static struct ast_codec g719 = {
716         .name = "g719",
717         .description = "ITU G.719",
718         .type = AST_MEDIA_TYPE_AUDIO,
719         .sample_rate = 48000,
720         .minimum_ms = 20,
721         .maximum_ms = 80,
722         .default_ms = 20,
723         .minimum_bytes = 160,
724         .samples_count = g719_samples,
725         .get_length = g719_length,
726 };
727
728 static struct ast_codec opus = {
729         .name = "opus",
730         .description = "Opus Codec",
731         .type = AST_MEDIA_TYPE_AUDIO,
732         .sample_rate = 48000,
733         .minimum_ms = 20,
734         .maximum_ms = 60,
735         .default_ms = 20,
736         .minimum_bytes = 10,
737 };
738
739 static struct ast_codec jpeg = {
740         .name = "jpeg",
741         .description = "JPEG image",
742         .type = AST_MEDIA_TYPE_IMAGE,
743 };
744
745 static struct ast_codec png = {
746         .name = "png",
747         .description = "PNG Image",
748         .type = AST_MEDIA_TYPE_IMAGE,
749 };
750
751 static struct ast_codec h261 = {
752         .name = "h261",
753         .description = "H.261 video",
754         .type = AST_MEDIA_TYPE_VIDEO,
755 };
756
757 static struct ast_codec h263 = {
758         .name = "h263",
759         .description = "H.263 video",
760         .type = AST_MEDIA_TYPE_VIDEO,
761 };
762
763 static struct ast_codec h263p = {
764         .name = "h263p",
765         .description = "H.263+ video",
766         .type = AST_MEDIA_TYPE_VIDEO,
767 };
768
769 static struct ast_codec h264 = {
770         .name = "h264",
771         .description = "H.264 video",
772         .type = AST_MEDIA_TYPE_VIDEO,
773 };
774
775 static struct ast_codec mpeg4 = {
776         .name = "mpeg4",
777         .description = "MPEG4 video",
778         .type = AST_MEDIA_TYPE_VIDEO,
779 };
780
781 static struct ast_codec vp8 = {
782         .name = "vp8",
783         .description = "VP8 video",
784         .type = AST_MEDIA_TYPE_VIDEO,
785 };
786
787 static struct ast_codec t140red = {
788         .name = "red",
789         .description = "T.140 Realtime Text with redundancy",
790         .type = AST_MEDIA_TYPE_TEXT,
791 };
792
793 static struct ast_codec t140 = {
794         .name = "t140",
795         .description = "Passthrough T.140 Realtime Text",
796         .type = AST_MEDIA_TYPE_TEXT,
797 };
798
799 static int silk_samples(struct ast_frame *frame)
800 {
801         /* XXX This is likely not at all what's intended from this callback. However,
802          * since SILK is variable bit rate, I have no idea how to take a frame of data
803          * and determine the number of samples present. Instead, we base this on the
804          * sample rate of the codec and the expected number of samples to receive in 20ms.
805          * In testing, this has worked just fine.
806          */
807         return ast_format_get_sample_rate(frame->subclass.format) / 50;
808 }
809
810 static struct ast_codec silk8 = {
811         .name = "silk",
812         .description = "SILK Codec (8 KHz)",
813         .type = AST_MEDIA_TYPE_AUDIO,
814         .sample_rate = 8000,
815         .minimum_ms = 20,
816         .maximum_ms = 100,
817         .default_ms = 20,
818         .minimum_bytes = 160,
819         .samples_count = silk_samples
820 };
821
822 static struct ast_codec silk12 = {
823         .name = "silk",
824         .description = "SILK Codec (12 KHz)",
825         .type = AST_MEDIA_TYPE_AUDIO,
826         .sample_rate = 12000,
827         .minimum_ms = 20,
828         .maximum_ms = 100,
829         .default_ms = 20,
830         .minimum_bytes = 240,
831         .samples_count = silk_samples
832 };
833
834 static struct ast_codec silk16 = {
835         .name = "silk",
836         .description = "SILK Codec (16 KHz)",
837         .type = AST_MEDIA_TYPE_AUDIO,
838         .sample_rate = 16000,
839         .minimum_ms = 20,
840         .maximum_ms = 100,
841         .default_ms = 20,
842         .minimum_bytes = 320,
843         .samples_count = silk_samples
844 };
845
846 static struct ast_codec silk24 = {
847         .name = "silk",
848         .description = "SILK Codec (24 KHz)",
849         .type = AST_MEDIA_TYPE_AUDIO,
850         .sample_rate = 24000,
851         .minimum_ms = 20,
852         .maximum_ms = 100,
853         .default_ms = 20,
854         .minimum_bytes = 480,
855         .samples_count = silk_samples
856 };
857
858 #define CODEC_REGISTER_AND_CACHE(codec) \
859         ({ \
860                 int __res_ ## __LINE__ = 0; \
861                 struct ast_format *__fmt_ ## __LINE__; \
862                 struct ast_codec *__codec_ ## __LINE__; \
863                 res |= __ast_codec_register_with_format(&(codec), (codec).name, NULL); \
864                 __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
865                 __fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
866                 res |= ast_format_cache_set(__fmt_ ## __LINE__); \
867                 ao2_ref(__fmt_ ## __LINE__, -1); \
868                 ao2_ref(__codec_ ## __LINE__, -1); \
869                 __res_ ## __LINE__; \
870         })
871
872 #define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
873         ({ \
874                 int __res_ ## __LINE__ = 0; \
875                 struct ast_format *__fmt_ ## __LINE__; \
876                 struct ast_codec *__codec_ ## __LINE__; \
877                 res |= __ast_codec_register_with_format(&(codec), fmt_name, NULL); \
878                 __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
879                 __fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
880                 res |= ast_format_cache_set(__fmt_ ## __LINE__); \
881                 ao2_ref(__fmt_ ## __LINE__, -1); \
882                 ao2_ref(__codec_ ## __LINE__, -1); \
883                 __res_ ## __LINE__; \
884         })
885
886 int ast_codec_builtin_init(void)
887 {
888         int res = 0;
889
890         res |= CODEC_REGISTER_AND_CACHE(codec2);
891         res |= CODEC_REGISTER_AND_CACHE(g723);
892         res |= CODEC_REGISTER_AND_CACHE(ulaw);
893         res |= CODEC_REGISTER_AND_CACHE(alaw);
894         res |= CODEC_REGISTER_AND_CACHE(gsm);
895         res |= CODEC_REGISTER_AND_CACHE(g726rfc3551);
896         res |= CODEC_REGISTER_AND_CACHE(g726aal2);
897         res |= CODEC_REGISTER_AND_CACHE(adpcm);
898         res |= CODEC_REGISTER_AND_CACHE(slin8);
899         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin12", slin12);
900         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin16", slin16);
901         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin24", slin24);
902         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin32", slin32);
903         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin44", slin44);
904         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin48", slin48);
905         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin96", slin96);
906         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin192", slin192);
907         res |= CODEC_REGISTER_AND_CACHE(lpc10);
908         res |= CODEC_REGISTER_AND_CACHE(g729a);
909         res |= CODEC_REGISTER_AND_CACHE(speex8);
910         res |= CODEC_REGISTER_AND_CACHE_NAMED("speex16", speex16);
911         res |= CODEC_REGISTER_AND_CACHE_NAMED("speex32", speex32);
912         res |= CODEC_REGISTER_AND_CACHE(ilbc);
913         res |= CODEC_REGISTER_AND_CACHE(g722);
914         res |= CODEC_REGISTER_AND_CACHE(siren7);
915         res |= CODEC_REGISTER_AND_CACHE(siren14);
916         res |= CODEC_REGISTER_AND_CACHE(testlaw);
917         res |= CODEC_REGISTER_AND_CACHE(g719);
918         res |= CODEC_REGISTER_AND_CACHE(opus);
919         res |= CODEC_REGISTER_AND_CACHE(jpeg);
920         res |= CODEC_REGISTER_AND_CACHE(png);
921         res |= CODEC_REGISTER_AND_CACHE(h261);
922         res |= CODEC_REGISTER_AND_CACHE(h263);
923         res |= CODEC_REGISTER_AND_CACHE(h263p);
924         res |= CODEC_REGISTER_AND_CACHE(h264);
925         res |= CODEC_REGISTER_AND_CACHE(mpeg4);
926         res |= CODEC_REGISTER_AND_CACHE(vp8);
927         res |= CODEC_REGISTER_AND_CACHE(t140red);
928         res |= CODEC_REGISTER_AND_CACHE(t140);
929         res |= CODEC_REGISTER_AND_CACHE(none);
930         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk8", silk8);
931         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk12", silk12);
932         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk16", silk16);
933         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk24", silk24);
934
935         return res;
936 }