Wed Aug 18 22:34:20 2010

Asterisk developer's documentation


codec_dahdi.c File Reference

Translate between various formats natively through DAHDI transcoding. More...

#include "asterisk.h"
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/translate.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/ulaw.h"

Go to the source code of this file.

Data Structures

struct  channel_usage
struct  codec_dahdi_pvt
struct  format_map
struct  translator
struct  translators
 the list of translators More...

Defines

#define BUFFER_SIZE   8000
#define G723_SAMPLES   240
#define G729_SAMPLES   160

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void build_translators (struct format_map *map, unsigned int dstfmts, unsigned int srcfmts)
static int dahdi_decoder_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_framedahdi_decoder_frameout (struct ast_trans_pvt *pvt)
static void dahdi_destroy (struct ast_trans_pvt *pvt)
static int dahdi_encoder_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_framedahdi_encoder_frameout (struct ast_trans_pvt *pvt)
static int dahdi_new (struct ast_trans_pvt *pvt)
static int dahdi_translate (struct ast_trans_pvt *pvt, int dest, int source)
static void dahdi_write_frame (struct codec_dahdi_pvt *dahdip, const uint8_t *buffer, const ssize_t count)
static void drop_translator (int dst, int src)
static struct ast_framefakesrc_sample (void)
static int find_transcoders (void)
static char * handle_cli_transcoder_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int is_encoder (struct translator *zt)
static int lintoulaw (struct ast_trans_pvt *pvt, struct ast_frame *f)
static int load_module (void)
static int parse_config (int reload)
static int register_translator (int dst, int src)
static int reload (void)
static int ulawtolin (struct ast_trans_pvt *pvt)
static int unload_module (void)
static void unregister_translators (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Generic DAHDI Transcoder Codec Translator" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_module_infoast_module_info = &__mod_info
static struct channel_usage channels
static struct ast_cli_entry cli []
static struct format_map global_format_map = { { { 0 } } }
static unsigned int global_useplc = 0


Detailed Description

Translate between various formats natively through DAHDI transcoding.

Definition in file codec_dahdi.c.


Define Documentation

#define BUFFER_SIZE   8000

Definition at line 54 of file codec_dahdi.c.

Referenced by register_translator().

#define G723_SAMPLES   240

Definition at line 56 of file codec_dahdi.c.

Referenced by dahdi_translate(), and register_translator().

#define G729_SAMPLES   160

Definition at line 57 of file codec_dahdi.c.

Referenced by dahdi_translate(), and register_translator().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 702 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 702 of file codec_dahdi.c.

static void build_translators ( struct format_map map,
unsigned int  dstfmts,
unsigned int  srcfmts 
) [static]

Definition at line 593 of file codec_dahdi.c.

References global_format_map, map, format_map::map, and register_translator().

00594 {
00595    unsigned int src, dst;
00596 
00597    for (src = 0; src < 32; src++) {
00598       for (dst = 0; dst < 32; dst++) {
00599          if (!(srcfmts & (1 << src)))
00600             continue;
00601 
00602          if (!(dstfmts & (1 << dst)))
00603             continue;
00604 
00605          if (global_format_map.map[dst][src])
00606             continue;
00607 
00608          if (!register_translator(dst, src))
00609             map->map[dst][src] = 1;
00610       }
00611    }
00612 }

static int dahdi_decoder_framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
) [static]

Definition at line 279 of file codec_dahdi.c.

References ast_log(), dahdi_write_frame(), ast_trans_pvt::datalen, f, codec_dahdi_pvt::fake, LOG_ERROR, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and ast_trans_pvt::samples.

Referenced by register_translator().

00280 {
00281    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00282 
00283    if (!f->subclass) {
00284       /* We're just faking a return for calculation purposes. */
00285       dahdip->fake = 2;
00286       pvt->samples = f->samples;
00287       return 0;
00288    }
00289 
00290    if (!f->datalen) {
00291       if (f->samples != dahdip->required_samples) {
00292          ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, dahdip->required_samples, f->datalen);
00293       }
00294    }
00295    dahdi_write_frame(dahdip, f->data.ptr, f->datalen);
00296    pvt->samples += f->samples;
00297    pvt->datalen = 0;
00298    return -1;
00299 }

