codec_builtin.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2014, Digium, Inc.
00005  *
00006  * Joshua Colp <jcolp@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Built-in supported codecs
00022  *
00023  * \author Joshua Colp <jcolp@digium.com>
00024  */
00025 
00026 /*** MODULEINFO
00027    <support_level>core</support_level>
00028  ***/
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 433065 $")
00033 
00034 #include "asterisk/logger.h"
00035 #include "asterisk/astobj2.h"
00036 #include "asterisk/codec.h"
00037 #include "asterisk/format.h"
00038 #include "asterisk/format_cache.h"
00039 #include "asterisk/frame.h"
00040 
00041 enum frame_type {
00042    TYPE_HIGH,     /* 0x0 */
00043    TYPE_LOW,      /* 0x1 */
00044    TYPE_SILENCE,  /* 0x2 */
00045    TYPE_DONTSEND  /* 0x3 */
00046 };
00047 
00048 #define TYPE_MASK 0x3
00049 
00050 static int g723_len(unsigned char buf)
00051 {
00052    enum frame_type type = buf & TYPE_MASK;
00053 
00054    switch(type) {
00055    case TYPE_DONTSEND:
00056       return 0;
00057       break;
00058    case TYPE_SILENCE:
00059       return 4;
00060       break;
00061    case TYPE_HIGH:
00062       return 24;
00063       break;
00064    case TYPE_LOW:
00065       return 20;
00066       break;
00067    default:
00068       ast_log(LOG_WARNING, "Badly encoded frame (%u)\n", type);
00069    }
00070    return -1;
00071 }
00072 
00073 static int g723_samples(struct ast_frame *frame)
00074 {
00075    unsigned char *buf = frame->data.ptr;
00076    int pos = 0, samples = 0, res;
00077 
00078    while(pos < frame->datalen) {
00079       res = g723_len(buf[pos]);
00080       if (res <= 0)
00081          break;
00082       samples += 240;
00083       pos += res;
00084    }
00085 
00086    return samples;
00087 }
00088 
00089 static int g723_length(unsigned int samples)
00090 {
00091    return (samples / 240) * 20;
00092 }
00093 
00094 static struct ast_codec g723 = {
00095    .name = "g723",
00096    .description = "G.723.1",
00097    .type = AST_MEDIA_TYPE_AUDIO,
00098    .sample_rate = 8000,
00099    .minimum_ms = 30,
00100    .maximum_ms = 300,
00101    .default_ms = 30,
00102    .minimum_bytes = 20,
00103    .samples_count = g723_samples,
00104    .get_length = g723_length,
00105 };
00106 
00107 static int none_samples(struct ast_frame *frame)
00108 {
00109    return frame->datalen;
00110 }
00111 
00112 static int none_length(unsigned int samples) {
00113    return samples;
00114 }
00115 
00116 static struct ast_codec none = {
00117    .name = "none",
00118    .description = "<Null> codec",
00119    .type = AST_MEDIA_TYPE_AUDIO,
00120    .sample_rate = 8000, /* This must have some sample rate to prevent divide by 0 */
00121    .minimum_ms = 10,
00122    .maximum_ms = 150,
00123    .default_ms = 20,
00124    .minimum_bytes = 20,
00125    .samples_count = none_samples,
00126    .get_length = none_length,
00127 };
00128 
00129 static int ulaw_samples(struct ast_frame *frame)
00130 {
00131    return frame->datalen;
00132 }
00133 
00134 static int ulaw_length(unsigned int samples)
00135 {
00136    return samples;
00137 }
00138 
00139 static struct ast_codec ulaw = {
00140    .name = "ulaw",
00141    .description = "G.711 u-law",
00142    .type = AST_MEDIA_TYPE_AUDIO,
00143    .sample_rate = 8000,
00144    .minimum_ms = 10,
00145    .maximum_ms = 150,
00146    .default_ms = 20,
00147    .minimum_bytes = 80,
00148    .samples_count = ulaw_samples,
00149    .get_length = ulaw_length,
00150    .smooth = 1,
00151 };
00152 
00153 static struct ast_codec alaw = {
00154    .name = "alaw",
00155    .description = "G.711 a-law",
00156    .type = AST_MEDIA_TYPE_AUDIO,
00157    .sample_rate = 8000,
00158    .minimum_ms = 10,
00159    .maximum_ms = 150,
00160    .default_ms = 20,
00161    .minimum_bytes = 80,
00162    .samples_count = ulaw_samples,
00163    .get_length = ulaw_length,
00164    .smooth = 1,
00165 };
00166 
00167 static int gsm_samples(struct ast_frame *frame)
00168 {
00169    return 160 * (frame->datalen / 33);
00170 }
00171 
00172 static int gsm_length(unsigned int samples)
00173 {
00174    return (samples / 160) * 33;
00175 }
00176 
00177 static struct ast_codec gsm = {
00178    .name = "gsm",
00179    .description = "GSM",
00180    .type = AST_MEDIA_TYPE_AUDIO,
00181    .sample_rate = 8000,
00182    .minimum_ms = 20,
00183    .maximum_ms = 300,
00184    .default_ms = 20,
00185    .minimum_bytes = 33,
00186    .samples_count = gsm_samples,
00187    .get_length = gsm_length,
00188    .smooth = 1,
00189 };
00190 
00191 static int g726_samples(struct ast_frame *frame)
00192 {
00193    return frame->datalen * 2;
00194 }
00195 
00196 static int g726_length(unsigned int samples)
00197 {
00198    return samples / 2;
00199 }
00200 
00201 static struct ast_codec g726rfc3551 = {
00202    .name = "g726",
00203    .description = "G.726 RFC3551",
00204    .type = AST_MEDIA_TYPE_AUDIO,
00205    .sample_rate = 8000,
00206    .minimum_ms = 10,
00207    .maximum_ms = 300,
00208    .default_ms = 20,
00209    .minimum_bytes = 40,
00210    .samples_count = g726_samples,
00211    .get_length = g726_length,
00212    .smooth = 1,
00213 };
00214 
00215 static struct ast_codec g726aal2 = {
00216    .name = "g726aal2",
00217    .description = "G.726 AAL2",
00218    .type = AST_MEDIA_TYPE_AUDIO,
00219    .sample_rate = 8000,
00220    .minimum_ms = 10,
00221    .maximum_ms = 300,
00222    .default_ms = 20,
00223    .minimum_bytes = 40,
00224    .samples_count = g726_samples,
00225    .get_length = g726_length,
00226    .smooth = 1,
00227 };
00228 
00229 static struct ast_codec adpcm = {
00230    .name = "adpcm",
00231    .description = "Dialogic ADPCM",
00232    .type = AST_MEDIA_TYPE_AUDIO,
00233    .sample_rate = 8000,
00234    .minimum_ms = 10,
00235    .maximum_ms = 300,
00236    .default_ms = 20,
00237    .minimum_bytes = 40,
00238    .samples_count = g726_samples,
00239    .get_length = g726_length,
00240    .smooth = 1,
00241 };
00242 
00243 static int slin_samples(struct ast_frame *frame)
00244 {
00245    return frame->datalen / 2;
00246 }
00247 
00248 static int slin_length(unsigned int samples)
00249 {
00250    return samples * 2;
00251 }
00252 
00253 static struct ast_codec slin8 = {
00254    .name = "slin",
00255    .description = "16 bit Signed Linear PCM",
00256    .type = AST_MEDIA_TYPE_AUDIO,
00257    .sample_rate = 8000,
00258    .minimum_ms = 10,
00259    .maximum_ms = 70,
00260    .default_ms = 20,
00261    .minimum_bytes = 160,
00262    .samples_count = slin_samples,
00263    .get_length = slin_length,
00264    .smooth = 1,
00265 };
00266 
00267 static struct ast_codec slin12 = {
00268    .name = "slin",
00269    .description = "16 bit Signed Linear PCM (12kHz)",
00270    .type = AST_MEDIA_TYPE_AUDIO,
00271    .sample_rate = 12000,
00272    .minimum_ms = 10,
00273    .maximum_ms = 70,
00274    .default_ms = 20,
00275    .minimum_bytes = 240,
00276    .samples_count = slin_samples,
00277    .get_length = slin_length,
00278    .smooth = 1,
00279 };
00280 
00281 static struct ast_codec slin16 = {
00282    .name = "slin",
00283    .description = "16 bit Signed Linear PCM (16kHz)",
00284    .type = AST_MEDIA_TYPE_AUDIO,
00285    .sample_rate = 16000,
00286    .minimum_ms = 10,
00287    .maximum_ms = 70,
00288    .default_ms = 20,
00289    .minimum_bytes = 320,
00290    .samples_count = slin_samples,
00291    .get_length = slin_length,
00292    .smooth = 1,
00293 };
00294 
00295 static struct ast_codec slin24 = {
00296    .name = "slin",
00297    .description = "16 bit Signed Linear PCM (24kHz)",
00298    .type = AST_MEDIA_TYPE_AUDIO,
00299    .sample_rate = 24000,
00300    .minimum_ms = 10,
00301    .maximum_ms = 70,
00302    .default_ms = 20,
00303    .minimum_bytes = 480,
00304    .samples_count = slin_samples,
00305    .get_length = slin_length,
00306    .smooth = 1,
00307 };
00308 
00309 static struct ast_codec slin32 = {
00310    .name = "slin",
00311    .description = "16 bit Signed Linear PCM (32kHz)",
00312    .type = AST_MEDIA_TYPE_AUDIO,
00313    .sample_rate = 32000,
00314    .minimum_ms = 10,
00315    .maximum_ms = 70,
00316    .default_ms = 20,
00317    .minimum_bytes = 640,
00318    .samples_count = slin_samples,
00319    .get_length = slin_length,
00320    .smooth = 1,
00321 };
00322 
00323 static struct ast_codec slin44 = {
00324    .name = "slin",
00325    .description = "16 bit Signed Linear PCM (44kHz)",
00326    .type = AST_MEDIA_TYPE_AUDIO,
00327    .sample_rate = 44100,
00328    .minimum_ms = 10,
00329    .maximum_ms = 70,
00330    .default_ms = 20,
00331    .minimum_bytes = 882,
00332    .samples_count = slin_samples,
00333    .get_length = slin_length,
00334    .smooth = 1,
00335 };
00336 
00337 static struct ast_codec slin48 = {
00338    .name = "slin",
00339    .description = "16 bit Signed Linear PCM (48kHz)",
00340    .type = AST_MEDIA_TYPE_AUDIO,
00341    .sample_rate = 48000,
00342    .minimum_ms = 10,
00343    .maximum_ms = 70,
00344    .default_ms = 20,
00345    .minimum_bytes = 960,
00346    .samples_count = slin_samples,
00347    .get_length = slin_length,
00348    .smooth = 1,
00349 };
00350 
00351 static struct ast_codec slin96 = {
00352    .name = "slin",
00353    .description = "16 bit Signed Linear PCM (96kHz)",
00354    .type = AST_MEDIA_TYPE_AUDIO,
00355    .sample_rate = 96000,
00356    .minimum_ms = 10,
00357    .maximum_ms = 70,
00358    .default_ms = 20,
00359    .minimum_bytes = 1920,
00360    .samples_count = slin_samples,
00361    .get_length = slin_length,
00362    .smooth = 1,
00363 };
00364 
00365 static struct ast_codec slin192 = {
00366    .name = "slin",
00367    .description = "16 bit Signed Linear PCM (192kHz)",
00368    .type = AST_MEDIA_TYPE_AUDIO,
00369    .sample_rate = 192000,
00370    .minimum_ms = 10,
00371    .maximum_ms = 70,
00372    .default_ms = 20,
00373    .minimum_bytes = 3840,
00374    .samples_count = slin_samples,
00375    .get_length = slin_length,
00376    .smooth = 1,
00377 };
00378 
00379 static int lpc10_samples(struct ast_frame *frame)
00380 {
00381    int samples = 22 * 8;
00382 
00383    /* assumes that the RTP packet contains one LPC10 frame */
00384    samples += (((char *)(frame->data.ptr))[7] & 0x1) * 8;
00385 
00386    return samples;
00387 }
00388 
00389 static struct ast_codec lpc10 = {
00390    .name = "lpc10",
00391    .description = "LPC10",
00392    .type = AST_MEDIA_TYPE_AUDIO,
00393    .sample_rate = 8000,
00394    .minimum_ms = 20,
00395    .maximum_ms = 20,
00396    .default_ms = 20,
00397    .minimum_bytes = 7,
00398    .samples_count = lpc10_samples,
00399    .smooth = 1,
00400 };
00401 
00402 static int g729_samples(struct ast_frame *frame)
00403 {
00404    return frame->datalen * 8;
00405 }
00406 
00407 static int g729_length(unsigned int samples)
00408 {
00409    return samples / 8;
00410 }
00411 
00412 static struct ast_codec g729a = {
00413    .name = "g729",
00414    .description = "G.729A",
00415    .type = AST_MEDIA_TYPE_AUDIO,
00416    .sample_rate = 8000,
00417    .minimum_ms = 10,
00418    .maximum_ms = 230,
00419    .default_ms = 20,
00420    .minimum_bytes = 10,
00421    .samples_count = g729_samples,
00422    .get_length = g729_length,
00423    .smooth = 1,
00424 };
00425 
00426 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
00427 {
00428    int byte = bit / 8;       /* byte containing first bit */
00429    int rem = 8 - (bit % 8);  /* remaining bits in first byte */
00430    unsigned char ret = 0;
00431 
00432    if (n <= 0 || n > 8)
00433       return 0;
00434 
00435    if (rem < n) {
00436       ret = (data[byte] << (n - rem));
00437       ret |= (data[byte + 1] >> (8 - n + rem));
00438    } else {
00439       ret = (data[byte] >> (rem - n));
00440    }
00441 
00442    return (ret & (0xff >> (8 - n)));
00443 }
00444 
00445 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
00446 {
00447    static const int SpeexWBSubModeSz[] = {
00448       4, 36, 112, 192,
00449       352, 0, 0, 0 };
00450    int off = bit;
00451    unsigned char c;
00452 
00453    /* skip up to two wideband frames */
00454    if (((len * 8 - off) >= 5) &&
00455       get_n_bits_at(data, 1, off)) {
00456       c = get_n_bits_at(data, 3, off + 1);
00457       off += SpeexWBSubModeSz[c];
00458 
00459       if (((len * 8 - off) >= 5) &&
00460          get_n_bits_at(data, 1, off)) {
00461          c = get_n_bits_at(data, 3, off + 1);
00462          off += SpeexWBSubModeSz[c];
00463 
00464          if (((len * 8 - off) >= 5) &&
00465             get_n_bits_at(data, 1, off)) {
00466             ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
00467             return -1;
00468          }
00469       }
00470 
00471    }
00472    return off - bit;
00473 }
00474 
00475 static int speex_samples(unsigned char *data, int len)
00476 {
00477    static const int SpeexSubModeSz[] = {
00478       5, 43, 119, 160,
00479       220, 300, 364, 492,
00480       79, 0, 0, 0,
00481       0, 0, 0, 0 };
00482    static const int SpeexInBandSz[] = {
00483       1, 1, 4, 4,
00484       4, 4, 4, 4,
00485       8, 8, 16, 16,
00486       32, 32, 64, 64 };
00487    int bit = 0;
00488    int cnt = 0;
00489    int off;
00490    unsigned char c;
00491 
00492    while ((len * 8 - bit) >= 5) {
00493       /* skip wideband frames */
00494       off = speex_get_wb_sz_at(data, len, bit);
00495       if (off < 0)  {
00496          ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
00497          break;
00498       }
00499       bit += off;
00500 
00501       if ((len * 8 - bit) < 5)
00502          break;
00503 
00504       /* get control bits */
00505       c = get_n_bits_at(data, 5, bit);
00506       bit += 5;
00507 
00508       if (c == 15) {
00509          /* terminator */
00510          break;
00511       } else if (c == 14) {
00512          /* in-band signal; next 4 bits contain signal id */
00513          c = get_n_bits_at(data, 4, bit);
00514          bit += 4;
00515          bit += SpeexInBandSz[c];
00516       } else if (c == 13) {
00517          /* user in-band; next 4 bits contain msg len */
00518          c = get_n_bits_at(data, 4, bit);
00519          bit += 4;
00520          /* after which it's 5-bit signal id + c bytes of data */
00521          bit += 5 + c * 8;
00522       } else if (c > 8) {
00523          /* unknown */
00524          ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
00525          break;
00526       } else {
00527          /* skip number bits for submode (less the 5 control bits) */
00528          bit += SpeexSubModeSz[c] - 5;
00529          cnt += 160; /* new frame */
00530       }
00531    }
00532    return cnt;
00533 }
00534 
00535 static int speex8_samples(struct ast_frame *frame)
00536 {
00537    return speex_samples(frame->data.ptr, frame->datalen);
00538 }
00539 
00540 static struct ast_codec speex8 = {
00541    .name = "speex",
00542    .description = "SpeeX",
00543    .type = AST_MEDIA_TYPE_AUDIO,
00544    .sample_rate = 8000,
00545    .minimum_ms = 10,
00546    .maximum_ms = 60,
00547    .default_ms = 20,
00548    .minimum_bytes = 10,
00549    .samples_count = speex8_samples,
00550 };
00551 
00552 static int speex16_samples(struct ast_frame *frame)
00553 {
00554    return 2 * speex_samples(frame->data.ptr, frame->datalen);
00555 }
00556 
00557 static struct ast_codec speex16 = {
00558    .name = "speex",
00559    .description = "SpeeX 16khz",
00560    .type = AST_MEDIA_TYPE_AUDIO,
00561    .sample_rate = 16000,
00562    .minimum_ms = 10,
00563    .maximum_ms = 60,
00564    .default_ms = 20,
00565    .minimum_bytes = 10,
00566    .samples_count = speex16_samples,
00567 };
00568 
00569 static int speex32_samples(struct ast_frame *frame)
00570 {
00571    return 4 * speex_samples(frame->data.ptr, frame->datalen);
00572 }
00573 
00574 static struct ast_codec speex32 = {
00575    .name = "speex",
00576    .description = "SpeeX 32khz",
00577    .type = AST_MEDIA_TYPE_AUDIO,
00578    .sample_rate = 32000,
00579    .minimum_ms = 10,
00580    .maximum_ms = 60,
00581    .default_ms = 20,
00582    .minimum_bytes = 10,
00583    .samples_count = speex32_samples,
00584 };
00585 
00586 static int ilbc_samples(struct ast_frame *frame)
00587 {
00588    return 240 * (frame->datalen / 50);
00589 }
00590 
00591 static struct ast_codec ilbc = {
00592    .name = "ilbc",
00593    .description = "iLBC",
00594    .type = AST_MEDIA_TYPE_AUDIO,
00595    .sample_rate = 8000,
00596    .minimum_ms = 30,
00597    .maximum_ms = 30,
00598    .default_ms = 30,
00599    .minimum_bytes = 50,
00600    .samples_count = ilbc_samples,
00601    .smooth = 1,
00602 };
00603 
00604 static struct ast_codec g722 = {
00605    .name = "g722",
00606    .description = "G722",
00607    .type = AST_MEDIA_TYPE_AUDIO,
00608    .sample_rate = 16000,
00609    .minimum_ms = 10,
00610    .maximum_ms = 150,
00611    .default_ms = 20,
00612    .minimum_bytes = 80,
00613    .samples_count = g726_samples,
00614    .get_length = g726_length,
00615    .smooth = 1,
00616 };
00617 
00618 static int siren7_samples(struct ast_frame *frame)
00619 {
00620    return frame->datalen * (16000 / 4000);
00621 }
00622 
00623 static int siren7_length(unsigned int samples)
00624 {
00625    return samples / (16000 / 4000);
00626 }
00627 
00628 static struct ast_codec siren7 = {
00629    .name = "siren7",
00630    .description = "ITU G.722.1 (Siren7, licensed from Polycom)",
00631    .type = AST_MEDIA_TYPE_AUDIO,
00632    .sample_rate = 16000,
00633    .minimum_ms = 20,
00634    .maximum_ms = 80,
00635    .default_ms = 20,
00636    .minimum_bytes = 80,
00637    .samples_count = siren7_samples,
00638    .get_length = siren7_length,
00639 };
00640 
00641 static int siren14_samples(struct ast_frame *frame)
00642 {
00643    return (int) frame->datalen * ((float) 32000 / 6000);
00644 }
00645 
00646 static int siren14_length(unsigned int samples)
00647 {
00648    return (int) samples / ((float) 32000 / 6000);;
00649 }
00650 
00651 static struct ast_codec siren14 = {
00652    .name = "siren14",
00653    .description = "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)",
00654    .type = AST_MEDIA_TYPE_AUDIO,
00655    .sample_rate = 32000,
00656    .minimum_ms = 20,
00657    .maximum_ms = 80,
00658    .default_ms = 20,
00659    .minimum_bytes = 120,
00660    .samples_count = siren14_samples,
00661    .get_length = siren14_length,
00662 };
00663 
00664 static struct ast_codec testlaw = {
00665    .name = "testlaw",
00666    .description = "G.711 test-law",
00667    .type = AST_MEDIA_TYPE_AUDIO,
00668    .sample_rate = 8000,
00669    .minimum_ms = 10,
00670    .maximum_ms = 150,
00671    .default_ms = 20,
00672    .minimum_bytes = 80,
00673    .samples_count = ulaw_samples,
00674    .get_length = ulaw_length,
00675    .smooth = 1,
00676 };
00677 
00678 static int g719_samples(struct ast_frame *frame)
00679 {
00680    return (int) frame->datalen * ((float) 48000 / 8000);
00681 }
00682 
00683 static int g719_length(unsigned int samples)
00684 {
00685    return (int) samples / ((float) 48000 / 8000);
00686 }
00687 
00688 static struct ast_codec g719 = {
00689    .name = "g719",
00690    .description = "ITU G.719",
00691    .type = AST_MEDIA_TYPE_AUDIO,
00692    .sample_rate = 48000,
00693    .minimum_ms = 20,
00694    .maximum_ms = 80,
00695    .default_ms = 20,
00696    .minimum_bytes = 160,
00697    .samples_count = g719_samples,
00698    .get_length = g719_length,
00699 };
00700 
00701 static struct ast_codec opus = {
00702    .name = "opus",
00703    .description = "Opus Codec",
00704    .type = AST_MEDIA_TYPE_AUDIO,
00705    .sample_rate = 48000,
00706    .minimum_ms = 20,
00707    .maximum_ms = 60,
00708    .default_ms = 20,
00709    .minimum_bytes = 10,
00710 };
00711 
00712 static struct ast_codec jpeg = {
00713    .name = "jpeg",
00714    .description = "JPEG image",
00715    .type = AST_MEDIA_TYPE_IMAGE,
00716 };
00717 
00718 static struct ast_codec png = {
00719    .name = "png",
00720    .description = "PNG Image",
00721    .type = AST_MEDIA_TYPE_IMAGE,
00722 };
00723 
00724 static struct ast_codec h261 = {
00725    .name = "h261",
00726    .description = "H.261 video",
00727    .type = AST_MEDIA_TYPE_VIDEO,
00728 };
00729 
00730 static struct ast_codec h263 = {
00731    .name = "h263",
00732    .description = "H.263 video",
00733    .type = AST_MEDIA_TYPE_VIDEO,
00734 };
00735 
00736 static struct ast_codec h263p = {
00737    .name = "h263p",
00738    .description = "H.263+ video",
00739    .type = AST_MEDIA_TYPE_VIDEO,
00740 };
00741 
00742 static struct ast_codec h264 = {
00743    .name = "h264",
00744    .description = "H.264 video",
00745    .type = AST_MEDIA_TYPE_VIDEO,
00746 };
00747 
00748 static struct ast_codec mpeg4 = {
00749    .name = "mpeg4",
00750    .description = "MPEG4 video",
00751    .type = AST_MEDIA_TYPE_VIDEO,
00752 };
00753 
00754 static struct ast_codec vp8 = {
00755    .name = "vp8",
00756    .description = "VP8 video",
00757    .type = AST_MEDIA_TYPE_VIDEO,
00758 };
00759 
00760 static struct ast_codec t140red = {
00761    .name = "red",
00762    .description = "T.140 Realtime Text with redundancy",
00763    .type = AST_MEDIA_TYPE_TEXT,
00764 };
00765 
00766 static struct ast_codec t140 = {
00767    .name = "t140",
00768    .description = "Passthrough T.140 Realtime Text",
00769    .type = AST_MEDIA_TYPE_TEXT,
00770 };
00771 
00772 #define CODEC_REGISTER_AND_CACHE(codec) \
00773    ({ \
00774       int __res_ ## __LINE__ = 0; \
00775       struct ast_format *__fmt_ ## __LINE__; \
00776       struct ast_codec *__codec_ ## __LINE__; \
00777       res |= __ast_codec_register(&(codec), NULL); \
00778       __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
00779       __fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
00780       res |= ast_format_cache_set(__fmt_ ## __LINE__); \
00781       ao2_ref(__fmt_ ## __LINE__, -1); \
00782       ao2_ref(__codec_ ## __LINE__, -1); \
00783       __res_ ## __LINE__; \
00784    })
00785 
00786 #define CODEC_REGISTER_AND_CACHE_NAMED(format_name, codec) \
00787    ({ \
00788       int __res_ ## __LINE__ = 0; \
00789       struct ast_format *__fmt_ ## __LINE__; \
00790       struct ast_codec *__codec_ ## __LINE__; \
00791       res |= __ast_codec_register(&(codec), NULL); \
00792       __codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
00793       __fmt_ ## __LINE__ = ast_format_create_named((format_name), __codec_ ## __LINE__); \
00794       res |= ast_format_cache_set(__fmt_ ## __LINE__); \
00795       ao2_ref(__fmt_ ## __LINE__, -1); \
00796       ao2_ref(__codec_ ## __LINE__, -1); \
00797       __res_ ## __LINE__; \
00798    })
00799 
00800 int ast_codec_builtin_init(void)
00801 {
00802    int res = 0;
00803 
00804    res |= CODEC_REGISTER_AND_CACHE(g723);
00805    res |= CODEC_REGISTER_AND_CACHE(ulaw);
00806    res |= CODEC_REGISTER_AND_CACHE(alaw);
00807    res |= CODEC_REGISTER_AND_CACHE(gsm);
00808    res |= CODEC_REGISTER_AND_CACHE(g726rfc3551);
00809    res |= CODEC_REGISTER_AND_CACHE(g726aal2);
00810    res |= CODEC_REGISTER_AND_CACHE(adpcm);
00811    res |= CODEC_REGISTER_AND_CACHE(slin8);
00812    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin12", slin12);
00813    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin16", slin16);
00814    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin24", slin24);
00815    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin32", slin32);
00816    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin44", slin44);
00817    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin48", slin48);
00818    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin96", slin96);
00819    res |= CODEC_REGISTER_AND_CACHE_NAMED("slin192", slin192);
00820    res |= CODEC_REGISTER_AND_CACHE(lpc10);
00821    res |= CODEC_REGISTER_AND_CACHE(g729a);
00822    res |= CODEC_REGISTER_AND_CACHE(speex8);
00823    res |= CODEC_REGISTER_AND_CACHE_NAMED("speex16", speex16);
00824    res |= CODEC_REGISTER_AND_CACHE_NAMED("speex32", speex32);
00825    res |= CODEC_REGISTER_AND_CACHE(ilbc);
00826    res |= CODEC_REGISTER_AND_CACHE(g722);
00827    res |= CODEC_REGISTER_AND_CACHE(siren7);
00828    res |= CODEC_REGISTER_AND_CACHE(siren14);
00829    res |= CODEC_REGISTER_AND_CACHE(testlaw);
00830    res |= CODEC_REGISTER_AND_CACHE(g719);
00831    res |= CODEC_REGISTER_AND_CACHE(opus);
00832    res |= CODEC_REGISTER_AND_CACHE(jpeg);
00833    res |= CODEC_REGISTER_AND_CACHE(png);
00834    res |= CODEC_REGISTER_AND_CACHE(h261);
00835    res |= CODEC_REGISTER_AND_CACHE(h263);
00836    res |= CODEC_REGISTER_AND_CACHE(h263p);
00837    res |= CODEC_REGISTER_AND_CACHE(h264);
00838    res |= CODEC_REGISTER_AND_CACHE(mpeg4);
00839    res |= CODEC_REGISTER_AND_CACHE(vp8);
00840    res |= CODEC_REGISTER_AND_CACHE(t140red);
00841    res |= CODEC_REGISTER_AND_CACHE(t140);
00842    res |= CODEC_REGISTER_AND_CACHE(none);
00843 
00844    return res;
00845 }

Generated on Thu Apr 16 06:27:30 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6