#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 void | parse_config (void) |
static int | register_translator (int dst, int src) |
static int | reload (void) |
static int | transcoder_show (int fd, int argc, char **argv) |
static int | ulawtolin (struct ast_trans_pvt *pvt) |
static int | unload_module (void) |
static void | unregister_translators (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Generic DAHDI Transcoder Codec Translator" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } |
static const struct ast_module_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 unsigned int | global_useplc = 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 |
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().
static void __reg_module | ( | void | ) | [static] |
Definition at line 718 of file codec_dahdi.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 718 of file codec_dahdi.c.
static void build_translators | ( | struct format_map * | map, | |
unsigned int | dstfmts, | |||
unsigned int | srcfmts | |||
) | [static] |
Definition at line 610 of file codec_dahdi.c.
References global_format_map, map, format_map::map, and register_translator().
00611 { 00612 unsigned int src, dst; 00613 00614 for (src = 0; src < 32; src++) { 00615 for (dst = 0; dst < 32; dst++) { 00616 if (!(srcfmts & (1 << src))) 00617 continue; 00618 00619 if (!(dstfmts & (1 << dst))) 00620 continue; 00621 00622 if (global_format_map.map[dst][src]) 00623 continue; 00624 00625 if (!register_translator(dst, src)) 00626 map->map[dst][src] = 1; 00627 } 00628 } 00629 }
static int dahdi_decoder_framein | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 289 of file codec_dahdi.c.
References ast_log(), dahdi_write_frame(), ast_trans_pvt::datalen, f, codec_dahdi_pvt::fake, LOG_ERROR, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and ast_trans_pvt::samples.
Referenced by register_translator().
00290 { 00291 struct codec_dahdi_pvt *ztp = pvt->pvt; 00292 00293 if (!f->subclass) { 00294 /* We're just faking a return for calculation purposes. */ 00295 ztp->fake = 2; 00296 pvt->samples = f->samples; 00297 return 0; 00298 } 00299 00300 if (!f->datalen) { 00301 if (f->samples != ztp->required_samples) { 00302 ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, ztp->required_samples, f->datalen); 00303 } 00304 } 00305 dahdi_write_frame(ztp, f->data, f->datalen); 00306 pvt->samples += f->samples; 00307 pvt->datalen = 0; 00308 return -1; 00309 }
static struct ast_frame* dahdi_decoder_frameout | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 311 of file codec_dahdi.c.
References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), ast_translator::buf_size, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, errno, ast_trans_pvt::f, codec_dahdi_pvt::fake, codec_dahdi_pvt::fd, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, ast_frame::samples, codec_dahdi_pvt::softslin, ast_frame::src, ast_frame::subclass, ast_trans_pvt::t, codec_dahdi_pvt::ulaw_buffer, and ulawtolin.
Referenced by register_translator().
00312 { 00313 int res; 00314 struct codec_dahdi_pvt *ztp = pvt->pvt; 00315 00316 if (2 == ztp->fake) { 00317 ztp->fake = 1; 00318 pvt->f.frametype = AST_FRAME_VOICE; 00319 pvt->f.subclass = 0; 00320 pvt->f.samples = ztp->required_samples; 00321 pvt->f.data = NULL; 00322 pvt->f.offset = 0; 00323 pvt->f.datalen = 0; 00324 pvt->f.mallocd = 0; 00325 pvt->samples = 0; 00326 return ast_frisolate(&pvt->f); 00327 } else if (1 == ztp->fake) { 00328 pvt->samples = 0; 00329 ztp->fake = 0; 00330 return NULL; 00331 } 00332 00333 /* Let's check to see if there is a new frame for us.... */ 00334 if (ztp->softslin) { 00335 res = read(ztp->fd, ztp->ulaw_buffer, sizeof(ztp->ulaw_buffer)); 00336 } else { 00337 res = read(ztp->fd, pvt->outbuf + pvt->datalen, pvt->t->buf_size - pvt->datalen); 00338 } 00339 00340 if (-1 == res) { 00341 if (EWOULDBLOCK == errno) { 00342 /* Nothing waiting... */ 00343 return NULL; 00344 } else { 00345 ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno)); 00346 return NULL; 00347 } 00348 } else { 00349 if (ztp->softslin) { 00350 ulawtolin(pvt); 00351 pvt->f.datalen = res * 2; 00352 } else { 00353 pvt->f.datalen = res; 00354 } 00355 pvt->datalen = 0; 00356 pvt->f.frametype = AST_FRAME_VOICE; 00357 pvt->f.subclass = 1 << (pvt->t->dstfmt); 00358 pvt->f.mallocd = 0; 00359 pvt->f.offset = AST_FRIENDLY_OFFSET; 00360 pvt->f.src = pvt->t->name; 00361 pvt->f.data = pvt->outbuf; 00362 pvt->f.samples = ztp->required_samples; 00363 pvt->samples = 0; 00364 00365 return ast_frisolate(&pvt->f); 00366 } 00367 00368 /* Shouldn't get here... */ 00369 return NULL; 00370 }
static void dahdi_destroy | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 373 of file codec_dahdi.c.
References ast_atomic_fetchadd_int(), AST_FORMAT_G723_1, AST_FORMAT_G729A, codec_dahdi_pvt::fd, codec_dahdi_pvt::fmts, and ast_trans_pvt::pvt.
Referenced by register_translator().
00374 { 00375 struct codec_dahdi_pvt *ztp = pvt->pvt; 00376 00377 switch (ztp->fmts.dstfmt) { 00378 case AST_FORMAT_G729A: 00379 case AST_FORMAT_G723_1: 00380 ast_atomic_fetchadd_int(&channels.encoders, -1); 00381 break; 00382 default: 00383 ast_atomic_fetchadd_int(&channels.decoders, -1); 00384 break; 00385 } 00386 00387 close(ztp->fd); 00388 }
static int dahdi_encoder_framein | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 194 of file codec_dahdi.c.
References ast_log(), dahdi_write_frame(), ast_trans_pvt::datalen, f, codec_dahdi_pvt::fake, lintoulaw, LOG_ERROR, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, codec_dahdi_pvt::samples_in_buffer, codec_dahdi_pvt::softslin, and codec_dahdi_pvt::ulaw_buffer.
Referenced by register_translator().
00195 { 00196 struct codec_dahdi_pvt *ztp = pvt->pvt; 00197 00198 if (!f->subclass) { 00199 /* We're just faking a return for calculation purposes. */ 00200 ztp->fake = 2; 00201 pvt->samples = f->samples; 00202 return 0; 00203 } 00204 00205 /* Buffer up the packets and send them to the hardware if we 00206 * have enough samples set up. */ 00207 if (ztp->softslin) { 00208 if (lintoulaw(pvt, f)) { 00209 return -1; 00210 } 00211 } else { 00212 /* NOTE: If softslin support is not needed, and the sample 00213 * size is equal to the required sample size, we wouldn't 00214 * need this copy operation. But at the time this was 00215 * written, only softslin is supported. */ 00216 if (ztp->samples_in_buffer + f->samples > sizeof(ztp->ulaw_buffer)) { 00217 ast_log(LOG_ERROR, "Out of buffer space.\n"); 00218 return -1; 00219 } 00220 memcpy(&ztp->ulaw_buffer[ztp->samples_in_buffer], f->data, f->samples); 00221 ztp->samples_in_buffer += f->samples; 00222 } 00223 00224 while (ztp->samples_in_buffer > ztp->required_samples) { 00225 dahdi_write_frame(ztp, ztp->ulaw_buffer, ztp->required_samples); 00226 ztp->samples_in_buffer -= ztp->required_samples; 00227 if (ztp->samples_in_buffer) { 00228 /* Shift any remaining bytes down. */ 00229 memmove(ztp->ulaw_buffer, &ztp->ulaw_buffer[ztp->required_samples], 00230 ztp->samples_in_buffer); 00231 } 00232 } 00233 pvt->samples += f->samples; 00234 pvt->datalen = 0; 00235 return -1; 00236 }
static struct ast_frame* dahdi_encoder_frameout | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 238 of file codec_dahdi.c.
References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_log(), ast_translator::buf_size, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, errno, ast_trans_pvt::f, codec_dahdi_pvt::fake, codec_dahdi_pvt::fd, ast_frame::frametype, LOG_ERROR, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, ast_trans_pvt::samples, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_trans_pvt::t.
Referenced by register_translator().
00239 { 00240 struct codec_dahdi_pvt *ztp = pvt->pvt; 00241 int res; 00242 00243 if (2 == ztp->fake) { 00244 ztp->fake = 1; 00245 pvt->f.frametype = AST_FRAME_VOICE; 00246 pvt->f.subclass = 0; 00247 pvt->f.samples = ztp->required_samples; 00248 pvt->f.data = NULL; 00249 pvt->f.offset = 0; 00250 pvt->f.datalen = 0; 00251 pvt->f.mallocd = 0; 00252 pvt->samples = 0; 00253 00254 return ast_frisolate(&pvt->f); 00255 00256 } else if (1 == ztp->fake) { 00257 ztp->fake = 0; 00258 return NULL; 00259 } 00260 00261 res = read(ztp->fd, pvt->outbuf + pvt->datalen, pvt->t->buf_size - pvt->datalen); 00262 if (-1 == res) { 00263 if (EWOULDBLOCK == errno) { 00264 /* Nothing waiting... */ 00265 return NULL; 00266 } else { 00267 ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno)); 00268 return NULL; 00269 } 00270 } else { 00271 pvt->f.datalen = res; 00272 pvt->f.samples = ztp->required_samples; 00273 pvt->f.frametype = AST_FRAME_VOICE; 00274 pvt->f.subclass = 1 << (pvt->t->dstfmt); 00275 pvt->f.mallocd = 0; 00276 pvt->f.offset = AST_FRIENDLY_OFFSET; 00277 pvt->f.src = pvt->t->name; 00278 pvt->f.data = pvt->outbuf; 00279 00280 pvt->samples = 0; 00281 pvt->datalen = 0; 00282 return ast_frisolate(&pvt->f); 00283 } 00284 00285 /* Shouldn't get here... */ 00286 return NULL; 00287 }
static int dahdi_new | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 473 of file codec_dahdi.c.
References dahdi_translate(), ast_translator::dstfmt, ast_translator::srcfmt, and ast_trans_pvt::t.
00474 { 00475 return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt); 00476 }
static int dahdi_translate | ( | struct ast_trans_pvt * | pvt, | |
int | dest, | |||
int | source | |||
) | [static] |
Definition at line 390 of file codec_dahdi.c.
References ast_atomic_fetchadd_int(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), errno, codec_dahdi_pvt::fd, codec_dahdi_pvt::fmts, G723_SAMPLES, G729_SAMPLES, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::softslin.
Referenced by dahdi_new().
00391 { 00392 /* Request translation through zap if possible */ 00393 int fd; 00394 struct codec_dahdi_pvt *ztp = pvt->pvt; 00395 int flags; 00396 int tried_once = 0; 00397 #ifdef HAVE_ZAPTEL 00398 const char *dev_filename = "/dev/zap/transcode"; 00399 #else 00400 const char *dev_filename = "/dev/dahdi/transcode"; 00401 #endif 00402 00403 if ((fd = open(dev_filename, O_RDWR)) < 0) { 00404 ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno)); 00405 return -1; 00406 } 00407 00408 ztp->fmts.srcfmt = (1 << source); 00409 ztp->fmts.dstfmt = (1 << dest); 00410 00411 if (option_debug) { 00412 ast_log(LOG_DEBUG, "Opening transcoder channel from %d to %d.\n", source, dest); 00413 } 00414 00415 retry: 00416 if (ioctl(fd, DAHDI_TC_ALLOCATE, &ztp->fmts)) { 00417 if ((ENODEV == errno) && !tried_once) { 00418 /* We requested to translate to/from an unsupported 00419 * format. Most likely this is because signed linear 00420 * was not supported by any hardware devices even 00421 * though this module always registers signed linear 00422 * support. In this case we'll retry, requesting 00423 * support for ULAW instead of signed linear and then 00424 * we'll just convert from ulaw to signed linear in 00425 * software. */ 00426 if (AST_FORMAT_SLINEAR == ztp->fmts.srcfmt) { 00427 if (option_debug) { 00428 ast_log(LOG_DEBUG, "Using soft_slin support on source\n"); 00429 } 00430 ztp->softslin = 1; 00431 ztp->fmts.srcfmt = AST_FORMAT_ULAW; 00432 } else if (AST_FORMAT_SLINEAR == ztp->fmts.dstfmt) { 00433 if (option_debug) { 00434 ast_log(LOG_DEBUG, "Using soft_slin support on destination\n"); 00435 } 00436 ztp->softslin = 1; 00437 ztp->fmts.dstfmt = AST_FORMAT_ULAW; 00438 } 00439 tried_once = 1; 00440 goto retry; 00441 } 00442 ast_log(LOG_ERROR, "Unable to attach to transcoder: %s\n", strerror(errno)); 00443 close(fd); 00444 00445 return -1; 00446 } 00447 00448 flags = fcntl(fd, F_GETFL); 00449 if (flags > - 1) { 00450 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) 00451 ast_log(LOG_WARNING, "Could not set non-block mode!\n"); 00452 } 00453 00454 ztp->fd = fd; 00455 00456 ztp->required_samples = ((ztp->fmts.dstfmt|ztp->fmts.srcfmt)&AST_FORMAT_G723_1) ? G723_SAMPLES : G729_SAMPLES; 00457 00458 switch (ztp->fmts.dstfmt) { 00459 case AST_FORMAT_G729A: 00460 ast_atomic_fetchadd_int(&channels.encoders, +1); 00461 break; 00462 case AST_FORMAT_G723_1: 00463 ast_atomic_fetchadd_int(&channels.encoders, +1); 00464 break; 00465 default: 00466 ast_atomic_fetchadd_int(&channels.decoders, +1); 00467 break; 00468 } 00469 00470 return 0; 00471 }
static void dahdi_write_frame | ( | struct codec_dahdi_pvt * | ztp, | |
const uint8_t * | buffer, | |||
const ssize_t | count | |||
) | [static] |
Definition at line 175 of file codec_dahdi.c.
References ast_log(), errno, codec_dahdi_pvt::fd, LOG_ERROR, and option_verbose.
Referenced by dahdi_decoder_framein(), and dahdi_encoder_framein().
00176 { 00177 int res; 00178 struct pollfd p = {0}; 00179 if (!count) return; 00180 res = write(ztp->fd, buffer, count); 00181 if (option_verbose > 10) { 00182 if (-1 == res) { 00183 ast_log(LOG_ERROR, "Failed to write to transcoder: %s\n", strerror(errno)); 00184 } 00185 if (count != res) { 00186 ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res); 00187 } 00188 } 00189 p.fd = ztp->fd; 00190 p.events = POLLOUT; 00191 res = poll(&p, 1, 50); 00192 }
static void drop_translator | ( | int | dst, | |
int | src | |||
) | [static] |
Definition at line 556 of file codec_dahdi.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_unregister_translator(), ast_translator::dstfmt, translator::entry, free, global_format_map, format_map::map, ast_translator::srcfmt, and translator::t.
00557 { 00558 struct translator *cur; 00559 00560 AST_LIST_LOCK(&translators); 00561 AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) { 00562 if (cur->t.srcfmt != src) 00563 continue; 00564 00565 if (cur->t.dstfmt != dst) 00566 continue; 00567 00568 AST_LIST_REMOVE_CURRENT(&translators, entry); 00569 ast_unregister_translator(&cur->t); 00570 free(cur); 00571 global_format_map.map[dst][src] = 0; 00572 break; 00573 } 00574 AST_LIST_TRAVERSE_SAFE_END; 00575 AST_LIST_UNLOCK(&translators); 00576 }
static struct ast_frame* fakesrc_sample | ( | void | ) | [static] |
Definition at line 478 of file codec_dahdi.c.
References AST_FRAME_VOICE, and f.
Referenced by register_translator().
00479 { 00480 /* Don't bother really trying to test hardware ones. */ 00481 static struct ast_frame f = { 00482 .frametype = AST_FRAME_VOICE, 00483 .samples = 160, 00484 .src = __PRETTY_FUNCTION__ 00485 }; 00486 00487 return &f; 00488 }
static int find_transcoders | ( | void | ) | [static] |
Definition at line 631 of file codec_dahdi.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), ast_verbose(), DAHDI_FILE_TRANSCODE, errno, LOG_ERROR, map, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module().
00632 { 00633 struct dahdi_transcoder_info info = { 0, }; 00634 struct format_map map = { { { 0 } } }; 00635 int fd, res; 00636 unsigned int x, y; 00637 00638 if ((fd = open(DAHDI_FILE_TRANSCODE, O_RDWR)) < 0) { 00639 ast_log(LOG_ERROR, "Failed to open " DAHDI_FILE_TRANSCODE ": %s\n", strerror(errno)); 00640 return 0; 00641 } 00642 00643 for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) { 00644 if (option_verbose > 1) 00645 ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name); 00646 00647 /* Complex codecs need to support signed linear. If the 00648 * hardware transcoder does not natively support signed linear 00649 * format, we will emulate it in software directly in this 00650 * module. Also, do not allow direct ulaw/alaw to complex 00651 * codec translation, since that will prevent the generic PLC 00652 * functions from working. */ 00653 if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) { 00654 info.dstfmts |= AST_FORMAT_SLINEAR; 00655 info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW); 00656 } 00657 if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) { 00658 info.srcfmts |= AST_FORMAT_SLINEAR; 00659 info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW); 00660 } 00661 00662 build_translators(&map, info.dstfmts, info.srcfmts); 00663 ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2); 00664 00665 } 00666 00667 close(fd); 00668 00669 if (!info.tcnum && (option_verbose > 1)) 00670 ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n"); 00671 00672 for (x = 0; x < 32; x++) { 00673 for (y = 0; y < 32; y++) { 00674 if (!map.map[x][y] && global_format_map.map[x][y]) 00675 drop_translator(x, y); 00676 } 00677 } 00678 00679 return 0; 00680 }
static int is_encoder | ( | struct translator * | zt | ) | [static] |
Definition at line 490 of file codec_dahdi.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_translator::srcfmt, and translator::t.
Referenced by register_translator().
00491 { 00492 if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) { 00493 return 1; 00494 } else { 00495 return 0; 00496 } 00497 }
static int lintoulaw | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 141 of file codec_dahdi.c.
References AST_LIN2MU, ast_log(), f, LOG_ERROR, ast_trans_pvt::pvt, codec_dahdi_pvt::samples_in_buffer, and codec_dahdi_pvt::ulaw_buffer.
00142 { 00143 struct codec_dahdi_pvt *ztp = pvt->pvt; 00144 int i = f->samples; 00145 uint8_t *dst = &ztp->ulaw_buffer[ztp->samples_in_buffer]; 00146 int16_t *src = (int16_t*)f->data; 00147 00148 if (ztp->samples_in_buffer + i > sizeof(ztp->ulaw_buffer)) { 00149 ast_log(LOG_ERROR, "Out of buffer space!\n"); 00150 return -i; 00151 } 00152 00153 while (i--) { 00154 *dst++ = AST_LIN2MU(*src++); 00155 } 00156 00157 ztp->samples_in_buffer += f->samples; 00158 return 0; 00159 }
static int load_module | ( | void | ) | [static] |
Definition at line 704 of file codec_dahdi.c.
References ast_cli_register_multiple(), ast_ulaw_init(), cli, find_transcoders(), and parse_config().
00705 { 00706 ast_ulaw_init(); 00707 parse_config(); 00708 find_transcoders(); 00709 ast_cli_register_multiple(cli, sizeof(cli) / sizeof(cli[0])); 00710 00711 return 0; 00712 }
static void parse_config | ( | void | ) | [static] |
Definition at line 590 of file codec_dahdi.c.
References ast_config_load(), ast_true(), ast_variable_browse(), ast_verbose(), option_verbose, var, and VERBOSE_PREFIX_3.
00591 { 00592 struct ast_variable *var; 00593 struct ast_config *cfg = ast_config_load("codecs.conf"); 00594 00595 if (!cfg) 00596 return; 00597 00598 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 00599 if (!strcasecmp(var->name, "genericplc")) { 00600 global_useplc = ast_true(var->value); 00601 if (option_verbose > 2) 00602 ast_verbose(VERBOSE_PREFIX_3 "codec_zap: %susing generic PLC\n", 00603 global_useplc ? "" : "not "); 00604 } 00605 } 00606 00607 ast_config_destroy(cfg); 00608 }
static int register_translator | ( | int | dst, | |
int | src | |||
) | [static] |
Definition at line 499 of file codec_dahdi.c.
References ast_calloc, AST_FORMAT_G723_1, ast_getformatname(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_register_translator, BUFFER_SIZE, dahdi_decoder_framein(), dahdi_decoder_frameout(), dahdi_destroy(), dahdi_encoder_framein(), dahdi_encoder_frameout(), dahdi_new(), translator::entry, fakesrc_sample(), free, G723_SAMPLES, G729_SAMPLES, global_format_map, is_encoder(), and format_map::map.
Referenced by build_translators().
00500 { 00501 struct translator *zt; 00502 int res; 00503 00504 if (!(zt = ast_calloc(1, sizeof(*zt)))) { 00505 return -1; 00506 } 00507 00508 snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s", 00509 ast_getformatname((1 << src)), ast_getformatname((1 << dst))); 00510 zt->t.srcfmt = (1 << src); 00511 zt->t.dstfmt = (1 << dst); 00512 zt->t.buf_size = BUFFER_SIZE; 00513 if (is_encoder(zt)) { 00514 zt->t.framein = dahdi_encoder_framein; 00515 zt->t.frameout = dahdi_encoder_frameout; 00516 #if 0 00517 zt->t.buffer_samples = 0; 00518 #endif 00519 } else { 00520 zt->t.framein = dahdi_decoder_framein; 00521 zt->t.frameout = dahdi_decoder_frameout; 00522 #if 0 00523 if (AST_FORMAT_G723_1 == zt->t.srcfmt) { 00524 zt->t.plc_samples = G723_SAMPLES; 00525 } else { 00526 zt->t.plc_samples = G729_SAMPLES; 00527 } 00528 zt->t.buffer_samples = zt->t.plc_samples * 8; 00529 #endif 00530 } 00531 zt->t.destroy = dahdi_destroy; 00532 zt->t.buffer_samples = 0; 00533 zt->t.newpvt = dahdi_new; 00534 zt->t.sample = fakesrc_sample; 00535 #if 0 00536 zt->t.useplc = global_useplc; 00537 #endif 00538 zt->t.useplc = 0; 00539 zt->t.native_plc = 0; 00540 00541 zt->t.desc_size = sizeof(struct codec_dahdi_pvt); 00542 if ((res = ast_register_translator(&zt->t))) { 00543 free(zt); 00544 return -1; 00545 } 00546 00547 AST_LIST_LOCK(&translators); 00548 AST_LIST_INSERT_HEAD(&translators, zt, entry); 00549 AST_LIST_UNLOCK(&translators); 00550 00551 global_format_map.map[dst][src] = 1; 00552 00553 return res; 00554 }
static int reload | ( | void | ) | [static] |
Definition at line 682 of file codec_dahdi.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, translator::entry, global_useplc, parse_config(), translator::t, and ast_translator::useplc.
00683 { 00684 struct translator *cur; 00685 00686 parse_config(); 00687 00688 AST_LIST_LOCK(&translators); 00689 AST_LIST_TRAVERSE(&translators, cur, entry) 00690 cur->t.useplc = global_useplc; 00691 AST_LIST_UNLOCK(&translators); 00692 00693 return 0; 00694 }
static int transcoder_show | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 161 of file codec_dahdi.c.
References ast_cli(), copy(), and RESULT_SUCCESS.
00162 { 00163 struct channel_usage copy; 00164 00165 copy = channels; 00166 00167 if (copy.total == 0) 00168 ast_cli(fd, "No DAHDI transcoders found.\n"); 00169 else 00170 ast_cli(fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total); 00171 00172 return RESULT_SUCCESS; 00173 }
static int ulawtolin | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 125 of file codec_dahdi.c.
References AST_MULAW, ast_trans_pvt::datalen, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::ulaw_buffer.
00126 { 00127 struct codec_dahdi_pvt *ztp = pvt->pvt; 00128 int i = ztp->required_samples; 00129 uint8_t *src = &ztp->ulaw_buffer[0]; 00130 int16_t *dst = (int16_t *)pvt->outbuf + pvt->datalen; 00131 00132 /* convert and copy in outbuf */ 00133 while (i--) { 00134 *dst++ = AST_MULAW(*src++); 00135 } 00136 00137 return 0; 00138 }
static int unload_module | ( | void | ) | [static] |
Definition at line 696 of file codec_dahdi.c.
References ast_cli_unregister_multiple(), cli, and unregister_translators().
00697 { 00698 ast_cli_unregister_multiple(cli, sizeof(cli) / sizeof(cli[0])); 00699 unregister_translators(); 00700 00701 return 0; 00702 }
static void unregister_translators | ( | void | ) | [static] |
Definition at line 578 of file codec_dahdi.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_unregister_translator(), translator::entry, free, and translator::t.
Referenced by unload_module().
00579 { 00580 struct translator *cur; 00581 00582 AST_LIST_LOCK(&translators); 00583 while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) { 00584 ast_unregister_translator(&cur->t); 00585 free(cur); 00586 } 00587 AST_LIST_UNLOCK(&translators); 00588 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Generic DAHDI Transcoder Codec Translator" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 718 of file codec_dahdi.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 718 of file codec_dahdi.c.
struct channel_usage channels [static] |
struct ast_cli_entry cli[] [static] |
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] |
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.