static struct ast_frame* dahdi_decoder_frameout ( struct ast_trans_pvt pvt  )  [static]

Definition at line 301 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), ast_translator::buf_size, ast_trans_pvt::c, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, errno, ast_trans_pvt::f, codec_dahdi_pvt::fake, codec_dahdi_pvt::fd, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, ast_frame::samples, codec_dahdi_pvt::softslin, ast_frame::src, ast_frame::subclass, ast_trans_pvt::t, codec_dahdi_pvt::ulaw_buffer, and ulawtolin.

Referenced by register_translator().

00302 {
00303    int res;
00304    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00305 
00306    if (2 == dahdip->fake) {
00307       dahdip->fake = 1;
00308       pvt->f.frametype = AST_FRAME_VOICE;
00309       pvt->f.subclass = 0;
00310       pvt->f.samples = dahdip->required_samples;
00311       pvt->f.data.ptr = NULL;
00312       pvt->f.offset = 0;
00313       pvt->f.datalen = 0;
00314       pvt->f.mallocd = 0;
00315       pvt->samples = 0;
00316       return ast_frisolate(&pvt->f);
00317    } else if (1 == dahdip->fake) {
00318       pvt->samples = 0;
00319       dahdip->fake = 0;
00320       return NULL;
00321    }
00322 
00323    /* Let's check to see if there is a new frame for us.... */
00324    if (dahdip->softslin) {
00325       res = read(dahdip->fd, dahdip->ulaw_buffer, sizeof(dahdip->ulaw_buffer));
00326    } else {
00327       res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
00328    }
00329 
00330    if (-1 == res) {
00331       if (EWOULDBLOCK == errno) {
00332          /* Nothing waiting... */
00333          return NULL;
00334       } else {
00335          ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
00336          return NULL;
00337       }
00338    } else {
00339       if (dahdip->softslin) {
00340          ulawtolin(pvt);
00341          pvt->f.datalen = res * 2;
00342       } else {
00343          pvt->f.datalen = res;
00344       }
00345       pvt->datalen = 0;
00346       pvt->f.frametype = AST_FRAME_VOICE;
00347       pvt->f.subclass = 1 <<  (pvt->t->dstfmt);
00348       pvt->f.mallocd = 0;
00349       pvt->f.offset = AST_FRIENDLY_OFFSET;
00350       pvt->f.src = pvt->t->name;
00351       pvt->f.data.ptr = pvt->outbuf.c;
00352       pvt->f.samples = dahdip->required_samples;
00353       pvt->samples = 0;
00354 
00355       return ast_frisolate(&pvt->f);
00356    }
00357 
00358    /* Shouldn't get here... */
00359    return NULL;
00360 }

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

Definition at line 363 of file codec_dahdi.c.

References ast_atomic_fetchadd_int(), AST_FORMAT_G723_1, AST_FORMAT_G729A, codec_dahdi_pvt::fd, codec_dahdi_pvt::fmts, and ast_trans_pvt::pvt.

Referenced by register_translator().

00364 {
00365    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00366 
00367    switch (dahdip->fmts.dstfmt) {
00368    case AST_FORMAT_G729A:
00369    case AST_FORMAT_G723_1:
00370       ast_atomic_fetchadd_int(&channels.encoders, -1);
00371       break;
00372    default:
00373       ast_atomic_fetchadd_int(&channels.decoders, -1);
00374       break;
00375    }
00376 
00377    close(dahdip->fd);
00378 }

static int dahdi_encoder_framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
) [static]

Definition at line 184 of file codec_dahdi.c.

References ast_log(), dahdi_write_frame(), ast_trans_pvt::datalen, f, codec_dahdi_pvt::fake, lintoulaw, LOG_ERROR, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, codec_dahdi_pvt::samples_in_buffer, codec_dahdi_pvt::softslin, and codec_dahdi_pvt::ulaw_buffer.

Referenced by register_translator().

