Asterisk - The Open Source Telephony Project  18.5.0
codec_builtin.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2014, Digium, Inc.
5  *
6  * Joshua Colp <[email protected]>
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 <[email protected]>
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,
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,
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,
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,
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,
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,
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,
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,
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,
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 {
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 h265 = {
810  .name = "h265",
811  .description = "H.265 video",
812  .type = AST_MEDIA_TYPE_VIDEO,
813  .sample_rate = 1000,
814 };
815 
816 static struct ast_codec mpeg4 = {
817  .name = "mpeg4",
818  .description = "MPEG4 video",
819  .type = AST_MEDIA_TYPE_VIDEO,
820  .sample_rate = 1000,
821 };
822 
823 static struct ast_codec vp8 = {
824  .name = "vp8",
825  .description = "VP8 video",
826  .type = AST_MEDIA_TYPE_VIDEO,
827  .sample_rate = 1000,
828 };
829 
830 static struct ast_codec vp9 = {
831  .name = "vp9",
832  .description = "VP9 video",
833  .type = AST_MEDIA_TYPE_VIDEO,
834  .sample_rate = 1000,
835 };
836 
837 static struct ast_codec t140red = {
838  .name = "red",
839  .description = "T.140 Realtime Text with redundancy",
840  .type = AST_MEDIA_TYPE_TEXT,
841 };
842 
843 static struct ast_codec t140 = {
844  .name = "t140",
845  .description = "Passthrough T.140 Realtime Text",
846  .type = AST_MEDIA_TYPE_TEXT,
847 };
848 
849 static struct ast_codec t38 = {
850  .name = "t38",
851  .description = "T.38 UDPTL Fax",
852  .type = AST_MEDIA_TYPE_IMAGE,
853 };
854 
855 static int silk_samples(struct ast_frame *frame)
856 {
857  /* XXX This is likely not at all what's intended from this callback. However,
858  * since SILK is variable bit rate, I have no idea how to take a frame of data
859  * and determine the number of samples present. Instead, we base this on the
860  * sample rate of the codec and the expected number of samples to receive in 20ms.
861  * In testing, this has worked just fine.
862  */
863  return ast_format_get_sample_rate(frame->subclass.format) / 50;
864 }
865 
866 static struct ast_codec silk8 = {
867  .name = "silk",
868  .description = "SILK Codec (8 KHz)",
869  .type = AST_MEDIA_TYPE_AUDIO,
870  .sample_rate = 8000,
871  .minimum_ms = 20,
872  .maximum_ms = 100,
873  .default_ms = 20,
874  .minimum_bytes = 160,
875  .samples_count = silk_samples
876 };
877 
878 static struct ast_codec silk12 = {
879  .name = "silk",
880  .description = "SILK Codec (12 KHz)",
881  .type = AST_MEDIA_TYPE_AUDIO,
882  .sample_rate = 12000,
883  .minimum_ms = 20,
884  .maximum_ms = 100,
885  .default_ms = 20,
886  .minimum_bytes = 240,
887  .samples_count = silk_samples
888 };
889 
890 static struct ast_codec silk16 = {
891  .name = "silk",
892  .description = "SILK Codec (16 KHz)",
893  .type = AST_MEDIA_TYPE_AUDIO,
894  .sample_rate = 16000,
895  .minimum_ms = 20,
896  .maximum_ms = 100,
897  .default_ms = 20,
898  .minimum_bytes = 320,
899  .samples_count = silk_samples
900 };
901 
902 static struct ast_codec silk24 = {
903  .name = "silk",
904  .description = "SILK Codec (24 KHz)",
905  .type = AST_MEDIA_TYPE_AUDIO,
906  .sample_rate = 24000,
907  .minimum_ms = 20,
908  .maximum_ms = 100,
909  .default_ms = 20,
910  .minimum_bytes = 480,
911  .samples_count = silk_samples
912 };
913 
914 #define CODEC_REGISTER_AND_CACHE(codec) \
915  ({ \
916  int __res_ ## __LINE__ = 0; \
917  struct ast_format *__fmt_ ## __LINE__; \
918  struct ast_codec *__codec_ ## __LINE__; \
919  res |= __ast_codec_register_with_format(&(codec), (codec).name, NULL); \
920  __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
921  __fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
922  res |= ast_format_cache_set(__fmt_ ## __LINE__); \
923  ao2_ref(__fmt_ ## __LINE__, -1); \
924  ao2_ref(__codec_ ## __LINE__, -1); \
925  __res_ ## __LINE__; \
926  })
927 
928 #define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
929  ({ \
930  int __res_ ## __LINE__ = 0; \
931  struct ast_format *__fmt_ ## __LINE__; \
932  struct ast_codec *__codec_ ## __LINE__; \
933  res |= __ast_codec_register_with_format(&(codec), fmt_name, NULL); \
934  __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
935  __fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
936  res |= ast_format_cache_set(__fmt_ ## __LINE__); \
937  ao2_ref(__fmt_ ## __LINE__, -1); \
938  ao2_ref(__codec_ ## __LINE__, -1); \
939  __res_ ## __LINE__; \
940  })
941 
943 {
944  int res = 0;
945 
946  res |= CODEC_REGISTER_AND_CACHE(codec2);
947  res |= CODEC_REGISTER_AND_CACHE(g723);
948  res |= CODEC_REGISTER_AND_CACHE(ulaw);
949  res |= CODEC_REGISTER_AND_CACHE(alaw);
950  res |= CODEC_REGISTER_AND_CACHE(gsm);
951  res |= CODEC_REGISTER_AND_CACHE(g726rfc3551);
952  res |= CODEC_REGISTER_AND_CACHE(g726aal2);
953  res |= CODEC_REGISTER_AND_CACHE(adpcm);
954  res |= CODEC_REGISTER_AND_CACHE(slin8);
955  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin12", slin12);
956  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin16", slin16);
957  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin24", slin24);
958  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin32", slin32);
959  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin44", slin44);
960  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin48", slin48);
961  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin96", slin96);
962  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin192", slin192);
963  res |= CODEC_REGISTER_AND_CACHE(lpc10);
964  res |= CODEC_REGISTER_AND_CACHE(g729a);
965  res |= CODEC_REGISTER_AND_CACHE(speex8);
966  res |= CODEC_REGISTER_AND_CACHE_NAMED("speex16", speex16);
967  res |= CODEC_REGISTER_AND_CACHE_NAMED("speex32", speex32);
968  res |= CODEC_REGISTER_AND_CACHE(ilbc);
969  res |= CODEC_REGISTER_AND_CACHE(g722);
970  res |= CODEC_REGISTER_AND_CACHE(siren7);
971  res |= CODEC_REGISTER_AND_CACHE(siren14);
972  res |= CODEC_REGISTER_AND_CACHE(testlaw);
973  res |= CODEC_REGISTER_AND_CACHE(g719);
974  res |= CODEC_REGISTER_AND_CACHE(opus);
975  res |= CODEC_REGISTER_AND_CACHE(jpeg);
976  res |= CODEC_REGISTER_AND_CACHE(png);
977  res |= CODEC_REGISTER_AND_CACHE(h261);
978  res |= CODEC_REGISTER_AND_CACHE(h263);
979  res |= CODEC_REGISTER_AND_CACHE(h263p);
980  res |= CODEC_REGISTER_AND_CACHE(h264);
981  res |= CODEC_REGISTER_AND_CACHE(h265);
982  res |= CODEC_REGISTER_AND_CACHE(mpeg4);
983  res |= CODEC_REGISTER_AND_CACHE(vp8);
984  res |= CODEC_REGISTER_AND_CACHE(vp9);
985  res |= CODEC_REGISTER_AND_CACHE(t140red);
986  res |= CODEC_REGISTER_AND_CACHE(t140);
987  res |= CODEC_REGISTER_AND_CACHE(t38);
988  res |= CODEC_REGISTER_AND_CACHE(none);
989  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk8", silk8);
990  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk12", silk12);
991  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk16", silk16);
992  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk24", silk24);
993 
994  return res;
995 }
static const char type[]
Definition: chan_ooh323.c:109
static int speex_samples(unsigned char *data, int len)
static int speex8_samples(struct ast_frame *frame)
const char * name
Name for this codec.
Definition: codec.h:46
static int g723_len(unsigned char buf)
Definition: codec_builtin.c:53
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_codec testlaw
static struct ast_codec slin8
static struct ast_codec opus
static struct ast_codec ulaw
Definition: ilbc.h:4
static struct ast_codec speex8
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct ast_codec g726aal2
static int slin_length(unsigned int samples)
static int siren14_length(unsigned int samples)
static struct ast_codec slin48
static int gsm_samples(struct ast_frame *frame)
#define LOG_WARNING
Definition: logger.h:274
static int g726_samples(struct ast_frame *frame)
static int siren7_length(unsigned int samples)
int ast_codec_builtin_init(void)
Initialize built-in codecs within the core.
static struct ast_codec silk12
static struct ast_codec none
static int siren7_samples(struct ast_frame *frame)
static struct ast_codec slin44
static struct ast_codec silk24
static struct ast_codec slin16
Codec API.
static int none_length(unsigned int samples)
#define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec)
static struct ast_codec h261
static struct ast_codec siren14
void * ast_format_get_attribute_data(const struct ast_format *format)
Get the attribute data on a format.
Definition: format.c:125
static int none_samples(struct ast_frame *frame)
static struct test_val c
static struct ast_codec speex16
static struct ast_codec t140red
static struct ast_codec alaw
static struct ast_codec siren7
static struct ast_codec silk16
Asterisk internal frame definitions.
#define CODEC_REGISTER_AND_CACHE(codec)
struct ast_frame_subclass subclass
Media Format API.
static struct ast_codec codec2
int __ast_codec_register_with_format(struct ast_codec *codec, const char *format_name, struct ast_module *mod)
Definition: codec.c:277
static struct ast_codec mpeg4
#define ast_log
Definition: astobj2.c:42
static struct ast_codec g722
static struct ast_codec silk8
static struct ast_codec t38
static struct ast_codec slin192
static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
static struct ast_codec speex32
#define AST_SMOOTHER_FLAG_FORCED
Definition: smoother.h:36
static struct ast_codec jpeg
Asterisk internal frame definitions.
static int speex32_samples(struct ast_frame *frame)
static int codec2_samples(struct ast_frame *frame)
static int slin_samples(struct ast_frame *frame)
static int g723_length(unsigned int samples)
Definition: codec_builtin.c:92
static int g726_length(unsigned int samples)
static int g719_length(unsigned int samples)
static struct ast_codec slin96
static struct ast_codec adpcm
#define TYPE_MASK
Definition: codec_builtin.c:51
static struct ast_codec g729a
static int g729_length(unsigned int samples)
static struct ast_codec h263
static struct ast_codec h264
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
frame_type
Definition: codec_builtin.c:44
static int opus_samples(struct ast_frame *frame)
static struct ast_codec vp8
static int ilbc_samples(struct ast_frame *frame)
static struct ast_codec slin32
static struct ast_codec t140
unsigned int mode
Definition: ilbc.h:5
static struct ast_codec g726rfc3551
static struct ast_codec slin24
static struct ast_codec g719
static struct ast_codec h265
Support for logging to various files, console and syslog Configuration in file logger.conf.
static int silk_samples(struct ast_frame *frame)
static int g723_samples(struct ast_frame *frame)
Definition: codec_builtin.c:76
#define AST_SMOOTHER_FLAG_BE
Definition: smoother.h:35
static struct ast_codec lpc10
static int codec2_length(unsigned int samples)
static struct ast_codec png
static struct ast_codec g723
Definition: codec_builtin.c:97
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
Data structure associated with a single frame of data.
static struct ast_codec vp9
static struct ast_codec slin12
static int lpc10_samples(struct ast_frame *frame)
static int siren14_samples(struct ast_frame *frame)
union ast_frame::@263 data
struct ast_format * format
static int speex16_samples(struct ast_frame *frame)
static struct ast_codec h263p
static struct ast_codec ilbc
static int gsm_length(unsigned int samples)
static int ulaw_samples(struct ast_frame *frame)
Represents a media codec within Asterisk.
Definition: codec.h:42
static int ulaw_length(unsigned int samples)
static int g719_samples(struct ast_frame *frame)
Media Format Cache API.
static int g729_samples(struct ast_frame *frame)