#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_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 *dahdip, 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 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_info * | ast_module_info = &__mod_info |
static struct channel_usage | channels |
static struct ast_cli_entry | cli [] |
static struct format_map | global_format_map = { { { 0 } } } |
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 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 }
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().