00185 {
00186    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00187 
00188    if (!f->subclass) {
00189       /* We're just faking a return for calculation purposes. */
00190       dahdip->fake = 2;
00191       pvt->samples = f->samples;
00192       return 0;
00193    }
00194 
00195    /* Buffer up the packets and send them to the hardware if we
00196     * have enough samples set up. */
00197    if (dahdip->softslin) {
00198       if (lintoulaw(pvt, f)) {
00199           return -1;
00200       }
00201    } else {
00202       /* NOTE:  If softslin support is not needed, and the sample
00203        * size is equal to the required sample size, we wouldn't
00204        * need this copy operation.  But at the time this was
00205        * written, only softslin is supported. */
00206       if (dahdip->samples_in_buffer + f->samples > sizeof(dahdip->ulaw_buffer)) {
00207          ast_log(LOG_ERROR, "Out of buffer space.\n");
00208          return -1;
00209       }
00210       memcpy(&dahdip->ulaw_buffer[dahdip->samples_in_buffer], f->data.ptr, f->samples);
00211       dahdip->samples_in_buffer += f->samples;
00212    }
00213 
00214    while (dahdip->samples_in_buffer > dahdip->required_samples) {
00215       dahdi_write_frame(dahdip, dahdip->ulaw_buffer, dahdip->required_samples);
00216       dahdip->samples_in_buffer -= dahdip->required_samples;
00217       if (dahdip->samples_in_buffer) {
00218          /* Shift any remaining bytes down. */
00219          memmove(dahdip->ulaw_buffer, &dahdip->ulaw_buffer[dahdip->required_samples],
00220             dahdip->samples_in_buffer);
00221       }
00222    }
00223    pvt->samples += f->samples;
00224    pvt->datalen = 0;
00225    return -1;
00226 }

static struct ast_frame* dahdi_encoder_frameout ( struct ast_trans_pvt pvt  )  [static]

Definition at line 228 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), ast_translator::buf_size, ast_trans_pvt::c, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, errno, ast_trans_pvt::f, codec_dahdi_pvt::fake, codec_dahdi_pvt::fd, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_trans_pvt::t.

Referenced by register_translator().

00229 {
00230    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00231    int res;
00232 
00233    if (2 == dahdip->fake) {
00234       dahdip->fake = 1;
00235       pvt->f.frametype = AST_FRAME_VOICE;
00236       pvt->f.subclass = 0;
00237       pvt->f.samples = dahdip->required_samples;
00238       pvt->f.data.ptr = NULL;
00239       pvt->f.offset = 0;
00240       pvt->f.datalen = 0;
00241       pvt->f.mallocd = 0;
00242       pvt->samples = 0;
00243 
00244       return ast_frisolate(&pvt->f);
00245 
00246    } else if (1 == dahdip->fake) {
00247       dahdip->fake = 0;
00248       return NULL;
00249    }
00250 
00251    res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
00252    if (-1 == res) {
00253       if (EWOULDBLOCK == errno) {
00254          /* Nothing waiting... */
00255          return NULL;
00256       } else {
00257          ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
00258          return NULL;
00259       }
00260    } else {
00261       pvt->f.datalen = res;
00262       pvt->f.samples = dahdip->required_samples;
00263       pvt->f.frametype = AST_FRAME_VOICE;
00264       pvt->f.subclass = 1 <<  (pvt->t->dstfmt);
00265       pvt->f.mallocd = 0;
00266       pvt->f.offset = AST_FRIENDLY_OFFSET;
00267       pvt->f.src = pvt->t->name;
00268       pvt->f.data.ptr = pvt->outbuf.c;
00269 
00270       pvt->samples = 0;
00271       pvt->datalen = 0;
00272       return ast_frisolate(&pvt->f);
00273    }
00274 
00275    /* Shouldn't get here... */
00276    return NULL;
00277 }

static int dahdi_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 453 of file codec_dahdi.c.

References dahdi_translate(), ast_translator::dstfmt, ast_translator::srcfmt, and ast_trans_pvt::t.

00454 {
00455    return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
00456 }

static int dahdi_translate ( struct ast_trans_pvt pvt,
int  dest,
int  source 
) [static]

