Mon Mar 19 11:30:46 2012

Asterisk developer's documentation


codec_dahdi.c File Reference

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

#include "asterisk.h"
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/translate.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/ulaw.h"

Go to the source code of this file.

Data Structures

struct  channel_usage
struct  codec_dahdi_pvt
struct  format_map
struct  translator
struct  translators
 the list of translators More...

Defines

#define BUFFER_SIZE   8000
#define G723_SAMPLES   240
#define G729_SAMPLES   160

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void build_translators (struct format_map *map, unsigned int dstfmts, unsigned int srcfmts)
static int dahdi_decoder_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_framedahdi_decoder_frameout (struct ast_trans_pvt *pvt)
static void dahdi_destroy (struct ast_trans_pvt *pvt)
static int dahdi_encoder_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_framedahdi_encoder_frameout (struct ast_trans_pvt *pvt)
static int dahdi_new (struct ast_trans_pvt *pvt)
static int dahdi_translate (struct ast_trans_pvt *pvt, int dest, int source)
static void dahdi_write_frame (struct codec_dahdi_pvt *dahdip, const uint8_t *buffer, const ssize_t count)
static void drop_translator (int dst, int src)
static struct ast_framefakesrc_sample (void)
static int find_transcoders (void)
static char * handle_cli_transcoder_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int is_encoder (struct translator *zt)
static int lintoulaw (struct ast_trans_pvt *pvt, struct ast_frame *f)
static int load_module (void)
static int register_translator (int dst, int src)
static int reload (void)
static int ulawtolin (struct ast_trans_pvt *pvt, int samples)
static int unload_module (void)
static void unregister_translators (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Generic DAHDI Transcoder Codec Translator" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_module_infoast_module_info = &__mod_info
static struct channel_usage channels
static struct ast_cli_entry cli []
static struct format_map global_format_map = { { { 0 } } }


Detailed Description

Translate between various formats natively through DAHDI transcoding.

Definition in file codec_dahdi.c.


Define Documentation

#define BUFFER_SIZE   8000

Definition at line 55 of file codec_dahdi.c.

Referenced by register_translator().

#define G723_SAMPLES   240

Definition at line 57 of file codec_dahdi.c.

Referenced by dahdi_translate().

#define G729_SAMPLES   160

Definition at line 58 of file codec_dahdi.c.

Referenced by dahdi_translate().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 647 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 647 of file codec_dahdi.c.

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

Definition at line 550 of file codec_dahdi.c.

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

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

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

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

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

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

Definition at line 296 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), ast_translator::buf_size, ast_trans_pvt::c, ast_frame_subclass::codec, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, errno, ast_trans_pvt::f, codec_dahdi_pvt::fake, codec_dahdi_pvt::fd, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, ast_frame::samples, codec_dahdi_pvt::softslin, ast_frame::src, ast_frame::subclass, ast_trans_pvt::t, codec_dahdi_pvt::ulaw_buffer, and ulawtolin.

Referenced by register_translator().

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

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

Definition at line 358 of file codec_dahdi.c.

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

Referenced by register_translator().

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

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

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

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

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

Definition at line 223 of file codec_dahdi.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), ast_translator::buf_size, ast_trans_pvt::c, ast_frame_subclass::codec, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, errno, ast_trans_pvt::f, codec_dahdi_pvt::fake, codec_dahdi_pvt::fd, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_trans_pvt::t.

Referenced by register_translator().

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

static int dahdi_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 448 of file codec_dahdi.c.

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

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

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

Definition at line 375 of file codec_dahdi.c.

References ast_atomic_fetchadd_int(), ast_debug, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), channels, channel_usage::decoders, channel_usage::encoders, errno, codec_dahdi_pvt::fd, codec_dahdi_pvt::fmts, G723_SAMPLES, G729_SAMPLES, LOG_ERROR, LOG_WARNING, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::softslin.

Referenced by dahdi_new().

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

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

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

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

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

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

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

static struct ast_frame* fakesrc_sample ( void   )  [static]

Definition at line 453 of file codec_dahdi.c.

References AST_FRAME_VOICE, and f.

Referenced by register_translator().

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

static int find_transcoders ( void   )  [static]

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

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

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

Definition at line 132 of file codec_dahdi.c.

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

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

static int is_encoder ( struct translator zt  )  [static]

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

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

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

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

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

static int load_module ( void   )  [static]

Definition at line 635 of file codec_dahdi.c.

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

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

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

Definition at line 474 of file codec_dahdi.c.

References ast_calloc, ast_free, ast_getformatname(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_register_translator, BUFFER_SIZE, dahdi_decoder_framein(), dahdi_decoder_frameout(), dahdi_destroy(), dahdi_encoder_framein(), dahdi_encoder_frameout(), dahdi_new(), translator::entry, fakesrc_sample(), global_format_map, is_encoder(), and format_map::map.

Referenced by build_translators().

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

static int reload ( void   )  [static]

Definition at line 622 of file codec_dahdi.c.

References AST_MODULE_LOAD_SUCCESS.

00623 {
00624    return AST_MODULE_LOAD_SUCCESS;
00625 }

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

Definition at line 96 of file codec_dahdi.c.

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

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

static int unload_module ( void   )  [static]

Definition at line 627 of file codec_dahdi.c.

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

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

static void unregister_translators ( void   )  [static]

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

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


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

Definition at line 647 of file codec_dahdi.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 647 of file codec_dahdi.c.

struct channel_usage channels [static]

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

struct ast_cli_entry cli[] [static]

Initial value:

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

Definition at line 68 of file codec_dahdi.c.

Referenced by load_module(), and unload_module().

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

Definition at line 76 of file codec_dahdi.c.

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


Generated on Mon Mar 19 11:30:46 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7