Thu Oct 8 00:59:36 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 <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 = "6989f2ec67f8497e38c12890500c525b" , .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 716 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 716 of file codec_dahdi.c.

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

Definition at line 608 of file codec_dahdi.c.

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

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

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

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

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

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

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

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

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

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

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

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

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       ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR);
00253       pvt->samples = 0;
00254 
00255       return &pvt->f;
00256 
00257    } else if (1 == ztp->fake) {
00258       ztp->fake = 0;
00259       return NULL;
00260    }
00261 
00262    res = read(ztp->fd, pvt->outbuf + pvt->datalen, pvt->t->buf_size - pvt->datalen);
00263    if (-1 == res) {
00264       if (EWOULDBLOCK == errno) {
00265          /* Nothing waiting... */
00266          return NULL;
00267       } else {
00268          ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
00269          return NULL;
00270       }
00271    } else {
00272       pvt->f.datalen = res;
00273       pvt->f.samples = ztp->required_samples;
00274       pvt->f.frametype = AST_FRAME_VOICE;
00275       pvt->f.subclass = 1 <<  (pvt->t->dstfmt);
00276       pvt->f.mallocd = 0;
00277       pvt->f.offset = AST_FRIENDLY_OFFSET;
00278       pvt->f.src = pvt->t->name;
00279       pvt->f.data = pvt->outbuf;
00280       ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR);
00281 
00282       pvt->samples = 0;
00283       pvt->datalen = 0;
00284       return &pvt->f;
00285    }
00286 
00287    /* Shouldn't get here... */
00288    return NULL;
00289 }

static int dahdi_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 471 of file codec_dahdi.c.

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

00472 {
00473    return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
00474 }

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

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

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

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

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

static struct ast_frame* fakesrc_sample ( void   )  [static]

Definition at line 476 of file codec_dahdi.c.

References AST_FRAME_VOICE, and f.

Referenced by register_translator().

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

static int find_transcoders ( void   )  [static]

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

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

static int is_encoder ( struct translator zt  )  [static]

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

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

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

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

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

static void parse_config ( void   )  [static]

Definition at line 588 of file codec_dahdi.c.

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

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

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

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

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

static int reload ( void   )  [static]

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

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

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

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

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

static void unregister_translators ( void   )  [static]

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

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


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

Definition at line 716 of file codec_dahdi.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 716 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 Thu Oct 8 00:59:36 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7