Definition at line 380 of file codec_dahdi.c.

References ast_atomic_fetchadd_int(), ast_debug, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), errno, codec_dahdi_pvt::fd, codec_dahdi_pvt::fmts, G723_SAMPLES, G729_SAMPLES, LOG_ERROR, LOG_WARNING, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::softslin.

Referenced by dahdi_new().

00381 {
00382    /* Request translation through zap if possible */
00383    int fd;
00384    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00385    int flags;
00386    int tried_once = 0;
00387    const char *dev_filename = "/dev/dahdi/transcode";
00388 
00389    if ((fd = open(dev_filename, O_RDWR)) < 0) {
00390       ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno));
00391       return -1;
00392    }
00393 
00394    dahdip->fmts.srcfmt = (1 << source);
00395    dahdip->fmts.dstfmt = (1 << dest);
00396 
00397    ast_debug(1, "Opening transcoder channel from %d to %d.\n", source, dest);
00398 
00399 retry:
00400    if (ioctl(fd, DAHDI_TC_ALLOCATE, &dahdip->fmts)) {
00401       if ((ENODEV == errno) && !tried_once) {
00402          /* We requested to translate to/from an unsupported
00403           * format.  Most likely this is because signed linear
00404           * was not supported by any hardware devices even
00405           * though this module always registers signed linear
00406           * support. In this case we'll retry, requesting
00407           * support for ULAW instead of signed linear and then
00408           * we'll just convert from ulaw to signed linear in
00409           * software. */
00410          if (AST_FORMAT_SLINEAR == dahdip->fmts.srcfmt) {
00411             ast_debug(1, "Using soft_slin support on source\n");
00412             dahdip->softslin = 1;
00413             dahdip->fmts.srcfmt = AST_FORMAT_ULAW;
00414          } else if (AST_FORMAT_SLINEAR == dahdip->fmts.dstfmt) {
00415             ast_debug(1, "Using soft_slin support on destination\n");
00416             dahdip->softslin = 1;
00417             dahdip->fmts.dstfmt = AST_FORMAT_ULAW;
00418          }
00419          tried_once = 1;
00420          goto retry;
00421       }
00422       ast_log(LOG_ERROR, "Unable to attach to transcoder: %s\n", strerror(errno));
00423       close(fd);
00424 
00425       return -1;
00426    }
00427 
00428    flags = fcntl(fd, F_GETFL);
00429    if (flags > - 1) {
00430       if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
00431          ast_log(LOG_WARNING, "Could not set non-block mode!\n");
00432    }
00433 
00434    dahdip->fd = fd;
00435 
00436    dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt)&AST_FORMAT_G723_1) ? G723_SAMPLES : G729_SAMPLES;
00437 
00438    switch (dahdip->fmts.dstfmt) {
00439    case AST_FORMAT_G729A:
00440       ast_atomic_fetchadd_int(&channels.encoders, +1);
00441       break;
00442    case AST_FORMAT_G723_1:
00443       ast_atomic_fetchadd_int(&channels.encoders, +1);
00444       break;
00445    default:
00446       ast_atomic_fetchadd_int(&channels.decoders, +1);
00447       break;
00448    }
00449 
00450    return 0;
00451 }

static void dahdi_write_frame ( struct codec_dahdi_pvt dahdip,
const uint8_t *  buffer,
const ssize_t  count 
) [static]

Definition at line 165 of file codec_dahdi.c.

References ast_log(), errno, codec_dahdi_pvt::fd, LOG_ERROR, and option_verbose.

Referenced by dahdi_decoder_framein(), and dahdi_encoder_framein().

00166 {
00167    int res;
00168    struct pollfd p = {0};
00169    if (!count) return;
00170    res = write(dahdip->fd, buffer, count);
00171    if (option_verbose > 10) {
00172       if (-1 == res) {
00173          ast_log(LOG_ERROR, "Failed to write to transcoder: %s\n", strerror(errno));
00174       }
00175       if (count != res) {
00176          ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res);
00177       }
00178    }
00179    p.fd = dahdip->fd;
00180    p.events = POLLOUT;
00181    res = poll(&p, 1, 50);
00182 }

