Sat Aug 6 00:39:54 2011

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

#define G729_SAMPLES   160

Definition at line 66 of file codec_dahdi.c.

Referenced by dahdi_translate().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 671 of file codec_dahdi.c.

static void __unreg_module ( void   )  [static]

Definition at line 671 of file codec_dahdi.c.

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

Definition at line 573 of file codec_dahdi.c.

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

00574 {
00575    unsigned int src, dst;
00576 
00577    for (src = 0; src < 32; src++) {
00578       for (dst = 0; dst < 32; dst++) {
00579          if (!(srcfmts & (1 << src)))
00580             continue;
00581 
00582          if (!(dstfmts & (1 << dst)))
00583             continue;
00584 
00585          if (global_format_map.map[dst][src])
00586             continue;
00587 
00588          if (!register_translator(dst, src))
00589             map->map[dst][src] = 1;
00590       }
00591    }
00592 }

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

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

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

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

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

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

static void dahdi_destroy ( struct ast_trans_pvt pvt  )  [static]

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

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

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

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

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

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

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

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

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

00389 {
00390    /* Request translation through zap if possible */
00391    int fd;
00392    struct codec_dahdi_pvt *ztp = pvt->pvt;
00393    int flags;
00394    int tried_once = 0;
00395 #ifdef HAVE_ZAPTEL
00396    const char *dev_filename = "/dev/zap/transcode";
00397 #else
00398    const char *dev_filename = "/dev/dahdi/transcode";
00399 #endif
00400    
00401    if ((fd = open(dev_filename, O_RDWR)) < 0) {
00402       ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno));
00403       return -1;
00404    }
00405    
00406    ztp->fmts.srcfmt = (1 << source);
00407    ztp->fmts.dstfmt = (1 << dest);
00408 
00409    if (option_debug) {
00410       ast_log(LOG_DEBUG, "Opening transcoder channel from %d to %d.\n", source, dest);
00411    }
00412 
00413 retry:
00414    if (ioctl(fd, DAHDI_TC_ALLOCATE, &ztp->fmts)) {
00415       if ((ENODEV == errno) && !tried_once) {
00416          /* We requested to translate to/from an unsupported
00417           * format.  Most likely this is because signed linear
00418           * was not supported by any hardware devices even
00419           * though this module always registers signed linear
00420           * support. In this case we'll retry, requesting
00421           * support for ULAW instead of signed linear and then
00422           * we'll just convert from ulaw to signed linear in
00423           * software. */
00424          if (AST_FORMAT_SLINEAR == ztp->fmts.srcfmt) {
00425             if (option_debug) {
00426                ast_log(LOG_DEBUG, "Using soft_slin support on source\n");
00427             }
00428             ztp->softslin = 1;
00429             ztp->fmts.srcfmt = AST_FORMAT_ULAW;
00430          } else if (AST_FORMAT_SLINEAR == ztp->fmts.dstfmt) {
00431             if (option_debug) {
00432                ast_log(LOG_DEBUG, "Using soft_slin support on destination\n");
00433             }
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 173 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().

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

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

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

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

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

00595 {
00596    struct dahdi_transcoder_info info = { 0, };
00597    struct format_map map = { { { 0 } } };
00598    int fd, res;
00599    unsigned int x, y;
00600 
00601    if ((fd = open(DAHDI_FILE_TRANSCODE, O_RDWR)) < 0) {
00602       ast_log(LOG_ERROR, "Failed to open " DAHDI_FILE_TRANSCODE ": %s\n", strerror(errno));
00603       return 0;
00604    }
00605 
00606    for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) {
00607       if (option_verbose > 1)
00608          ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name);
00609 
00610       /* Complex codecs need to support signed linear.  If the
00611        * hardware transcoder does not natively support signed linear
00612        * format, we will emulate it in software directly in this
00613        * module. Also, do not allow direct ulaw/alaw to complex
00614        * codec translation, since that will prevent the generic PLC
00615        * functions from working. */
00616       if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
00617          info.dstfmts |= AST_FORMAT_SLINEAR;
00618          info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
00619       }
00620       if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
00621          info.srcfmts |= AST_FORMAT_SLINEAR;
00622          info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
00623       }
00624 
00625       build_translators(&map, info.dstfmts, info.srcfmts);
00626       ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2);
00627 
00628    }
00629 
00630    close(fd);
00631 
00632    if (!info.tcnum && (option_verbose > 1))
00633       ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n");
00634 
00635    for (x = 0; x < 32; x++) {
00636       for (y = 0; y < 32; y++) {
00637          if (!map.map[x][y] && global_format_map.map[x][y])
00638             drop_translator(x, y);
00639       }
00640    }
00641 
00642    return 0;
00643 }

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

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

static int load_module ( void   )  [static]

Definition at line 658 of file codec_dahdi.c.

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

00659 {
00660    ast_ulaw_init();
00661    find_transcoders();
00662    ast_cli_register_multiple(cli, sizeof(cli) / sizeof(cli[0]));
00663 
00664    return 0;
00665 }

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

Definition at line 497 of file codec_dahdi.c.

References ast_calloc, 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, 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    } else {
00515       zt->t.framein = dahdi_decoder_framein;
00516       zt->t.frameout = dahdi_decoder_frameout;
00517    }
00518    zt->t.destroy = dahdi_destroy;
00519    zt->t.buffer_samples = 0;
00520    zt->t.newpvt = dahdi_new;
00521    zt->t.sample = fakesrc_sample;
00522    zt->t.native_plc = 0;
00523 
00524    zt->t.desc_size = sizeof(struct codec_dahdi_pvt);
00525    if ((res = ast_register_translator(&zt->t))) {
00526       free(zt);
00527       return -1;
00528    }
00529 
00530    AST_LIST_LOCK(&translators);
00531    AST_LIST_INSERT_HEAD(&translators, zt, entry);
00532    AST_LIST_UNLOCK(&translators);
00533 
00534    global_format_map.map[dst][src] = 1;
00535 
00536    return res;
00537 }

static int reload ( void   )  [static]

Definition at line 645 of file codec_dahdi.c.

00646 {
00647    return 0;
00648 }

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

Definition at line 159 of file codec_dahdi.c.

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

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

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

Definition at line 123 of file codec_dahdi.c.

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

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

static int unload_module ( void   )  [static]

Definition at line 650 of file codec_dahdi.c.

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

00651 {
00652    ast_cli_unregister_multiple(cli, sizeof(cli) / sizeof(cli[0]));
00653    unregister_translators();
00654 
00655    return 0;
00656 }

static void unregister_translators ( void   )  [static]

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

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


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

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 671 of file codec_dahdi.c.

struct channel_usage channels [static]

struct ast_cli_entry cli[] [static]

Definition at line 91 of file codec_dahdi.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_deprecated[] [static]

Definition at line 84 of file codec_dahdi.c.

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

Definition at line 103 of file codec_dahdi.c.

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

char show_transcoder_usage[] [static]

Initial value:

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

Definition at line 74 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 78 of file codec_dahdi.c.


Generated on Sat Aug 6 00:39:54 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7