Asterisk - The Open Source Telephony Project  GIT-master-4a4f1a5
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 <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,
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  .smoother_flags = AST_SMOOTHER_FLAG_G729,
461 };
462 
463 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
464 {
465  int byte = bit / 8; /* byte containing first bit */
466  int rem = 8 - (bit % 8); /* remaining bits in first byte */
467  unsigned char ret = 0;
468 
469  if (n <= 0 || n > 8)
470  return 0;
471 
472  if (rem < n) {
473  ret = (data[byte] << (n - rem));
474  ret |= (data[byte + 1] >> (8 - n + rem));
475  } else {
476  ret = (data[byte] >> (rem - n));
477  }
478 
479  return (ret & (0xff >> (8 - n)));
480 }
481 
482 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
483 {
484  static const int SpeexWBSubModeSz[] = {
485  4, 36, 112, 192,
486  352, 0, 0, 0 };
487  int off = bit;
488  unsigned char c;
489 
490  /* skip up to two wideband frames */
491  if (((len * 8 - off) >= 5) &&
492  get_n_bits_at(data, 1, off)) {
493  c = get_n_bits_at(data, 3, off + 1);
494  off += SpeexWBSubModeSz[c];
495 
496  if (((len * 8 - off) >= 5) &&
497  get_n_bits_at(data, 1, off)) {
498  c = get_n_bits_at(data, 3, off + 1);
499  off += SpeexWBSubModeSz[c];
500 
501  if (((len * 8 - off) >= 5) &&
502  get_n_bits_at(data, 1, off)) {
503  ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
504  return -1;
505  }
506  }
507 
508  }
509  return off - bit;
510 }
511 
512 static int speex_samples(unsigned char *data, int len)
513 {
514  static const int SpeexSubModeSz[] = {
515  5, 43, 119, 160,
516  220, 300, 364, 492,
517  79, 0, 0, 0,
518  0, 0, 0, 0 };
519  static const int SpeexInBandSz[] = {
520  1, 1, 4, 4,
521  4, 4, 4, 4,
522  8, 8, 16, 16,
523  32, 32, 64, 64 };
524  int bit = 0;
525  int cnt = 0;
526  int off;
527  unsigned char c;
528 
529  while ((len * 8 - bit) >= 5) {
530  /* skip wideband frames */
531  off = speex_get_wb_sz_at(data, len, bit);
532  if (off < 0) {
533  ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
534  break;
535  }
536  bit += off;
537 
538  if ((len * 8 - bit) < 5)
539  break;
540 
541  /* get control bits */
542  c = get_n_bits_at(data, 5, bit);
543  bit += 5;
544 
545  if (c == 15) {
546  /* terminator */
547  break;
548  } else if (c == 14) {
549  /* in-band signal; next 4 bits contain signal id */
550  c = get_n_bits_at(data, 4, bit);
551  bit += 4;
552  bit += SpeexInBandSz[c];
553  } else if (c == 13) {
554  /* user in-band; next 4 bits contain msg len */
555  c = get_n_bits_at(data, 4, bit);
556  bit += 4;
557  /* after which it's 5-bit signal id + c bytes of data */
558  bit += 5 + c * 8;
559  } else if (c > 8) {
560  /* unknown */
561  ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
562  break;
563  } else {
564  /* skip number bits for submode (less the 5 control bits) */
565  bit += SpeexSubModeSz[c] - 5;
566  cnt += 160; /* new frame */
567  }
568  }
569  return cnt;
570 }
571 
572 static int speex8_samples(struct ast_frame *frame)
573 {
574  return speex_samples(frame->data.ptr, frame->datalen);
575 }
576 
577 static struct ast_codec speex8 = {
578  .name = "speex",
579  .description = "SpeeX",
580  .type = AST_MEDIA_TYPE_AUDIO,
581  .sample_rate = 8000,
582  .minimum_ms = 10,
583  .maximum_ms = 60,
584  .default_ms = 20,
585  .minimum_bytes = 10,
586  .samples_count = speex8_samples,
587 };
588 
589 static int speex16_samples(struct ast_frame *frame)
590 {
591  return 2 * speex_samples(frame->data.ptr, frame->datalen);
592 }
593 
594 static struct ast_codec speex16 = {
595  .name = "speex",
596  .description = "SpeeX 16khz",
597  .type = AST_MEDIA_TYPE_AUDIO,
598  .sample_rate = 16000,
599  .minimum_ms = 10,
600  .maximum_ms = 60,
601  .default_ms = 20,
602  .minimum_bytes = 10,
603  .samples_count = speex16_samples,
604 };
605 
606 static int speex32_samples(struct ast_frame *frame)
607 {
608  return 4 * speex_samples(frame->data.ptr, frame->datalen);
609 }
610 
611 static struct ast_codec speex32 = {
612  .name = "speex",
613  .description = "SpeeX 32khz",
614  .type = AST_MEDIA_TYPE_AUDIO,
615  .sample_rate = 32000,
616  .minimum_ms = 10,
617  .maximum_ms = 60,
618  .default_ms = 20,
619  .minimum_bytes = 10,
620  .samples_count = speex32_samples,
621 };
622 
623 static int ilbc_samples(struct ast_frame *frame)
624 {
626  const unsigned int mode = attr ? attr->mode : 30;
627  const unsigned int samples_per_frame = mode * ast_format_get_sample_rate(frame->subclass.format) / 1000;
628  const unsigned int octets_per_frame = (mode == 20) ? 38 : 50;
629 
630  return samples_per_frame * frame->datalen / octets_per_frame;
631 }
632 
633 static struct ast_codec ilbc = {
634  .name = "ilbc",
635  .description = "iLBC",
636  .type = AST_MEDIA_TYPE_AUDIO,
637  .sample_rate = 8000,
638  .minimum_ms = 20,
639  .maximum_ms = 300,
640  .default_ms = 20,
641  .minimum_bytes = 38,
642  .samples_count = ilbc_samples,
643  .smooth = 0,
644 };
645 
646 static struct ast_codec g722 = {
647  .name = "g722",
648  .description = "G722",
649  .type = AST_MEDIA_TYPE_AUDIO,
650  .sample_rate = 16000,
651  .minimum_ms = 10,
652  .maximum_ms = 150,
653  .default_ms = 20,
654  .minimum_bytes = 80,
655  .samples_count = g726_samples,
656  .get_length = g726_length,
657  .smooth = 1,
658 };
659 
660 static int siren7_samples(struct ast_frame *frame)
661 {
662  return frame->datalen * (16000 / 4000);
663 }
664 
665 static int siren7_length(unsigned int samples)
666 {
667  return samples / (16000 / 4000);
668 }
669 
670 static struct ast_codec siren7 = {
671  .name = "siren7",
672  .description = "ITU G.722.1 (Siren7, licensed from Polycom)",
673  .type = AST_MEDIA_TYPE_AUDIO,
674  .sample_rate = 16000,
675  .minimum_ms = 20,
676  .maximum_ms = 80,
677  .default_ms = 20,
678  .minimum_bytes = 80,
679  .samples_count = siren7_samples,
680  .get_length = siren7_length,
681 };
682 
683 static int siren14_samples(struct ast_frame *frame)
684 {
685  return (int) frame->datalen * ((float) 32000 / 6000);
686 }
687 
688 static int siren14_length(unsigned int samples)
689 {
690  return (int) samples / ((float) 32000 / 6000);;
691 }
692 
693 static struct ast_codec siren14 = {
694  .name = "siren14",
695  .description = "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)",
696  .type = AST_MEDIA_TYPE_AUDIO,
697  .sample_rate = 32000,
698  .minimum_ms = 20,
699  .maximum_ms = 80,
700  .default_ms = 20,
701  .minimum_bytes = 120,
702  .samples_count = siren14_samples,
703  .get_length = siren14_length,
704 };
705 
706 static int g719_samples(struct ast_frame *frame)
707 {
708  return (int) frame->datalen * ((float) 48000 / 8000);
709 }
710 
711 static int g719_length(unsigned int samples)
712 {
713  return (int) samples / ((float) 48000 / 8000);
714 }
715 
716 static struct ast_codec g719 = {
717  .name = "g719",
718  .description = "ITU G.719",
719  .type = AST_MEDIA_TYPE_AUDIO,
720  .sample_rate = 48000,
721  .minimum_ms = 20,
722  .maximum_ms = 80,
723  .default_ms = 20,
724  .minimum_bytes = 160,
725  .samples_count = g719_samples,
726  .get_length = g719_length,
727 };
728 
729 static int opus_samples(struct ast_frame *frame)
730 {
731  /*
732  * XXX This is likely not at all what's intended from this
733  * callback. If you have codec_opus.so loaded then this
734  * function is overridden anyway. However, since opus is
735  * variable bit rate and I cannot extract the calculation code
736  * from the opus library, I am going to punt and assume 20ms
737  * worth of samples. In testing, this has worked just fine.
738  * Pass through support doesn't seem to care about the value
739  * returned anyway.
740  */
741  return ast_format_get_sample_rate(frame->subclass.format) / 50;
742 }
743 
744 static struct ast_codec opus = {
745  .name = "opus",
746  .description = "Opus Codec",
747  .type = AST_MEDIA_TYPE_AUDIO,
748  .sample_rate = 48000,
749  .minimum_ms = 20,
750  .maximum_ms = 60,
751  .default_ms = 20,
752  .samples_count = opus_samples,
753  .minimum_bytes = 10,
754 };
755 
756 static struct ast_codec jpeg = {
757  .name = "jpeg",
758  .description = "JPEG image",
759  .type = AST_MEDIA_TYPE_IMAGE,
760 };
761 
762 static struct ast_codec png = {
763  .name = "png",
764  .description = "PNG Image",
765  .type = AST_MEDIA_TYPE_IMAGE,
766 };
767 
768 static struct ast_codec h261 = {
769  .name = "h261",
770  .description = "H.261 video",
771  .type = AST_MEDIA_TYPE_VIDEO,
772  .sample_rate = 1000,
773 };
774 
775 static struct ast_codec h263 = {
776  .name = "h263",
777  .description = "H.263 video",
778  .type = AST_MEDIA_TYPE_VIDEO,
779  .sample_rate = 1000,
780 };
781 
782 static struct ast_codec h263p = {
783  .name = "h263p",
784  .description = "H.263+ video",
785  .type = AST_MEDIA_TYPE_VIDEO,
786  .sample_rate = 1000,
787 };
788 
789 static struct ast_codec h264 = {
790  .name = "h264",
791  .description = "H.264 video",
792  .type = AST_MEDIA_TYPE_VIDEO,
793  .sample_rate = 1000,
794 };
795 
796 static struct ast_codec h265 = {
797  .name = "h265",
798  .description = "H.265 video",
799  .type = AST_MEDIA_TYPE_VIDEO,
800  .sample_rate = 1000,
801 };
802 
803 static struct ast_codec mpeg4 = {
804  .name = "mpeg4",
805  .description = "MPEG4 video",
806  .type = AST_MEDIA_TYPE_VIDEO,
807  .sample_rate = 1000,
808 };
809 
810 static struct ast_codec vp8 = {
811  .name = "vp8",
812  .description = "VP8 video",
813  .type = AST_MEDIA_TYPE_VIDEO,
814  .sample_rate = 1000,
815 };
816 
817 static struct ast_codec vp9 = {
818  .name = "vp9",
819  .description = "VP9 video",
820  .type = AST_MEDIA_TYPE_VIDEO,
821  .sample_rate = 1000,
822 };
823 
824 static struct ast_codec t140red = {
825  .name = "red",
826  .description = "T.140 Realtime Text with redundancy",
827  .type = AST_MEDIA_TYPE_TEXT,
828 };
829 
830 static struct ast_codec t140 = {
831  .name = "t140",
832  .description = "Passthrough T.140 Realtime Text",
833  .type = AST_MEDIA_TYPE_TEXT,
834 };
835 
836 static struct ast_codec t38 = {
837  .name = "t38",
838  .description = "T.38 UDPTL Fax",
839  .type = AST_MEDIA_TYPE_IMAGE,
840 };
841 
842 static int silk_samples(struct ast_frame *frame)
843 {
844  /* XXX This is likely not at all what's intended from this callback. However,
845  * since SILK is variable bit rate, I have no idea how to take a frame of data
846  * and determine the number of samples present. Instead, we base this on the
847  * sample rate of the codec and the expected number of samples to receive in 20ms.
848  * In testing, this has worked just fine.
849  */
850  return ast_format_get_sample_rate(frame->subclass.format) / 50;
851 }
852 
853 static struct ast_codec silk8 = {
854  .name = "silk",
855  .description = "SILK Codec (8 KHz)",
856  .type = AST_MEDIA_TYPE_AUDIO,
857  .sample_rate = 8000,
858  .minimum_ms = 20,
859  .maximum_ms = 100,
860  .default_ms = 20,
861  .minimum_bytes = 160,
862  .samples_count = silk_samples
863 };
864 
865 static struct ast_codec silk12 = {
866  .name = "silk",
867  .description = "SILK Codec (12 KHz)",
868  .type = AST_MEDIA_TYPE_AUDIO,
869  .sample_rate = 12000,
870  .minimum_ms = 20,
871  .maximum_ms = 100,
872  .default_ms = 20,
873  .minimum_bytes = 240,
874  .samples_count = silk_samples
875 };
876 
877 static struct ast_codec silk16 = {
878  .name = "silk",
879  .description = "SILK Codec (16 KHz)",
880  .type = AST_MEDIA_TYPE_AUDIO,
881  .sample_rate = 16000,
882  .minimum_ms = 20,
883  .maximum_ms = 100,
884  .default_ms = 20,
885  .minimum_bytes = 320,
886  .samples_count = silk_samples
887 };
888 
889 static struct ast_codec silk24 = {
890  .name = "silk",
891  .description = "SILK Codec (24 KHz)",
892  .type = AST_MEDIA_TYPE_AUDIO,
893  .sample_rate = 24000,
894  .minimum_ms = 20,
895  .maximum_ms = 100,
896  .default_ms = 20,
897  .minimum_bytes = 480,
898  .samples_count = silk_samples
899 };
900 
901 #define CODEC_REGISTER_AND_CACHE(codec) \
902  ({ \
903  int __res_ ## __LINE__ = 0; \
904  struct ast_format *__fmt_ ## __LINE__; \
905  struct ast_codec *__codec_ ## __LINE__; \
906  res |= __ast_codec_register_with_format(&(codec), (codec).name, NULL); \
907  __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
908  __fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
909  res |= ast_format_cache_set(__fmt_ ## __LINE__); \
910  ao2_ref(__fmt_ ## __LINE__, -1); \
911  ao2_ref(__codec_ ## __LINE__, -1); \
912  __res_ ## __LINE__; \
913  })
914 
915 #define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
916  ({ \
917  int __res_ ## __LINE__ = 0; \
918  struct ast_format *__fmt_ ## __LINE__; \
919  struct ast_codec *__codec_ ## __LINE__; \
920  res |= __ast_codec_register_with_format(&(codec), fmt_name, NULL); \
921  __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
922  __fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
923  res |= ast_format_cache_set(__fmt_ ## __LINE__); \
924  ao2_ref(__fmt_ ## __LINE__, -1); \
925  ao2_ref(__codec_ ## __LINE__, -1); \
926  __res_ ## __LINE__; \
927  })
928 
930 {
931  int res = 0;
932 
942  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin12", slin12);
943  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin16", slin16);
944  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin24", slin24);
945  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin32", slin32);
946  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin44", slin44);
947  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin48", slin48);
948  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin96", slin96);
949  res |= CODEC_REGISTER_AND_CACHE_NAMED("slin192", slin192);
953  res |= CODEC_REGISTER_AND_CACHE_NAMED("speex16", speex16);
954  res |= CODEC_REGISTER_AND_CACHE_NAMED("speex32", speex32);
975  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk8", silk8);
976  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk12", silk12);
977  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk16", silk16);
978  res |= CODEC_REGISTER_AND_CACHE_NAMED("silk24", silk24);
979 
980  return res;
981 }
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
static const char type[]
Definition: chan_ooh323.c:109
Codec API.
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
@ AST_MEDIA_TYPE_IMAGE
Definition: codec.h:34
@ AST_MEDIA_TYPE_TEXT
Definition: codec.h:35
static int silk_samples(struct ast_frame *frame)
static int ulaw_length(unsigned int samples)
static struct ast_codec g722
static int g723_samples(struct ast_frame *frame)
Definition: codec_builtin.c:76
static struct ast_codec codec2
static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
static int slin_length(unsigned int samples)
static struct ast_codec jpeg
static struct ast_codec t38
static int ulaw_samples(struct ast_frame *frame)
static int speex32_samples(struct ast_frame *frame)
static struct ast_codec siren7
static struct ast_codec silk16
static int g719_samples(struct ast_frame *frame)
static int none_length(unsigned int samples)
static struct ast_codec h263p
static int speex8_samples(struct ast_frame *frame)
static int codec2_length(unsigned int samples)
static int siren7_samples(struct ast_frame *frame)
static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
frame_type
Definition: codec_builtin.c:44
@ TYPE_LOW
Definition: codec_builtin.c:46
@ TYPE_SILENCE
Definition: codec_builtin.c:47
@ TYPE_HIGH
Definition: codec_builtin.c:45
@ TYPE_DONTSEND
Definition: codec_builtin.c:48
static struct ast_codec h263
static struct ast_codec ulaw
static struct ast_codec silk24
static int slin_samples(struct ast_frame *frame)
static struct ast_codec slin16
static struct ast_codec siren14
static int lpc10_samples(struct ast_frame *frame)
static struct ast_codec adpcm
static struct ast_codec silk8
static int g729_samples(struct ast_frame *frame)
static int g723_len(unsigned char buf)
Definition: codec_builtin.c:53
static struct ast_codec g723
Definition: codec_builtin.c:97
static struct ast_codec g729a
static int g719_length(unsigned int samples)
static struct ast_codec slin32
static struct ast_codec h265
static struct ast_codec lpc10
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 vp8
static struct ast_codec slin192
static struct ast_codec g726rfc3551
static int speex16_samples(struct ast_frame *frame)
static struct ast_codec none
static struct ast_codec g719
static struct ast_codec t140
static struct ast_codec ilbc
static struct ast_codec t140red
static int g723_length(unsigned int samples)
Definition: codec_builtin.c:92
static int gsm_samples(struct ast_frame *frame)
static struct ast_codec mpeg4
static struct ast_codec slin48
static struct ast_codec speex8
static int ilbc_samples(struct ast_frame *frame)
static struct ast_codec g726aal2
static struct ast_codec png
static struct ast_codec slin24
static int none_samples(struct ast_frame *frame)
#define CODEC_REGISTER_AND_CACHE(codec)
static struct ast_codec speex32
static struct ast_codec speex16
static int siren14_length(unsigned int samples)
static struct ast_codec slin8
static int g726_length(unsigned int samples)
static int gsm_length(unsigned int samples)
static struct ast_codec alaw
static struct ast_codec h261
static int g729_length(unsigned int samples)
static struct ast_codec slin12
static struct ast_codec vp9
int ast_codec_builtin_init(void)
Initialize built-in codecs within the core.
static int speex_samples(unsigned char *data, int len)
static int g726_samples(struct ast_frame *frame)
static struct ast_codec opus
static struct ast_codec h264
static struct ast_codec silk12
static struct ast_codec slin96
#define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec)
static int siren14_samples(struct ast_frame *frame)
static int siren7_length(unsigned int samples)
static int opus_samples(struct ast_frame *frame)
static struct ast_codec slin44
static int codec2_samples(struct ast_frame *frame)
#define TYPE_MASK
Definition: codec_builtin.c:51
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Media Format API.
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
void * ast_format_get_attribute_data(const struct ast_format *format)
Get the attribute data on a format.
Definition: format.c:125
Media Format Cache API.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Asterisk internal frame definitions.
Support for logging to various files, console and syslog Configuration in file logger....
#define LOG_WARNING
Definition: logger.h:275
Asterisk internal frame definitions.
#define AST_SMOOTHER_FLAG_G729
Definition: smoother.h:34
#define AST_SMOOTHER_FLAG_FORCED
Definition: smoother.h:36
#define AST_SMOOTHER_FLAG_BE
Definition: smoother.h:35
Represents a media codec within Asterisk.
Definition: codec.h:42
const char * name
Name for this codec.
Definition: codec.h:46
struct ast_format * format
Data structure associated with a single frame of data.
union ast_frame::@250 data
struct ast_frame_subclass subclass
Definition: ilbc.h:4
unsigned int mode
Definition: ilbc.h:5
static struct test_val c