static void drop_translator ( int  dst,
int  src 
) [static]

Definition at line 536 of file codec_dahdi.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_unregister_translator(), ast_translator::dstfmt, translator::entry, global_format_map, format_map::map, ast_translator::srcfmt, and translator::t.

00537 {
00538    struct translator *cur;
00539 
00540    AST_LIST_LOCK(&translators);
00541    AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) {
00542       if (cur->t.srcfmt != src)
00543          continue;
00544 
00545       if (cur->t.dstfmt != dst)
00546          continue;
00547 
00548       AST_LIST_REMOVE_CURRENT(entry);
00549       ast_unregister_translator(&cur->t);
00550       ast_free(cur);
00551       global_format_map.map[dst][src] = 0;
00552       break;
00553    }
00554    AST_LIST_TRAVERSE_SAFE_END;
00555    AST_LIST_UNLOCK(&translators);
00556 }

static struct ast_frame* fakesrc_sample ( void   )  [static]

Definition at line 458 of file codec_dahdi.c.

References AST_FRAME_VOICE, and f.

Referenced by register_translator().

00459 {
00460    /* Don't bother really trying to test hardware ones. */
00461    static struct ast_frame f = {
00462       .frametype = AST_FRAME_VOICE,
00463       .samples = 160,
00464       .src = __PRETTY_FUNCTION__
00465    };
00466 
00467    return &f;
00468 }

static int find_transcoders ( void   )  [static]

Definition at line 614 of file codec_dahdi.c.

References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), ast_verbose, errno, LOG_ERROR, map, option_verbose, and VERBOSE_PREFIX_2.

Referenced by load_module().

00615 {
00616    struct dahdi_transcoder_info info = { 0, };
00617    struct format_map map = { { { 0 } } };
00618    int fd, res;
00619    unsigned int x, y;
00620 
00621    if ((fd = open("/dev/dahdi/transcode", O_RDWR)) < 0) {
00622       ast_log(LOG_ERROR, "Failed to open /dev/dahdi/transcode: %s\n", strerror(errno));
00623       return 0;
00624    }
00625 
00626    for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) {
00627       if (option_verbose > 1)
00628          ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name);
00629 
00630       /* Complex codecs need to support signed linear.  If the
00631        * hardware transcoder does not natively support signed linear
00632        * format, we will emulate it in software directly in this
00633        * module. Also, do not allow direct ulaw/alaw to complex
00634        * codec translation, since that will prevent the generic PLC
00635        * functions from working. */
00636       if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
00637          info.dstfmts |= AST_FORMAT_SLINEAR;
00638          info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
00639       }
00640       if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
00641          info.srcfmts |= AST_FORMAT_SLINEAR;
00642          info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
00643       }
00644 
00645       build_translators(&map, info.dstfmts, info.srcfmts);
00646       ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2);
00647 
00648    }
00649 
00650    close(fd);
00651 
00652    if (!info.tcnum && (option_verbose > 1))
00653       ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n");
00654 
00655    for (x = 0; x < 32; x++) {
00656       for (y = 0; y < 32; y++) {
00657          if (!map.map[x][y] && global_format_map.map[x][y])
00658             drop_translator(x, y);
00659       }
00660    }
00661 
00662    return 0;
00663 }

static char * handle_cli_transcoder_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 137 of file codec_dahdi.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, copy(), ast_cli_args::fd, and ast_cli_entry::usage.

00138 {
00139    struct channel_usage copy;
00140 
00141    switch (cmd) {
00142    case CLI_INIT:
00143       e->command = "transcoder show";
00144       e->usage =
00145          "Usage: transcoder show\n"
00146          "       Displays channel utilization of DAHDI transcoder(s).\n";
00147       return NULL;
00148    case CLI_GENERATE:
00149       return NULL;
00150    }
00151 
00152    if (a->argc != 2)
00153       return CLI_SHOWUSAGE;
00154 
00155    copy = channels;
00156 
00157    if (copy.total == 0)
00158       ast_cli(a->fd, "No DAHDI transcoders found.\n");
00159    else
00160       ast_cli(a->fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
00161 
00162    return CLI_SUCCESS;
00163 }

static int is_encoder ( struct translator zt  )  [static]

Definition at line 470 of file codec_dahdi.c.

References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_translator::srcfmt, and translator::t.

Referenced by register_translator().

00471 {
00472    if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) {
00473       return 1;
00474    } else {
00475       return 0;
00476    }
00477 }

