Thu Jul 9 13:41:15 2009

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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, }
static const 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 277 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().

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

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

Definition at line 299 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRFLAG_FROM_TRANSLATOR, AST_FRIENDLY_OFFSET, ast_log(), ast_set_flag, ast_translator::buf_size, 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_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().

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

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

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

Definition at line 224 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRFLAG_FROM_TRANSLATOR, AST_FRIENDLY_OFFSET, ast_log(), ast_set_flag, ast_translator::buf_size, 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_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().

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

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_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_DEBUG, 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_log(LOG_DEBUG, "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_log(LOG_DEBUG, "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_log(LOG_DEBUG, "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 161 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().

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

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 133 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.

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

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 113 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.

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

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_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 97 of file codec_dahdi.c.

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

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

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

Definition at line 702 of file codec_dahdi.c.

const 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 Thu Jul 9 13:41:15 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7