#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_frame * | dahdi_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_frame * | dahdi_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_frame * | fakesrc_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_info * | ast_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 [] |
Definition in file codec_dahdi.c.
#define BUFFER_SIZE 8000 |
#define G723_SAMPLES 240 |
#define G729_SAMPLES 160 |
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] |
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 }
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] |
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.