32 #include "asterisk/ilbc.h"
41 int __ast_codec_register_with_format(
struct ast_codec *codec,
const char *format_name,
53 static int g723_len(
unsigned char buf)
55 enum frame_type type = buf & TYPE_MASK;
71 ast_log(LOG_WARNING,
"Badly encoded frame (%u)\n", type);
76 static int g723_samples(
struct ast_frame *frame)
78 unsigned char *buf = frame->
data.ptr;
79 int pos = 0, samples = 0, res;
81 while(pos < frame->datalen) {
82 res = g723_len(buf[pos]);
92 static int g723_length(
unsigned int samples)
94 return (samples / 240) * 20;
99 .description =
"G.723.1",
100 .type = AST_MEDIA_TYPE_AUDIO,
106 .samples_count = g723_samples,
107 .get_length = g723_length,
111 static int codec2_samples(
struct ast_frame *frame)
113 return 160 * (frame->
datalen / 6);
116 static int codec2_length(
unsigned int samples)
118 return (samples / 160) * 6;
123 .description =
"Codec 2",
124 .type = AST_MEDIA_TYPE_AUDIO,
130 .samples_count = codec2_samples,
131 .get_length = codec2_length,
135 static int none_samples(
struct ast_frame *frame)
140 static int none_length(
unsigned int samples) {
146 .description =
"<Null> codec",
147 .type = AST_MEDIA_TYPE_AUDIO,
153 .samples_count = none_samples,
154 .get_length = none_length,
157 static int ulaw_samples(
struct ast_frame *frame)
162 static int ulaw_length(
unsigned int samples)
169 .description =
"G.711 u-law",
170 .type = AST_MEDIA_TYPE_AUDIO,
176 .samples_count = ulaw_samples,
177 .get_length = ulaw_length,
184 .description =
"G.711 a-law",
185 .type = AST_MEDIA_TYPE_AUDIO,
191 .samples_count = ulaw_samples,
192 .get_length = ulaw_length,
197 static int gsm_samples(
struct ast_frame *frame)
199 return 160 * (frame->
datalen / 33);
202 static int gsm_length(
unsigned int samples)
204 return (samples / 160) * 33;
209 .description =
"GSM",
210 .type = AST_MEDIA_TYPE_AUDIO,
216 .samples_count = gsm_samples,
217 .get_length = gsm_length,
222 static int g726_samples(
struct ast_frame *frame)
227 static int g726_length(
unsigned int samples)
234 .description =
"G.726 RFC3551",
235 .type = AST_MEDIA_TYPE_AUDIO,
241 .samples_count = g726_samples,
242 .get_length = g726_length,
249 .description =
"G.726 AAL2",
250 .type = AST_MEDIA_TYPE_AUDIO,
256 .samples_count = g726_samples,
257 .get_length = g726_length,
264 .description =
"Dialogic ADPCM",
265 .type = AST_MEDIA_TYPE_AUDIO,
271 .samples_count = g726_samples,
272 .get_length = g726_length,
277 static int slin_samples(
struct ast_frame *frame)
282 static int slin_length(
unsigned int samples)
289 .description =
"16 bit Signed Linear PCM",
290 .type = AST_MEDIA_TYPE_AUDIO,
295 .minimum_bytes = 160,
296 .samples_count = slin_samples,
297 .get_length = slin_length,
299 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
305 .description =
"16 bit Signed Linear PCM (12kHz)",
306 .type = AST_MEDIA_TYPE_AUDIO,
307 .sample_rate = 12000,
311 .minimum_bytes = 240,
312 .samples_count = slin_samples,
313 .get_length = slin_length,
315 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
321 .description =
"16 bit Signed Linear PCM (16kHz)",
322 .type = AST_MEDIA_TYPE_AUDIO,
323 .sample_rate = 16000,
327 .minimum_bytes = 320,
328 .samples_count = slin_samples,
329 .get_length = slin_length,
331 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
337 .description =
"16 bit Signed Linear PCM (24kHz)",
338 .type = AST_MEDIA_TYPE_AUDIO,
339 .sample_rate = 24000,
343 .minimum_bytes = 480,
344 .samples_count = slin_samples,
345 .get_length = slin_length,
347 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
353 .description =
"16 bit Signed Linear PCM (32kHz)",
354 .type = AST_MEDIA_TYPE_AUDIO,
355 .sample_rate = 32000,
359 .minimum_bytes = 640,
360 .samples_count = slin_samples,
361 .get_length = slin_length,
363 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
369 .description =
"16 bit Signed Linear PCM (44kHz)",
370 .type = AST_MEDIA_TYPE_AUDIO,
371 .sample_rate = 44100,
375 .minimum_bytes = 882,
376 .samples_count = slin_samples,
377 .get_length = slin_length,
379 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
385 .description =
"16 bit Signed Linear PCM (48kHz)",
386 .type = AST_MEDIA_TYPE_AUDIO,
387 .sample_rate = 48000,
391 .minimum_bytes = 960,
392 .samples_count = slin_samples,
393 .get_length = slin_length,
395 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
401 .description =
"16 bit Signed Linear PCM (96kHz)",
402 .type = AST_MEDIA_TYPE_AUDIO,
403 .sample_rate = 96000,
407 .minimum_bytes = 1920,
408 .samples_count = slin_samples,
409 .get_length = slin_length,
411 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
417 .description =
"16 bit Signed Linear PCM (192kHz)",
418 .type = AST_MEDIA_TYPE_AUDIO,
419 .sample_rate = 192000,
423 .minimum_bytes = 3840,
424 .samples_count = slin_samples,
425 .get_length = slin_length,
427 .smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
431 static int lpc10_samples(
struct ast_frame *frame)
433 int samples = 22 * 8;
436 samples += (((
char *)(frame->
data.ptr))[7] & 0x1) * 8;
443 .description =
"LPC10",
444 .type = AST_MEDIA_TYPE_AUDIO,
450 .samples_count = lpc10_samples,
455 static int g729_samples(
struct ast_frame *frame)
460 static int g729_length(
unsigned int samples)
467 .description =
"G.729A",
468 .type = AST_MEDIA_TYPE_AUDIO,
474 .samples_count = g729_samples,
475 .get_length = g729_length,
477 .smoother_flags = AST_SMOOTHER_FLAG_G729,
481 static unsigned char get_n_bits_at(
unsigned char *data,
int n,
int bit)
484 int rem = 8 - (bit % 8);
485 unsigned char ret = 0;
491 ret = (data[byte] << (n - rem));
492 ret |= (data[byte + 1] >> (8 - n + rem));
494 ret = (data[byte] >> (rem - n));
497 return (ret & (0xff >> (8 - n)));
500 static int speex_get_wb_sz_at(
unsigned char *data,
int len,
int bit)
502 static const int SpeexWBSubModeSz[] = {
509 if (((len * 8 - off) >= 5) &&
510 get_n_bits_at(data, 1, off)) {
511 c = get_n_bits_at(data, 3, off + 1);
512 off += SpeexWBSubModeSz[c];
514 if (((len * 8 - off) >= 5) &&
515 get_n_bits_at(data, 1, off)) {
516 c = get_n_bits_at(data, 3, off + 1);
517 off += SpeexWBSubModeSz[c];
519 if (((len * 8 - off) >= 5) &&
520 get_n_bits_at(data, 1, off)) {
521 ast_log(LOG_WARNING,
"Encountered corrupt speex frame; too many wideband frames in a row.\n");
530 static int speex_samples(
unsigned char *data,
int len)
532 static const int SpeexSubModeSz[] = {
537 static const int SpeexInBandSz[] = {
547 while ((len * 8 - bit) >= 5) {
549 off = speex_get_wb_sz_at(data, len, bit);
551 ast_log(LOG_WARNING,
"Had error while reading wideband frames for speex samples\n");
556 if ((len * 8 - bit) < 5)
560 c = get_n_bits_at(data, 5, bit);
566 }
else if (c == 14) {
568 c = get_n_bits_at(data, 4, bit);
570 bit += SpeexInBandSz[c];
571 }
else if (c == 13) {
573 c = get_n_bits_at(data, 4, bit);
579 ast_log(LOG_WARNING,
"Unknown speex control frame %d\n", c);
583 bit += SpeexSubModeSz[c] - 5;
590 static int speex8_samples(
struct ast_frame *frame)
592 return speex_samples(frame->
data.ptr, frame->
datalen);
597 .description =
"SpeeX",
598 .type = AST_MEDIA_TYPE_AUDIO,
604 .samples_count = speex8_samples,
608 static int speex16_samples(
struct ast_frame *frame)
610 return 2 * speex_samples(frame->
data.ptr, frame->
datalen);
615 .description =
"SpeeX 16khz",
616 .type = AST_MEDIA_TYPE_AUDIO,
617 .sample_rate = 16000,
622 .samples_count = speex16_samples,
626 static int speex32_samples(
struct ast_frame *frame)
628 return 4 * speex_samples(frame->
data.ptr, frame->
datalen);
633 .description =
"SpeeX 32khz",
634 .type = AST_MEDIA_TYPE_AUDIO,
635 .sample_rate = 32000,
640 .samples_count = speex32_samples,
644 static int ilbc_samples(
struct ast_frame *frame)
647 const unsigned int mode = attr ? attr->mode : 30;
649 const unsigned int octets_per_frame = (mode == 20) ? 38 : 50;
651 return samples_per_frame * frame->
datalen / octets_per_frame;
656 .description =
"iLBC",
657 .type = AST_MEDIA_TYPE_AUDIO,
663 .samples_count = ilbc_samples,
670 .description =
"G722",
671 .type = AST_MEDIA_TYPE_AUDIO,
672 .sample_rate = 16000,
677 .samples_count = g726_samples,
678 .get_length = g726_length,
683 static int siren7_samples(
struct ast_frame *frame)
685 return frame->
datalen * (16000 / 4000);
688 static int siren7_length(
unsigned int samples)
690 return samples / (16000 / 4000);
695 .description =
"ITU G.722.1 (Siren7, licensed from Polycom)",
696 .type = AST_MEDIA_TYPE_AUDIO,
697 .sample_rate = 16000,
702 .samples_count = siren7_samples,
703 .get_length = siren7_length,
707 static int siren14_samples(
struct ast_frame *frame)
709 return (
int) frame->
datalen * ((float) 32000 / 6000);
712 static int siren14_length(
unsigned int samples)
714 return (
int) samples / ((float) 32000 / 6000);;
719 .description =
"ITU G.722.1 Annex C, (Siren14, licensed from Polycom)",
720 .type = AST_MEDIA_TYPE_AUDIO,
721 .sample_rate = 32000,
725 .minimum_bytes = 120,
726 .samples_count = siren14_samples,
727 .get_length = siren14_length,
731 static int g719_samples(
struct ast_frame *frame)
733 return (
int) frame->
datalen * ((float) 48000 / 8000);
736 static int g719_length(
unsigned int samples)
738 return (
int) samples / ((float) 48000 / 8000);
743 .description =
"ITU G.719",
744 .type = AST_MEDIA_TYPE_AUDIO,
745 .sample_rate = 48000,
749 .minimum_bytes = 160,
750 .samples_count = g719_samples,
751 .get_length = g719_length,
755 static int opus_samples(
struct ast_frame *frame)
772 .description =
"Opus Codec",
773 .type = AST_MEDIA_TYPE_AUDIO,
774 .sample_rate = 48000,
778 .samples_count = opus_samples,
785 .description =
"JPEG image",
786 .type = AST_MEDIA_TYPE_IMAGE,
791 .description =
"PNG Image",
792 .type = AST_MEDIA_TYPE_IMAGE,
797 .description =
"H.261 video",
798 .type = AST_MEDIA_TYPE_VIDEO,
804 .description =
"H.263 video",
805 .type = AST_MEDIA_TYPE_VIDEO,
811 .description =
"H.263+ video",
812 .type = AST_MEDIA_TYPE_VIDEO,
818 .description =
"H.264 video",
819 .type = AST_MEDIA_TYPE_VIDEO,
825 .description =
"H.265 video",
826 .type = AST_MEDIA_TYPE_VIDEO,
832 .description =
"MPEG4 video",
833 .type = AST_MEDIA_TYPE_VIDEO,
839 .description =
"VP8 video",
840 .type = AST_MEDIA_TYPE_VIDEO,
846 .description =
"VP9 video",
847 .type = AST_MEDIA_TYPE_VIDEO,
853 .description =
"T.140 Realtime Text with redundancy",
854 .type = AST_MEDIA_TYPE_TEXT,
859 .description =
"Passthrough T.140 Realtime Text",
860 .type = AST_MEDIA_TYPE_TEXT,
865 .description =
"T.38 UDPTL Fax",
866 .type = AST_MEDIA_TYPE_IMAGE,
869 static int silk_samples(
struct ast_frame *frame)
882 .description =
"SILK Codec (8 KHz)",
883 .type = AST_MEDIA_TYPE_AUDIO,
888 .minimum_bytes = 160,
889 .samples_count = silk_samples,
894 .description =
"SILK Codec (12 KHz)",
895 .type = AST_MEDIA_TYPE_AUDIO,
896 .sample_rate = 12000,
900 .minimum_bytes = 240,
901 .samples_count = silk_samples
906 .description =
"SILK Codec (16 KHz)",
907 .type = AST_MEDIA_TYPE_AUDIO,
908 .sample_rate = 16000,
912 .minimum_bytes = 320,
913 .samples_count = silk_samples
918 .description =
"SILK Codec (24 KHz)",
919 .type = AST_MEDIA_TYPE_AUDIO,
920 .sample_rate = 24000,
924 .minimum_bytes = 480,
925 .samples_count = silk_samples
928 #define CODEC_REGISTER_AND_CACHE(codec) \
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), (codec).name, NULL); \
934 __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
935 __fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
936 res |= ast_format_cache_set(__fmt_ ## __LINE__); \
937 ao2_ref(__fmt_ ## __LINE__, -1); \
938 ao2_ref(__codec_ ## __LINE__, -1); \
939 __res_ ## __LINE__; \
942 #define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
944 int __res_ ## __LINE__ = 0; \
945 struct ast_format *__fmt_ ## __LINE__; \
946 struct ast_codec *__codec_ ## __LINE__; \
947 res |= __ast_codec_register_with_format(&(codec), fmt_name, NULL); \
948 __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
949 __fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
950 res |= ast_format_cache_set(__fmt_ ## __LINE__); \
951 ao2_ref(__fmt_ ## __LINE__, -1); \
952 ao2_ref(__codec_ ## __LINE__, -1); \
953 __res_ ## __LINE__; \
960 res |= CODEC_REGISTER_AND_CACHE(codec2);
961 res |= CODEC_REGISTER_AND_CACHE(g723);
962 res |= CODEC_REGISTER_AND_CACHE(ulaw);
963 res |= CODEC_REGISTER_AND_CACHE(alaw);
964 res |= CODEC_REGISTER_AND_CACHE(gsm);
965 res |= CODEC_REGISTER_AND_CACHE(g726rfc3551);
966 res |= CODEC_REGISTER_AND_CACHE(g726aal2);
967 res |= CODEC_REGISTER_AND_CACHE(adpcm);
968 res |= CODEC_REGISTER_AND_CACHE(slin8);
969 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin12", slin12);
970 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin16", slin16);
971 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin24", slin24);
972 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin32", slin32);
973 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin44", slin44);
974 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin48", slin48);
975 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin96", slin96);
976 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"slin192", slin192);
977 res |= CODEC_REGISTER_AND_CACHE(lpc10);
978 res |= CODEC_REGISTER_AND_CACHE(g729a);
979 res |= CODEC_REGISTER_AND_CACHE(speex8);
980 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"speex16", speex16);
981 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"speex32", speex32);
982 res |= CODEC_REGISTER_AND_CACHE(ilbc);
983 res |= CODEC_REGISTER_AND_CACHE(g722);
984 res |= CODEC_REGISTER_AND_CACHE(siren7);
985 res |= CODEC_REGISTER_AND_CACHE(siren14);
986 res |= CODEC_REGISTER_AND_CACHE(g719);
987 res |= CODEC_REGISTER_AND_CACHE(opus);
988 res |= CODEC_REGISTER_AND_CACHE(jpeg);
989 res |= CODEC_REGISTER_AND_CACHE(png);
990 res |= CODEC_REGISTER_AND_CACHE(h261);
991 res |= CODEC_REGISTER_AND_CACHE(h263);
992 res |= CODEC_REGISTER_AND_CACHE(h263p);
993 res |= CODEC_REGISTER_AND_CACHE(h264);
994 res |= CODEC_REGISTER_AND_CACHE(h265);
995 res |= CODEC_REGISTER_AND_CACHE(mpeg4);
996 res |= CODEC_REGISTER_AND_CACHE(vp8);
997 res |= CODEC_REGISTER_AND_CACHE(vp9);
998 res |= CODEC_REGISTER_AND_CACHE(t140red);
999 res |= CODEC_REGISTER_AND_CACHE(t140);
1000 res |= CODEC_REGISTER_AND_CACHE(t38);
1001 res |= CODEC_REGISTER_AND_CACHE(none);
1002 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"silk8", silk8);
1003 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"silk12", silk12);
1004 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"silk16", silk16);
1005 res |= CODEC_REGISTER_AND_CACHE_NAMED(
"silk24", silk24);
const char * name
Name for this codec.
Asterisk main include file. File version handling, generic pbx functions.
int ast_codec_builtin_init(void)
Initialize built-in codecs within the core.
Asterisk internal frame definitions.
struct ast_frame_subclass subclass
Asterisk internal frame definitions.
union ast_frame::@224 data
Support for logging to various files, console and syslog Configuration in file logger.conf.
Data structure associated with a single frame of data.
struct ast_format * format
Represents a media codec within Asterisk.