Mon Jun 27 16:51:12 2011

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 register_translator (int dst, int src)
static int reload (void)
static int ulawtolin (struct ast_trans_pvt *pvt, int samples)
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 } } }


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().

#define G729_SAMPLES   160

Definition at line 57 of file codec_dahdi.c.

Referenced by dahdi_translate().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 646 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 646 of file codec_dahdi.c.

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

Definition at line 549 of file codec_dahdi.c.

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

00550 {
00551    unsigned int src, dst;
00552 
00553    for (src = 0; src < 32; src++) {
00554       for (dst = 0; dst < 32; dst++) {
00555          if (!(srcfmts & (1 << src)))
00556             continue;
00557 
00558          if (!(dstfmts & (1 << dst)))
00559             continue;
00560 
00561          if (global_format_map.map[dst][src])
00562             continue;
00563 
00564          if (!register_translator(dst, src))
00565             map->map[dst][src] = 1;
00566       }
00567    }
00568 }

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

Definition at line 273 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().

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

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

Definition at line 295 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_subclass::codec, 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().

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

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

Definition at line 357 of file codec_dahdi.c.

References ast_atomic_fetchadd_int(), AST_FORMAT_G723_1, AST_FORMAT_G729A, channels, channel_usage::decoders, channel_usage::encoders, codec_dahdi_pvt::fd, codec_dahdi_pvt::fmts, and ast_trans_pvt::pvt.

Referenced by register_translator().

00358 {
00359    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00360 
00361    switch (dahdip->fmts.dstfmt) {
00362    case AST_FORMAT_G729A:
00363    case AST_FORMAT_G723_1:
00364       ast_atomic_fetchadd_int(&channels.encoders, -1);
00365       break;
00366    default:
00367       ast_atomic_fetchadd_int(&channels.decoders, -1);
00368       break;
00369    }
00370 
00371    close(dahdip->fd);
00372 }

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

Definition at line 178 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().

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

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

Definition at line 222 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_subclass::codec, 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().

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

static int dahdi_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 447 of file codec_dahdi.c.

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

00448 {
00449    return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
00450 }

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

Definition at line 374 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(), channels, channel_usage::decoders, channel_usage::encoders, 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().

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

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

Definition at line 159 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().

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

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

Definition at line 515 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.

00516 {
00517    struct translator *cur;
00518 
00519    AST_LIST_LOCK(&translators);
00520    AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) {
00521       if (cur->t.srcfmt != src)
00522          continue;
00523 
00524       if (cur->t.dstfmt != dst)
00525          continue;
00526 
00527       AST_LIST_REMOVE_CURRENT(entry);
00528       ast_unregister_translator(&cur->t);
00529       ast_free(cur);
00530       global_format_map.map[dst][src] = 0;
00531       break;
00532    }
00533    AST_LIST_TRAVERSE_SAFE_END;
00534    AST_LIST_UNLOCK(&translators);
00535 }

static struct ast_frame* fakesrc_sample ( void   )  [static]

Definition at line 452 of file codec_dahdi.c.

References AST_FRAME_VOICE, and f.

Referenced by register_translator().

00453 {
00454    /* Don't bother really trying to test hardware ones. */
00455    static struct ast_frame f = {
00456       .frametype = AST_FRAME_VOICE,
00457       .samples = 160,
00458       .src = __PRETTY_FUNCTION__
00459    };
00460 
00461    return &f;
00462 }

static int find_transcoders ( void   )  [static]

Definition at line 570 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().

00571 {
00572    struct dahdi_transcoder_info info = { 0, };
00573    struct format_map map = { { { 0 } } };
00574    int fd, res;
00575    unsigned int x, y;
00576 
00577    if ((fd = open("/dev/dahdi/transcode", O_RDWR)) < 0) {
00578       ast_log(LOG_ERROR, "Failed to open /dev/dahdi/transcode: %s\n", strerror(errno));
00579       return 0;
00580    }
00581 
00582    for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) {
00583       if (option_verbose > 1)
00584          ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name);
00585 
00586       /* Complex codecs need to support signed linear.  If the
00587        * hardware transcoder does not natively support signed linear
00588        * format, we will emulate it in software directly in this
00589        * module. Also, do not allow direct ulaw/alaw to complex
00590        * codec translation, since that will prevent the generic PLC
00591        * functions from working. */
00592       if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
00593          info.dstfmts |= AST_FORMAT_SLINEAR;
00594          info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
00595       }
00596       if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
00597          info.srcfmts |= AST_FORMAT_SLINEAR;
00598          info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
00599       }
00600 
00601       build_translators(&map, info.dstfmts, info.srcfmts);
00602       ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2);
00603 
00604    }
00605 
00606    close(fd);
00607 
00608    if (!info.tcnum && (option_verbose > 1))
00609       ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n");
00610 
00611    for (x = 0; x < 32; x++) {
00612       for (y = 0; y < 32; y++) {
00613          if (!map.map[x][y] && global_format_map.map[x][y])
00614             drop_translator(x, y);
00615       }
00616    }
00617 
00618    return 0;
00619 }

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

