Fri Jul 24 00:41:39 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 = "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 706 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 706 of file codec_dahdi.c.

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

Definition at line 597 of file codec_dahdi.c.

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

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

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

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

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

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

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

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

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

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

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

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_FRFLAG_FROM_TRANSLATOR, AST_FRIENDLY_OFFSET, ast_log(), ast_set_flag, 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       ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR);
00243       pvt->samples = 0;
00244 
00245       return &pvt->f;
00246 
00247    } else if (1 == dahdip->fake) {
00248       dahdip->fake = 0;
00249       return NULL;
00250    }
00251 
00252    res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
00253    if (-1 == res) {
00254       if (EWOULDBLOCK == errno) {
00255          /* Nothing waiting... */
00256          return NULL;
00257       } else {
00258          ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
00259          return NULL;
00260       }
00261    } else {
00262       pvt->f.datalen = res;
00263       pvt->f.samples = dahdip->required_samples;
00264       pvt->f.frametype = AST_FRAME_VOICE;
00265       pvt->f.subclass = 1 <<  (pvt->t->dstfmt);
00266       pvt->f.mallocd = 0;
00267       pvt->f.offset = AST_FRIENDLY_OFFSET;
00268       pvt->f.src = pvt->t->name;
00269       pvt->f.data.ptr = pvt->outbuf.c;
00270       ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR);
00271 
00272       pvt->samples = 0;
00273       pvt->datalen = 0;
00274       return &pvt->f;
00275    }
00276 
00277    /* Shouldn't get here... */
00278    return NULL;
00279 }

static int dahdi_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 457 of file codec_dahdi.c.

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

00458 {
00459    return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
00460 }

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

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

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

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

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

static struct ast_frame* fakesrc_sample ( void   )  [static]

Definition at line 462 of file codec_dahdi.c.

References AST_FRAME_VOICE, and f.

Referenced by register_translator().

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

static int find_transcoders ( void   )  [static]

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

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

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

00475 {
00476    if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) {
00477       return 1;
00478    } else {
00479       return 0;
00480    }
00481 }

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

00693 {
00694    ast_ulaw_init();
00695    if (parse_config(0))
00696       return AST_MODULE_LOAD_DECLINE;
00697    find_transcoders();
00698    ast_cli_register_multiple(cli, ARRAY_LEN(cli));
00699    return AST_MODULE_LOAD_SUCCESS;
00700 }

static int parse_config ( int  reload  )  [static]

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

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

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

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

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

static int reload ( void   )  [static]

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

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

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

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

00685 {
00686    ast_cli_unregister_multiple(cli, ARRAY_LEN(cli));
00687    unregister_translators();
00688 
00689    return 0;
00690 }

static void unregister_translators ( void   )  [static]

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

00563 {
00564    struct translator *cur;
00565 
00566    AST_LIST_LOCK(&translators);
00567    while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
00568       ast_unregister_translator(&cur->t);
00569       ast_free(cur);
00570    }
00571    AST_LIST_UNLOCK(&translators);
00572 }


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

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 706 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 Fri Jul 24 00:41:39 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7