Fri Jan 29 14:25:37 2010

Asterisk developer's documentation


codec_dahdi.c File Reference

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

#include "asterisk.h"
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include "asterisk/lock.h"
#include "asterisk/translate.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dahdi_compat.h"
#include "asterisk/frame.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 *ztp, 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 int is_encoder (struct translator *zt)
static int lintoulaw (struct ast_trans_pvt *pvt, struct ast_frame *f)
static int load_module (void)
static void parse_config (void)
static int register_translator (int dst, int src)
static int reload (void)
static int transcoder_show (int fd, int argc, char **argv)
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 | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 ast_cli_entry cli_deprecated []
static struct format_map global_format_map = { { { 0 } } }
static unsigned int global_useplc = 0
static char show_transcoder_usage []
static char transcoder_show_usage []


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

Referenced by register_translator().

#define G723_SAMPLES   240

Definition at line 65 of file codec_dahdi.c.

Referenced by dahdi_translate(), and register_translator().

#define G729_SAMPLES   160

Definition at line 66 of file codec_dahdi.c.

Referenced by dahdi_translate(), and register_translator().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 718 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 718 of file codec_dahdi.c.

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

Definition at line 610 of file codec_dahdi.c.

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

00611 {
00612    unsigned int src, dst;
00613 
00614    for (src = 0; src < 32; src++) {
00615       for (dst = 0; dst < 32; dst++) {
00616          if (!(srcfmts & (1 << src)))
00617             continue;
00618 
00619          if (!(dstfmts & (1 << dst)))
00620             continue;
00621 
00622          if (global_format_map.map[dst][src])
00623             continue;
00624 
00625          if (!register_translator(dst, src))
00626             map->map[dst][src] = 1;
00627       }
00628    }
00629 }

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

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

00290 {
00291    struct codec_dahdi_pvt *ztp = pvt->pvt;
00292 
00293    if (!f->subclass) {
00294       /* We're just faking a return for calculation purposes. */
00295       ztp->fake = 2;
00296       pvt->samples = f->samples;
00297       return 0;
00298    }
00299 
00300    if (!f->datalen) {
00301       if (f->samples != ztp->required_samples) {
00302          ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, ztp->required_samples, f->datalen);
00303       }
00304    }
00305    dahdi_write_frame(ztp, f->data, f->datalen);
00306    pvt->samples += f->samples;
00307    pvt->datalen = 0;
00308    return -1;
00309 }

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

Definition at line 311 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), 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().

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

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

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

00374 {
00375    struct codec_dahdi_pvt *ztp = pvt->pvt;
00376 
00377    switch (ztp->fmts.dstfmt) {
00378    case AST_FORMAT_G729A:
00379    case AST_FORMAT_G723_1:
00380       ast_atomic_fetchadd_int(&channels.encoders, -1);
00381       break;
00382    default:
00383       ast_atomic_fetchadd_int(&channels.decoders, -1);
00384       break;
00385    }
00386 
00387    close(ztp->fd);
00388 }

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

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

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

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

Definition at line 238 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), 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().

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

static int dahdi_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 473 of file codec_dahdi.c.

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

00474 {
00475    return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
00476 }

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

Definition at line 390 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, option_debug, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::softslin.

Referenced by dahdi_new().

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

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

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

00176 {
00177    int res;
00178    struct pollfd p = {0};
00179    if (!count) return;
00180    res = write(ztp->fd, buffer, count); 
00181    if (option_verbose > 10) {
00182       if (-1 == res) {
00183          ast_log(LOG_ERROR, "Failed to write to transcoder: %s\n", strerror(errno));
00184       } 
00185       if (count != res) {
00186          ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res);
00187       }
00188    }
00189    p.fd = ztp->fd;
00190    p.events = POLLOUT;
00191    res = poll(&p, 1, 50);
00192 }

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

Definition at line 556 of file codec_dahdi.c.

References 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, free, global_format_map, format_map::map, ast_translator::srcfmt, and translator::t.