static int lintoulaw ( struct ast_trans_pvt pvt,
struct ast_frame f 
) [static]

Definition at line 117 of file codec_dahdi.c.

References AST_LIN2MU, ast_log(), f, LOG_ERROR, ast_trans_pvt::pvt, codec_dahdi_pvt::samples_in_buffer, and codec_dahdi_pvt::ulaw_buffer.

00118 {
00119    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00120    int i = f->samples;
00121    uint8_t *dst = &dahdip->ulaw_buffer[dahdip->samples_in_buffer];
00122    int16_t *src = f->data.ptr;
00123 
00124    if (dahdip->samples_in_buffer + i > sizeof(dahdip->ulaw_buffer)) {
00125       ast_log(LOG_ERROR, "Out of buffer space!\n");
00126       return -i;
00127    }
00128 
00129    while (i--) {
00130       *dst++ = AST_LIN2MU(*src++);
00131    }
00132 
00133    dahdip->samples_in_buffer += f->samples;
00134    return 0;
00135 }

static int load_module ( void   )  [static]

Definition at line 688 of file codec_dahdi.c.

References ARRAY_LEN, ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_ulaw_init(), cli, find_transcoders(), and parse_config().

00689 {
00690    ast_ulaw_init();
00691    if (parse_config(0))
00692       return AST_MODULE_LOAD_DECLINE;
00693    find_transcoders();
00694    ast_cli_register_multiple(cli, ARRAY_LEN(cli));
00695    return AST_MODULE_LOAD_SUCCESS;
00696 }

static int parse_config ( int  reload  )  [static]

Definition at line 570 of file codec_dahdi.c.

References ast_config_load, ast_true(), ast_variable_browse(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEUNCHANGED, and var.

00571 {
00572    struct ast_variable *var;
00573    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00574    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00575 
00576    if (cfg == NULL)
00577       return 0;
00578    if (cfg == CONFIG_STATUS_FILEUNCHANGED)
00579       return 0;
00580 
00581    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00582           if (!strcasecmp(var->name, "genericplc")) {
00583              global_useplc = ast_true(var->value);
00584              ast_verb(3, "codec_dahdi: %susing generic PLC\n",
00585             global_useplc ? "" : "not ");
00586           }
00587    }
00588 
00589    ast_config_destroy(cfg);
00590    return 0;
00591 }

static int register_translator ( int  dst,
int  src 
) [static]

Definition at line 479 of file codec_dahdi.c.