Definition at line 131 of file codec_dahdi.c.

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

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

static int is_encoder ( struct translator zt  )  [static]

Definition at line 464 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().

00465 {
00466    if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) {
00467       return 1;
00468    } else {
00469       return 0;
00470    }
00471 }

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

Definition at line 111 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.

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

static int load_module ( void   )  [static]

Definition at line 634 of file codec_dahdi.c.

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

00635 {
00636    ast_ulaw_init();
00637    find_transcoders();
00638    ast_cli_register_multiple(cli, ARRAY_LEN(cli));
00639    return AST_MODULE_LOAD_SUCCESS;
00640 }

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

Definition at line 473 of file codec_dahdi.c.

References ast_calloc, 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(), global_format_map, is_encoder(), and format_map::map.

Referenced by build_translators().

00474 {
00475    struct translator *zt;
00476    int res;
00477 
00478    if (!(zt = ast_calloc(1, sizeof(*zt)))) {
00479       return -1;
00480    }
00481 
00482    snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s",
00483        ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
00484    zt->t.srcfmt = (1 << src);
00485    zt->t.dstfmt = (1 << dst);
00486    zt->t.buf_size = BUFFER_SIZE;
00487    if (is_encoder(zt)) {
00488       zt->t.framein = dahdi_encoder_framein;
00489       zt->t.frameout = dahdi_encoder_frameout;
00490    } else {
00491       zt->t.framein = dahdi_decoder_framein;
00492       zt->t.frameout = dahdi_decoder_frameout;
00493    }
00494    zt->t.destroy = dahdi_destroy;
00495    zt->t.buffer_samples = 0;
00496    zt->t.newpvt = dahdi_new;
00497    zt->t.sample = fakesrc_sample;
00498    zt->t.native_plc = 0;
00499 
00500    zt->t.desc_size = sizeof(struct codec_dahdi_pvt);
00501    if ((res = ast_register_translator(&zt->t))) {
00502       ast_free(zt);
00503       return -1;
00504    }
00505 
00506    AST_LIST_LOCK(&translators);
00507    AST_LIST_INSERT_HEAD(&translators, zt, entry);
00508    AST_LIST_UNLOCK(&translators);
00509 
00510    global_format_map.map[dst][src] = 1;
00511 
00512    return res;
00513 }

static int reload ( void   )  [static]

Definition at line 621 of file codec_dahdi.c.

References AST_MODULE_LOAD_SUCCESS.

00622 {
00623    return AST_MODULE_LOAD_SUCCESS;
00624 }

static int ulawtolin ( struct ast_trans_pvt pvt,
int  samples 
) [static]

Definition at line 95 of file codec_dahdi.c.

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

00096 {
00097    struct codec_dahdi_pvt *dahdip = pvt->pvt;
00098    int i = samples;
00099    uint8_t *src = &dahdip->ulaw_buffer[0];
00100    int16_t *dst = pvt->outbuf.i16 + pvt->datalen;
00101 
00102    /* convert and copy in outbuf */
00103    while (i--) {
00104       *dst++ = AST_MULAW(*src++);
00105    }
00106 
00107    return 0;
00108 }

static int unload_module ( void   )  [static]

Definition at line 626 of file codec_dahdi.c.

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

00627 {
00628    ast_cli_unregister_multiple(cli, ARRAY_LEN(cli));
00629    unregister_translators();
00630 
00631    return 0;
00632 }

static void unregister_translators ( void   )  [static]

Definition at line 537 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().

00538 {
00539    struct translator *cur;
00540 
00541    AST_LIST_LOCK(&translators);
00542    while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
00543       ast_unregister_translator(&cur->t);
00544       ast_free(cur);
00545    }
00546    AST_LIST_UNLOCK(&translators);
00547 }


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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 646 of file codec_dahdi.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 646 of file codec_dahdi.c.

struct channel_usage channels [static]

Referenced by __ast_channel_alloc_ap(), action_dahdishowchannels(), action_status(), ast_active_channels(), ast_begin_shutdown(), ast_change_name(), ast_channel_callback(), ast_channel_get_full(), ast_channel_iterator_all_new(), ast_channel_release(), ast_channels_init(), ast_do_masquerade(), ast_hangup(), channel_iterator_search(), check_header(), dahdi_destroy(), dahdi_translate(), and handle_cli_transcoder_show().

struct ast_cli_entry cli[] [static]

Initial value:

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

Definition at line 67 of file codec_dahdi.c.

Referenced by load_module(), and unload_module().

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

Definition at line 75 of file codec_dahdi.c.

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


Generated on Mon Jun 27 16:51:12 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7