CLI: Create ast_cli_completion_add function.
[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 #include "asterisk/ilbc.h"
33 #include "asterisk/logger.h"
34 #include "asterisk/astobj2.h"
35 #include "asterisk/codec.h"
36 #include "asterisk/format.h"
37 #include "asterisk/format_cache.h"
38 #include "asterisk/frame.h"
39 #include "asterisk/smoother.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         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
293 };
294
295 static struct ast_codec slin12 = {
296         .name = "slin",
297         .description = "16 bit Signed Linear PCM (12kHz)",
298         .type = AST_MEDIA_TYPE_AUDIO,
299         .sample_rate = 12000,
300         .minimum_ms = 10,
301         .maximum_ms = 70,
302         .default_ms = 20,
303         .minimum_bytes = 240,
304         .samples_count = slin_samples,
305         .get_length = slin_length,
306         .smooth = 1,
307         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
308 };
309
310 static struct ast_codec slin16 = {
311         .name = "slin",
312         .description = "16 bit Signed Linear PCM (16kHz)",
313         .type = AST_MEDIA_TYPE_AUDIO,
314         .sample_rate = 16000,
315         .minimum_ms = 10,
316         .maximum_ms = 70,
317         .default_ms = 20,
318         .minimum_bytes = 320,
319         .samples_count = slin_samples,
320         .get_length = slin_length,
321         .smooth = 1,
322         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
323 };
324
325 static struct ast_codec slin24 = {
326         .name = "slin",
327         .description = "16 bit Signed Linear PCM (24kHz)",
328         .type = AST_MEDIA_TYPE_AUDIO,
329         .sample_rate = 24000,
330         .minimum_ms = 10,
331         .maximum_ms = 70,
332         .default_ms = 20,
333         .minimum_bytes = 480,
334         .samples_count = slin_samples,
335         .get_length = slin_length,
336         .smooth = 1,
337         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
338 };
339
340 static struct ast_codec slin32 = {
341         .name = "slin",
342         .description = "16 bit Signed Linear PCM (32kHz)",
343         .type = AST_MEDIA_TYPE_AUDIO,
344         .sample_rate = 32000,
345         .minimum_ms = 10,
346         .maximum_ms = 70,
347         .default_ms = 20,
348         .minimum_bytes = 640,
349         .samples_count = slin_samples,
350         .get_length = slin_length,
351         .smooth = 1,
352         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
353 };
354
355 static struct ast_codec slin44 = {
356         .name = "slin",
357         .description = "16 bit Signed Linear PCM (44kHz)",
358         .type = AST_MEDIA_TYPE_AUDIO,
359         .sample_rate = 44100,
360         .minimum_ms = 10,
361         .maximum_ms = 70,
362         .default_ms = 20,
363         .minimum_bytes = 882,
364         .samples_count = slin_samples,
365         .get_length = slin_length,
366         .smooth = 1,
367         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
368 };
369
370 static struct ast_codec slin48 = {
371         .name = "slin",
372         .description = "16 bit Signed Linear PCM (48kHz)",
373         .type = AST_MEDIA_TYPE_AUDIO,
374         .sample_rate = 48000,
375         .minimum_ms = 10,
376         .maximum_ms = 70,
377         .default_ms = 20,
378         .minimum_bytes = 960,
379         .samples_count = slin_samples,
380         .get_length = slin_length,
381         .smooth = 1,
382         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
383 };
384
385 static struct ast_codec slin96 = {
386         .name = "slin",
387         .description = "16 bit Signed Linear PCM (96kHz)",
388         .type = AST_MEDIA_TYPE_AUDIO,
389         .sample_rate = 96000,
390         .minimum_ms = 10,
391         .maximum_ms = 70,
392         .default_ms = 20,
393         .minimum_bytes = 1920,
394         .samples_count = slin_samples,
395         .get_length = slin_length,
396         .smooth = 1,
397         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
398 };
399
400 static struct ast_codec slin192 = {
401         .name = "slin",
402         .description = "16 bit Signed Linear PCM (192kHz)",
403         .type = AST_MEDIA_TYPE_AUDIO,
404         .sample_rate = 192000,
405         .minimum_ms = 10,
406         .maximum_ms = 70,
407         .default_ms = 20,
408         .minimum_bytes = 3840,
409         .samples_count = slin_samples,
410         .get_length = slin_length,
411         .smooth = 1,
412         .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
413 };
414
415 static int lpc10_samples(struct ast_frame *frame)
416 {
417         int samples = 22 * 8;
418
419         /* assumes that the RTP packet contains one LPC10 frame */
420         samples += (((char *)(frame->data.ptr))[7] & 0x1) * 8;
421
422         return samples;
423 }
424
425 static struct ast_codec lpc10 = {
426         .name = "lpc10",
427         .description = "LPC10",
428         .type = AST_MEDIA_TYPE_AUDIO,
429         .sample_rate = 8000,
430         .minimum_ms = 20,
431         .maximum_ms = 20,
432         .default_ms = 20,
433         .minimum_bytes = 7,
434         .samples_count = lpc10_samples,
435         .smooth = 1,
436 };
437
438 static int g729_samples(struct ast_frame *frame)
439 {
440         return frame->datalen * 8;
441 }
442
443 static int g729_length(unsigned int samples)
444 {
445         return samples / 8;
446 }
447
448 static struct ast_codec g729a = {
449         .name = "g729",
450         .description = "G.729A",
451         .type = AST_MEDIA_TYPE_AUDIO,
452         .sample_rate = 8000,
453         .minimum_ms = 10,
454         .maximum_ms = 230,
455         .default_ms = 20,
456         .minimum_bytes = 10,
457         .samples_count = g729_samples,
458         .get_length = g729_length,
459         .smooth = 1,
460 };
461
462 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
463 {
464         int byte = bit / 8;       /* byte containing first bit */
465         int rem = 8 - (bit % 8);  /* remaining bits in first byte */
466         unsigned char ret = 0;
467
468         if (n <= 0 || n > 8)
469                 return 0;
470
471         if (rem < n) {
472                 ret = (data[byte] << (n - rem));
473                 ret |= (data[byte + 1] >> (8 - n + rem));
474         } else {
475                 ret = (data[byte] >> (rem - n));
476         }
477
478         return (ret & (0xff >> (8 - n)));
479 }
480
481 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
482 {
483         static const int SpeexWBSubModeSz[] = {
484                 4, 36, 112, 192,
485                 352, 0, 0, 0 };
486         int off = bit;
487         unsigned char c;
488
489         /* skip up to two wideband frames */
490         if (((len * 8 - off) >= 5) &&
491                 get_n_bits_at(data, 1, off)) {
492                 c = get_n_bits_at(data, 3, off + 1);
493                 off += SpeexWBSubModeSz[c];
494
495                 if (((len * 8 - off) >= 5) &&
496                         get_n_bits_at(data, 1, off)) {
497                         c = get_n_bits_at(data, 3, off + 1);
498                         off += SpeexWBSubModeSz[c];
499
500                         if (((len * 8 - off) >= 5) &&
501                                 get_n_bits_at(data, 1, off)) {
502                                 ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
503                                 return -1;
504                         }
505                 }
506
507         }
508         return off - bit;
509 }
510
511 static int speex_samples(unsigned char *data, int len)
512 {
513         static const int SpeexSubModeSz[] = {
514                 5, 43, 119, 160,
515                 220, 300, 364, 492,
516                 79, 0, 0, 0,
517                 0, 0, 0, 0 };
518         static const int SpeexInBandSz[] = {
519                 1, 1, 4, 4,
520                 4, 4, 4, 4,
521                 8, 8, 16, 16,
522                 32, 32, 64, 64 };
523         int bit = 0;
524         int cnt = 0;
525         int off;
526         unsigned char c;
527
528         while ((len * 8 - bit) >= 5) {
529                 /* skip wideband frames */
530                 off = speex_get_wb_sz_at(data, len, bit);
531                 if (off < 0)  {
532                         ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
533                         break;
534                 }
535                 bit += off;
536
537                 if ((len * 8 - bit) < 5)
538                         break;
539
540                 /* get control bits */
541                 c = get_n_bits_at(data, 5, bit);
542                 bit += 5;
543
544                 if (c == 15) {
545                         /* terminator */
546                         break;
547                 } else if (c == 14) {
548                         /* in-band signal; next 4 bits contain signal id */
549                         c = get_n_bits_at(data, 4, bit);
550                         bit += 4;
551                         bit += SpeexInBandSz[c];
552                 } else if (c == 13) {
553                         /* user in-band; next 4 bits contain msg len */
554                         c = get_n_bits_at(data, 4, bit);
555                         bit += 4;
556                         /* after which it's 5-bit signal id + c bytes of data */
557                         bit += 5 + c * 8;
558                 } else if (c > 8) {
559                         /* unknown */
560                         ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
561                         break;
562                 } else {
563                         /* skip number bits for submode (less the 5 control bits) */
564                         bit += SpeexSubModeSz[c] - 5;
565                         cnt += 160; /* new frame */
566                 }
567         }
568         return cnt;
569 }
570
571 static int speex8_samples(struct ast_frame *frame)
572 {
573         return speex_samples(frame->data.ptr, frame->datalen);
574 }
575
576 static struct ast_codec speex8 = {
577         .name = "speex",
578         .description = "SpeeX",
579         .type = AST_MEDIA_TYPE_AUDIO,
580         .sample_rate = 8000,
581         .minimum_ms = 10,
582         .maximum_ms = 60,
583         .default_ms = 20,
584         .minimum_bytes = 10,
585         .samples_count = speex8_samples,
586 };
587
588 static int speex16_samples(struct ast_frame *frame)
589 {
590         return 2 * speex_samples(frame->data.ptr, frame->datalen);
591 }
592
593 static struct ast_codec speex16 = {
594         .name = "speex",
595         .description = "SpeeX 16khz",
596         .type = AST_MEDIA_TYPE_AUDIO,
597         .sample_rate = 16000,
598         .minimum_ms = 10,
599         .maximum_ms = 60,
600         .default_ms = 20,
601         .minimum_bytes = 10,
602         .samples_count = speex16_samples,
603 };
604
605 static int speex32_samples(struct ast_frame *frame)
606 {
607         return 4 * speex_samples(frame->data.ptr, frame->datalen);
608 }
609
610 static struct ast_codec speex32 = {
611         .name = "speex",
612         .description = "SpeeX 32khz",
613         .type = AST_MEDIA_TYPE_AUDIO,
614         .sample_rate = 32000,
615         .minimum_ms = 10,
616         .maximum_ms = 60,
617         .default_ms = 20,
618         .minimum_bytes = 10,
619         .samples_count = speex32_samples,
620 };
621
622 static int ilbc_samples(struct ast_frame *frame)
623 {
624         struct ilbc_attr *attr = ast_format_get_attribute_data(frame->subclass.format);
625         const unsigned int mode = attr ? attr->mode : 30;
626         const unsigned int samples_per_frame = mode * ast_format_get_sample_rate(frame->subclass.format) / 1000;
627         const unsigned int octets_per_frame = (mode == 20) ? 38 : 50;
628
629         return samples_per_frame * frame->datalen / octets_per_frame;
630 }
631
632 static struct ast_codec ilbc = {
633         .name = "ilbc",
634         .description = "iLBC",
635         .type = AST_MEDIA_TYPE_AUDIO,
636         .sample_rate = 8000,
637         .minimum_ms = 20,
638         .maximum_ms = 300,
639         .default_ms = 20,
640         .minimum_bytes = 38,
641         .samples_count = ilbc_samples,
642         .smooth = 0,
643 };
644
645 static struct ast_codec g722 = {
646         .name = "g722",
647         .description = "G722",
648         .type = AST_MEDIA_TYPE_AUDIO,
649         .sample_rate = 16000,
650         .minimum_ms = 10,
651         .maximum_ms = 150,
652         .default_ms = 20,
653         .minimum_bytes = 80,
654         .samples_count = g726_samples,
655         .get_length = g726_length,
656         .smooth = 1,
657 };
658
659 static int siren7_samples(struct ast_frame *frame)
660 {
661         return frame->datalen * (16000 / 4000);
662 }
663
664 static int siren7_length(unsigned int samples)
665 {
666         return samples / (16000 / 4000);
667 }
668
669 static struct ast_codec siren7 = {
670         .name = "siren7",
671         .description = "ITU G.722.1 (Siren7, licensed from Polycom)",
672         .type = AST_MEDIA_TYPE_AUDIO,
673         .sample_rate = 16000,
674         .minimum_ms = 20,
675         .maximum_ms = 80,
676         .default_ms = 20,
677         .minimum_bytes = 80,
678         .samples_count = siren7_samples,
679         .get_length = siren7_length,
680 };
681
682 static int siren14_samples(struct ast_frame *frame)
683 {
684         return (int) frame->datalen * ((float) 32000 / 6000);
685 }
686
687 static int siren14_length(unsigned int samples)
688 {
689         return (int) samples / ((float) 32000 / 6000);;
690 }
691
692 static struct ast_codec siren14 = {
693         .name = "siren14",
694         .description = "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)",
695         .type = AST_MEDIA_TYPE_AUDIO,
696         .sample_rate = 32000,
697         .minimum_ms = 20,
698         .maximum_ms = 80,
699         .default_ms = 20,
700         .minimum_bytes = 120,
701         .samples_count = siren14_samples,
702         .get_length = siren14_length,
703 };
704
705 static struct ast_codec testlaw = {
706         .name = "testlaw",
707         .description = "G.711 test-law",
708         .type = AST_MEDIA_TYPE_AUDIO,
709         .sample_rate = 8000,
710         .minimum_ms = 10,
711         .maximum_ms = 150,
712         .default_ms = 20,
713         .minimum_bytes = 80,
714         .samples_count = ulaw_samples,
715         .get_length = ulaw_length,
716         .smooth = 1,
717 };
718
719 static int g719_samples(struct ast_frame *frame)
720 {
721         return (int) frame->datalen * ((float) 48000 / 8000);
722 }
723
724 static int g719_length(unsigned int samples)
725 {
726         return (int) samples / ((float) 48000 / 8000);
727 }
728
729 static struct ast_codec g719 = {
730         .name = "g719",
731         .description = "ITU G.719",
732         .type = AST_MEDIA_TYPE_AUDIO,
733         .sample_rate = 48000,
734         .minimum_ms = 20,
735         .maximum_ms = 80,
736         .default_ms = 20,
737         .minimum_bytes = 160,
738         .samples_count = g719_samples,
739         .get_length = g719_length,
740 };
741
742 static int opus_samples(struct ast_frame *frame)
743 {
744         /*
745          * XXX This is likely not at all what's intended from this
746          * callback.  If you have codec_opus.so loaded then this
747          * function is overridden anyway.  However, since opus is
748          * variable bit rate and I cannot extract the calculation code
749          * from the opus library, I am going to punt and assume 20ms
750          * worth of samples.  In testing, this has worked just fine.
751          * Pass through support doesn't seem to care about the value
752          * returned anyway.
753          */
754         return ast_format_get_sample_rate(frame->subclass.format) / 50;
755 }
756
757 static struct ast_codec opus = {
758         .name = "opus",
759         .description = "Opus Codec",
760         .type = AST_MEDIA_TYPE_AUDIO,
761         .sample_rate = 48000,
762         .minimum_ms = 20,
763         .maximum_ms = 60,
764         .default_ms = 20,
765         .samples_count = opus_samples,
766         .minimum_bytes = 10,
767 };
768
769 static struct ast_codec jpeg = {
770         .name = "jpeg",
771         .description = "JPEG image",
772         .type = AST_MEDIA_TYPE_IMAGE,
773 };
774
775 static struct ast_codec png = {
776         .name = "png",
777         .description = "PNG Image",
778         .type = AST_MEDIA_TYPE_IMAGE,
779 };
780
781 static struct ast_codec h261 = {
782         .name = "h261",
783         .description = "H.261 video",
784         .type = AST_MEDIA_TYPE_VIDEO,
785         .sample_rate = 1000,
786 };
787
788 static struct ast_codec h263 = {
789         .name = "h263",
790         .description = "H.263 video",
791         .type = AST_MEDIA_TYPE_VIDEO,
792         .sample_rate = 1000,
793 };
794
795 static struct ast_codec h263p = {
796         .name = "h263p",
797         .description = "H.263+ video",
798         .type = AST_MEDIA_TYPE_VIDEO,
799         .sample_rate = 1000,
800 };
801
802 static struct ast_codec h264 = {
803         .name = "h264",
804         .description = "H.264 video",
805         .type = AST_MEDIA_TYPE_VIDEO,
806         .sample_rate = 1000,
807 };
808
809 static struct ast_codec mpeg4 = {
810         .name = "mpeg4",
811         .description = "MPEG4 video",
812         .type = AST_MEDIA_TYPE_VIDEO,
813         .sample_rate = 1000,
814 };
815
816 static struct ast_codec vp8 = {
817         .name = "vp8",
818         .description = "VP8 video",
819         .type = AST_MEDIA_TYPE_VIDEO,
820         .sample_rate = 1000,
821 };
822
823 static struct ast_codec vp9 = {
824         .name = "vp9",
825         .description = "VP9 video",
826         .type = AST_MEDIA_TYPE_VIDEO,
827         .sample_rate = 1000,
828 };
829
830 static struct ast_codec t140red = {
831         .name = "red",
832         .description = "T.140 Realtime Text with redundancy",
833         .type = AST_MEDIA_TYPE_TEXT,
834 };
835
836 static struct ast_codec t140 = {
837         .name = "t140",
838         .description = "Passthrough T.140 Realtime Text",
839         .type = AST_MEDIA_TYPE_TEXT,
840 };
841
842 static struct ast_codec t38 = {
843         .name = "t38",
844         .description = "T.38 UDPTL Fax",
845         .type = AST_MEDIA_TYPE_IMAGE,
846 };
847
848 static int silk_samples(struct ast_frame *frame)
849 {
850         /* XXX This is likely not at all what's intended from this callback. However,
851          * since SILK is variable bit rate, I have no idea how to take a frame of data
852          * and determine the number of samples present. Instead, we base this on the
853          * sample rate of the codec and the expected number of samples to receive in 20ms.
854          * In testing, this has worked just fine.
855          */
856         return ast_format_get_sample_rate(frame->subclass.format) / 50;
857 }
858
859 static struct ast_codec silk8 = {
860         .name = "silk",
861         .description = "SILK Codec (8 KHz)",
862         .type = AST_MEDIA_TYPE_AUDIO,
863         .sample_rate = 8000,
864         .minimum_ms = 20,
865         .maximum_ms = 100,
866         .default_ms = 20,
867         .minimum_bytes = 160,
868         .samples_count = silk_samples
869 };
870
871 static struct ast_codec silk12 = {
872         .name = "silk",
873         .description = "SILK Codec (12 KHz)",
874         .type = AST_MEDIA_TYPE_AUDIO,
875         .sample_rate = 12000,
876         .minimum_ms = 20,
877         .maximum_ms = 100,
878         .default_ms = 20,
879         .minimum_bytes = 240,
880         .samples_count = silk_samples
881 };
882
883 static struct ast_codec silk16 = {
884         .name = "silk",
885         .description = "SILK Codec (16 KHz)",
886         .type = AST_MEDIA_TYPE_AUDIO,
887         .sample_rate = 16000,
888         .minimum_ms = 20,
889         .maximum_ms = 100,
890         .default_ms = 20,
891         .minimum_bytes = 320,
892         .samples_count = silk_samples
893 };
894
895 static struct ast_codec silk24 = {
896         .name = "silk",
897         .description = "SILK Codec (24 KHz)",
898         .type = AST_MEDIA_TYPE_AUDIO,
899         .sample_rate = 24000,
900         .minimum_ms = 20,
901         .maximum_ms = 100,
902         .default_ms = 20,
903         .minimum_bytes = 480,
904         .samples_count = silk_samples
905 };
906
907 #define CODEC_REGISTER_AND_CACHE(codec) \
908         ({ \
909                 int __res_ ## __LINE__ = 0; \
910                 struct ast_format *__fmt_ ## __LINE__; \
911                 struct ast_codec *__codec_ ## __LINE__; \
912                 res |= __ast_codec_register_with_format(&(codec), (codec).name, NULL); \
913                 __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
914                 __fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
915                 res |= ast_format_cache_set(__fmt_ ## __LINE__); \
916                 ao2_ref(__fmt_ ## __LINE__, -1); \
917                 ao2_ref(__codec_ ## __LINE__, -1); \
918                 __res_ ## __LINE__; \
919         })
920
921 #define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
922         ({ \
923                 int __res_ ## __LINE__ = 0; \
924                 struct ast_format *__fmt_ ## __LINE__; \
925                 struct ast_codec *__codec_ ## __LINE__; \
926                 res |= __ast_codec_register_with_format(&(codec), fmt_name, NULL); \
927                 __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
928                 __fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
929                 res |= ast_format_cache_set(__fmt_ ## __LINE__); \
930                 ao2_ref(__fmt_ ## __LINE__, -1); \
931                 ao2_ref(__codec_ ## __LINE__, -1); \
932                 __res_ ## __LINE__; \
933         })
934
935 int ast_codec_builtin_init(void)
936 {
937         int res = 0;
938
939         res |= CODEC_REGISTER_AND_CACHE(codec2);
940         res |= CODEC_REGISTER_AND_CACHE(g723);
941         res |= CODEC_REGISTER_AND_CACHE(ulaw);
942         res |= CODEC_REGISTER_AND_CACHE(alaw);
943         res |= CODEC_REGISTER_AND_CACHE(gsm);
944         res |= CODEC_REGISTER_AND_CACHE(g726rfc3551);
945         res |= CODEC_REGISTER_AND_CACHE(g726aal2);
946         res |= CODEC_REGISTER_AND_CACHE(adpcm);
947         res |= CODEC_REGISTER_AND_CACHE(slin8);
948         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin12", slin12);
949         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin16", slin16);
950         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin24", slin24);
951         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin32", slin32);
952         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin44", slin44);
953         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin48", slin48);
954         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin96", slin96);
955         res |= CODEC_REGISTER_AND_CACHE_NAMED("slin192", slin192);
956         res |= CODEC_REGISTER_AND_CACHE(lpc10);
957         res |= CODEC_REGISTER_AND_CACHE(g729a);
958         res |= CODEC_REGISTER_AND_CACHE(speex8);
959         res |= CODEC_REGISTER_AND_CACHE_NAMED("speex16", speex16);
960         res |= CODEC_REGISTER_AND_CACHE_NAMED("speex32", speex32);
961         res |= CODEC_REGISTER_AND_CACHE(ilbc);
962         res |= CODEC_REGISTER_AND_CACHE(g722);
963         res |= CODEC_REGISTER_AND_CACHE(siren7);
964         res |= CODEC_REGISTER_AND_CACHE(siren14);
965         res |= CODEC_REGISTER_AND_CACHE(testlaw);
966         res |= CODEC_REGISTER_AND_CACHE(g719);
967         res |= CODEC_REGISTER_AND_CACHE(opus);
968         res |= CODEC_REGISTER_AND_CACHE(jpeg);
969         res |= CODEC_REGISTER_AND_CACHE(png);
970         res |= CODEC_REGISTER_AND_CACHE(h261);
971         res |= CODEC_REGISTER_AND_CACHE(h263);
972         res |= CODEC_REGISTER_AND_CACHE(h263p);
973         res |= CODEC_REGISTER_AND_CACHE(h264);
974         res |= CODEC_REGISTER_AND_CACHE(mpeg4);
975         res |= CODEC_REGISTER_AND_CACHE(vp8);
976         res |= CODEC_REGISTER_AND_CACHE(vp9);
977         res |= CODEC_REGISTER_AND_CACHE(t140red);
978         res |= CODEC_REGISTER_AND_CACHE(t140);
979         res |= CODEC_REGISTER_AND_CACHE(t38);
980         res |= CODEC_REGISTER_AND_CACHE(none);
981         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk8", silk8);
982         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk12", silk12);
983         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk16", silk16);
984         res |= CODEC_REGISTER_AND_CACHE_NAMED("silk24", silk24);
985
986         return res;
987 }