References ast_calloc, AST_FORMAT_G723_1, ast_free, ast_getformatname(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_register_translator, BUFFER_SIZE, dahdi_decoder_framein(), dahdi_decoder_frameout(), dahdi_destroy(), dahdi_encoder_framein(), dahdi_encoder_frameout(), dahdi_new(), translator::entry, fakesrc_sample(), G723_SAMPLES, G729_SAMPLES, global_format_map, is_encoder(), and format_map::map.

Referenced by build_translators().

00480 {
00481    struct translator *zt;
00482    int res;
00483 
00484    if (!(zt = ast_calloc(1, sizeof(*zt)))) {
00485       return -1;
00486    }
00487 
00488    snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s",
00489        ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
00490    zt->t.srcfmt = (1 << src);
00491    zt->t.dstfmt = (1 << dst);
00492    zt->t.buf_size = BUFFER_SIZE;
00493    if (is_encoder(zt)) {
00494       zt->t.framein = dahdi_encoder_framein;
00495       zt->t.frameout = dahdi_encoder_frameout;
00496 #if 0
00497       zt->t.buffer_samples = 0;
00498 #endif
00499    } else {
00500       zt->t.framein = dahdi_decoder_framein;
00501       zt->t.frameout = dahdi_decoder_frameout;
00502 #if 0
00503       if (AST_FORMAT_G723_1 == zt->t.srcfmt) {
00504          zt->t.plc_samples = G723_SAMPLES;
00505       } else {
00506          zt->t.plc_samples = G729_SAMPLES;
00507       }
00508       zt->t.buffer_samples = zt->t.plc_samples * 8;
00509 #endif
00510    }
00511    zt->t.destroy = dahdi_destroy;
00512    zt->t.buffer_samples = 0;
00513    zt->t.newpvt = dahdi_new;
00514    zt->t.sample = fakesrc_sample;
00515 #if 0
00516    zt->t.useplc = global_useplc;
00517 #endif
00518    zt->t.useplc = 0;
00519    zt->t.native_plc = 0;
00520 
00521    zt->t.desc_size = sizeof(struct codec_dahdi_pvt);
00522    if ((res = ast_register_translator(&zt->t))) {
00523       ast_free(zt);
00524       return -1;
00525    }
00526 
00527    AST_LIST_LOCK(&translators);
00528    AST_LIST_INSERT_HEAD(&translators, zt, entry);
00529    AST_LIST_UNLOCK(&translators);
00530 
00531    global_format_map.map[dst][src] = 1;
00532 
00533    return res;
00534 }

static int reload ( void   )  [static]

Definition at line 665 of file codec_dahdi.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, translator::entry, global_useplc, parse_config(), translator::t, and ast_translator::useplc.

00666 {
00667    struct translator *cur;
00668 
00669    if (parse_config(1))
00670       return AST_MODULE_LOAD_DECLINE;
00671 
00672    AST_LIST_LOCK(&translators);
00673    AST_LIST_TRAVERSE(&translators, cur, entry)
00674       cur->t.useplc = global_useplc;
00675    AST_LIST_UNLOCK(&translators);
00676 
00677    return AST_MODULE_LOAD_SUCCESS;
00678 }

static int ulawtolin ( struct ast_trans_pvt pvt  )  [static]

Definition at line 101 of file codec_dahdi.c.

References AST_MULAW, ast_trans_pvt::datalen, ast_trans_pvt::i16, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::ulaw_buffer.

00102 {
00103    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00104    int i = dahdip->required_samples;
00105    uint8_t *src = &dahdip->ulaw_buffer[0];
00106    int16_t *dst = pvt->outbuf.i16 + pvt->datalen;
00107 
00108    /* convert and copy in outbuf */
00109    while (i--) {
00110       *dst++ = AST_MULAW(*src++);
00111    }
00112 
00113    return 0;
00114 }

static int unload_module ( void   )  [static]

Definition at line 680 of file codec_dahdi.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), cli, and unregister_translators().

00681 {
00682    ast_cli_unregister_multiple(cli, ARRAY_LEN(cli));
00683    unregister_translators();
00684 
00685    return 0;
00686 }

static void unregister_translators ( void   )  [static]

Definition at line 558 of file codec_dahdi.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_unregister_translator(), translator::entry, and translator::t.

Referenced by unload_module().

00559 {
00560    struct translator *cur;
00561 
00562    AST_LIST_LOCK(&translators);
00563    while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
00564       ast_unregister_translator(&cur->t);
00565       ast_free(cur);
00566    }
00567    AST_LIST_UNLOCK(&translators);
00568 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Generic DAHDI Transcoder Codec Translator" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 702 of file codec_dahdi.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 702 of file codec_dahdi.c.

struct channel_usage channels [static]

struct ast_cli_entry cli[] [static]

Initial value:

 {
   { .handler =  handle_cli_transcoder_show , .summary =  "Display DAHDI transcoder utilization." ,__VA_ARGS__ }
}

Definition at line 69 of file codec_dahdi.c.

Referenced by load_module(), and unload_module().

struct format_map global_format_map = { { { 0 } } } [static]

Definition at line 77 of file codec_dahdi.c.

Referenced by build_translators(), drop_translator(), and register_translator().

unsigned int global_useplc = 0 [static]

Definition at line 59 of file codec_dahdi.c.

Referenced by reload().


Generated on Wed Aug 18 22:34:20 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7