00557 {
00558    struct translator *cur;
00559 
00560    AST_LIST_LOCK(&translators);
00561    AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) {
00562       if (cur->t.srcfmt != src)
00563          continue;
00564 
00565       if (cur->t.dstfmt != dst)
00566          continue;
00567 
00568       AST_LIST_REMOVE_CURRENT(&translators, entry);
00569       ast_unregister_translator(&cur->t);
00570       free(cur);
00571       global_format_map.map[dst][src] = 0;
00572       break;
00573    }
00574    AST_LIST_TRAVERSE_SAFE_END;
00575    AST_LIST_UNLOCK(&translators);
00576 }

static struct ast_frame* fakesrc_sample ( void   )  [static]

Definition at line 478 of file codec_dahdi.c.

References AST_FRAME_VOICE, and f.

Referenced by register_translator().

00479 {
00480    /* Don't bother really trying to test hardware ones. */
00481    static struct ast_frame f = {
00482       .frametype = AST_FRAME_VOICE,
00483       .samples = 160,
00484       .src = __PRETTY_FUNCTION__
00485    };
00486 
00487    return &f;
00488 }

static int find_transcoders ( void   )  [static]

Definition at line 631 of file codec_dahdi.c.

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

Referenced by load_module().

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

static int is_encoder ( struct translator zt  )  [static]

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

00491 {
00492    if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) {
00493       return 1;
00494    } else {
00495       return 0;
00496    }
00497 }

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

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

00142 {
00143    struct codec_dahdi_pvt *ztp = pvt->pvt;
00144    int i = f->samples;
00145    uint8_t *dst = &ztp->ulaw_buffer[ztp->samples_in_buffer];
00146    int16_t *src = (int16_t*)f->data;
00147 
00148    if (ztp->samples_in_buffer + i > sizeof(ztp->ulaw_buffer)) {
00149       ast_log(LOG_ERROR, "Out of buffer space!\n");
00150       return -i;
00151    }
00152 
00153    while (i--) {
00154       *dst++ = AST_LIN2MU(*src++);
00155    }
00156 
00157    ztp->samples_in_buffer += f->samples;
00158    return 0;
00159 }

static int load_module ( void   )  [static]

Definition at line 704 of file codec_dahdi.c.

References ast_cli_register_multiple(), ast_ulaw_init(), cli, find_transcoders(), and parse_config().

00705 {
00706    ast_ulaw_init();
00707    parse_config();
00708    find_transcoders();
00709    ast_cli_register_multiple(cli, sizeof(cli) / sizeof(cli[0]));
00710 
00711    return 0;
00712 }

static void parse_config ( void   )  [static]

Definition at line 590 of file codec_dahdi.c.

References ast_config_load(), ast_true(), ast_variable_browse(), ast_verbose(), option_verbose, var, and VERBOSE_PREFIX_3.

00591 {
00592    struct ast_variable *var;
00593    struct ast_config *cfg = ast_config_load("codecs.conf");
00594 
00595    if (!cfg)
00596       return;
00597 
00598    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00599           if (!strcasecmp(var->name, "genericplc")) {
00600              global_useplc = ast_true(var->value);
00601              if (option_verbose > 2)
00602                 ast_verbose(VERBOSE_PREFIX_3 "codec_zap: %susing generic PLC\n",
00603                   global_useplc ? "" : "not ");
00604           }
00605    }
00606 
00607    ast_config_destroy(cfg);
00608 }

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

Definition at line 499 of file codec_dahdi.c.

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

Referenced by build_translators().

00500 {
00501    struct translator *zt;
00502    int res;
00503 
00504    if (!(zt = ast_calloc(1, sizeof(*zt)))) {
00505       return -1;
00506    }
00507 
00508    snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s", 
00509        ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
00510    zt->t.srcfmt = (1 << src);
00511    zt->t.dstfmt = (1 << dst);
00512    zt->t.buf_size = BUFFER_SIZE;
00513    if (is_encoder(zt)) {
00514       zt->t.framein = dahdi_encoder_framein;
00515       zt->t.frameout = dahdi_encoder_frameout;
00516 #if 0
00517       zt->t.buffer_samples = 0;
00518 #endif
00519    } else {
00520       zt->t.framein = dahdi_decoder_framein;
00521       zt->t.frameout = dahdi_decoder_frameout;
00522 #if 0
00523       if (AST_FORMAT_G723_1 == zt->t.srcfmt) {
00524          zt->t.plc_samples = G723_SAMPLES;
00525       } else {
00526          zt->t.plc_samples = G729_SAMPLES;
00527       }
00528       zt->t.buffer_samples = zt->t.plc_samples * 8;
00529 #endif
00530    }
00531    zt->t.destroy = dahdi_destroy;
00532    zt->t.buffer_samples = 0;
00533    zt->t.newpvt = dahdi_new;
00534    zt->t.sample = fakesrc_sample;
00535 #if 0
00536    zt->t.useplc = global_useplc;
00537 #endif
00538    zt->t.useplc = 0;
00539    zt->t.native_plc = 0;
00540 
00541    zt->t.desc_size = sizeof(struct codec_dahdi_pvt);
00542    if ((res = ast_register_translator(&zt->t))) {
00543       free(zt);
00544       return -1;
00545    }
00546 
00547    AST_LIST_LOCK(&translators);
00548    AST_LIST_INSERT_HEAD(&translators, zt, entry);
00549    AST_LIST_UNLOCK(&translators);
00550 
00551    global_format_map.map[dst][src] = 1;
00552 
00553    return res;
00554 }

static int reload ( void   )  [static]

Definition at line 682 of file codec_dahdi.c.

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

00683 {
00684    struct translator *cur;
00685 
00686    parse_config();
00687 
00688    AST_LIST_LOCK(&translators);
00689    AST_LIST_TRAVERSE(&translators, cur, entry)
00690       cur->t.useplc = global_useplc;
00691    AST_LIST_UNLOCK(&translators);
00692 
00693    return 0;
00694 }

static int transcoder_show ( int  fd,
int  argc,
char **  argv 
) [static]

Definition at line 161 of file codec_dahdi.c.

References ast_cli(), copy(), and RESULT_SUCCESS.

00162 {
00163    struct channel_usage copy;
00164 
00165    copy = channels;
00166 
00167    if (copy.total == 0)
00168       ast_cli(fd, "No DAHDI transcoders found.\n");
00169    else
00170       ast_cli(fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
00171 
00172    return RESULT_SUCCESS;
00173 }

static int ulawtolin ( struct ast_trans_pvt pvt  )  [static]

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

00126 {
00127    struct codec_dahdi_pvt *ztp = pvt->pvt;
00128    int i = ztp->required_samples;
00129    uint8_t *src = &ztp->ulaw_buffer[0];
00130    int16_t *dst = (int16_t *)pvt->outbuf + pvt->datalen;
00131 
00132    /* convert and copy in outbuf */
00133    while (i--) {
00134       *dst++ = AST_MULAW(*src++);
00135    }
00136 
00137    return 0;
00138 }

static int unload_module ( void   )  [static]

Definition at line 696 of file codec_dahdi.c.

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

00697 {
00698    ast_cli_unregister_multiple(cli, sizeof(cli) / sizeof(cli[0]));
00699    unregister_translators();
00700 
00701    return 0;
00702 }

static void unregister_translators ( void   )  [static]

Definition at line 578 of file codec_dahdi.c.

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

Referenced by unload_module().

00579 {
00580    struct translator *cur;
00581 
00582    AST_LIST_LOCK(&translators);
00583    while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
00584       ast_unregister_translator(&cur->t);
00585       free(cur);
00586    }
00587    AST_LIST_UNLOCK(&translators);
00588 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 718 of file codec_dahdi.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 718 of file codec_dahdi.c.

struct channel_usage channels [static]

struct ast_cli_entry cli[] [static]

Definition at line 93 of file codec_dahdi.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_deprecated[] [static]

Definition at line 86 of file codec_dahdi.c.

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

Definition at line 105 of file codec_dahdi.c.

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

unsigned int global_useplc = 0 [static]

Definition at line 68 of file codec_dahdi.c.

Referenced by reload().

char show_transcoder_usage[] [static]

Initial value:

"Usage: show transcoder\n"
"       Displays channel utilization of DAHDI transcoder(s).\n"

Definition at line 76 of file codec_dahdi.c.

char transcoder_show_usage[] [static]

Initial value:

"Usage: transcoder show\n"
"       Displays channel utilization of DAHDI transcoder(s).\n"

Definition at line 80 of file codec_dahdi.c.


Generated on Fri Jan 29 14:25:37 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7