#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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 646 of file codec_dahdi.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 646 of file codec_dahdi.c.
static void build_translators | ( | struct format_map * | map, | |
unsigned int | dstfmts, | |||
unsigned int | srcfmts | |||
) | [static] |
Definition at line 549 of file codec_dahdi.c.
References global_format_map, map, format_map::map, and register_translator().
00550 { 00551 unsigned int src, dst; 00552 00553 for (src = 0; src < 32; src++) { 00554 for (dst = 0; dst < 32; dst++) { 00555 if (!(srcfmts & (1 << src))) 00556 continue; 00557 00558 if (!(dstfmts & (1 << dst))) 00559 continue; 00560 00561 if (global_format_map.map[dst][src]) 00562 continue; 00563 00564 if (!register_translator(dst, src)) 00565 map->map[dst][src] = 1; 00566 } 00567 } 00568 }
static int dahdi_decoder_framein | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 273 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().
00274 { 00275 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00276 00277 if (!f->subclass.codec) { 00278 /* We're just faking a return for calculation purposes. */ 00279 dahdip->fake = 2; 00280 pvt->samples = f->samples; 00281 return 0; 00282 } 00283 00284 if (!f->datalen) { 00285 if (f->samples != dahdip->required_samples) { 00286 ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, dahdip->required_samples, f->datalen); 00287 } 00288 } 00289 dahdi_write_frame(dahdip, f->data.ptr, f->datalen); 00290 pvt->samples += f->samples; 00291 pvt->datalen = 0; 00292 return -1; 00293 }
static struct ast_frame* dahdi_decoder_frameout | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 295 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().
00296 { 00297 int res; 00298 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00299 00300 if (2 == dahdip->fake) { 00301 dahdip->fake = 1; 00302 pvt->f.frametype = AST_FRAME_VOICE; 00303 pvt->f.subclass.codec = 0; 00304 pvt->f.samples = dahdip->required_samples; 00305 pvt->f.data.ptr = NULL; 00306 pvt->f.offset = 0; 00307 pvt->f.datalen = 0; 00308 pvt->f.mallocd = 0; 00309 pvt->samples = 0; 00310 return ast_frisolate(&pvt->f); 00311 } else if (1 == dahdip->fake) { 00312 pvt->samples = 0; 00313 dahdip->fake = 0; 00314 return NULL; 00315 } 00316 00317 /* Let's check to see if there is a new frame for us.... */ 00318 if (dahdip->softslin) { 00319 res = read(dahdip->fd, dahdip->ulaw_buffer, sizeof(dahdip->ulaw_buffer)); 00320 } else { 00321 res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen); 00322 } 00323 00324 if (-1 == res) { 00325 if (EWOULDBLOCK == errno) { 00326 /* Nothing waiting... */ 00327 return NULL; 00328 } else { 00329 ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno)); 00330 return NULL; 00331 } 00332 } else { 00333 if (dahdip->softslin) { 00334 ulawtolin(pvt, res); 00335 pvt->f.datalen = res * 2; 00336 } else { 00337 pvt->f.datalen = res; 00338 } 00339 pvt->datalen = 0; 00340 pvt->f.frametype = AST_FRAME_VOICE; 00341 pvt->f.subclass.codec = 1 << (pvt->t->dstfmt); 00342 pvt->f.mallocd = 0; 00343 pvt->f.offset = AST_FRIENDLY_OFFSET; 00344 pvt->f.src = pvt->t->name; 00345 pvt->f.data.ptr = pvt->outbuf.c; 00346 pvt->f.samples = res; 00347 pvt->samples = 0; 00348 00349 return ast_frisolate(&pvt->f); 00350 } 00351 00352 /* Shouldn't get here... */ 00353 return NULL; 00354 }
static void dahdi_destroy | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 357 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().
00358 { 00359 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00360 00361 switch (dahdip->fmts.dstfmt) { 00362 case AST_FORMAT_G729A: 00363 case AST_FORMAT_G723_1: 00364 ast_atomic_fetchadd_int(&channels.encoders, -1); 00365 break; 00366 default: 00367 ast_atomic_fetchadd_int(&channels.decoders, -1); 00368 break; 00369 } 00370 00371 close(dahdip->fd); 00372 }
static int dahdi_encoder_framein | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 178 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().
00179 { 00180 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00181 00182 if (!f->subclass.codec) { 00183 /* We're just faking a return for calculation purposes. */ 00184 dahdip->fake = 2; 00185 pvt->samples = f->samples; 00186 return 0; 00187 } 00188 00189 /* Buffer up the packets and send them to the hardware if we 00190 * have enough samples set up. */ 00191 if (dahdip->softslin) { 00192 if (lintoulaw(pvt, f)) { 00193 return -1; 00194 } 00195 } else { 00196 /* NOTE: If softslin support is not needed, and the sample 00197 * size is equal to the required sample size, we wouldn't 00198 * need this copy operation. But at the time this was 00199 * written, only softslin is supported. */ 00200 if (dahdip->samples_in_buffer + f->samples > sizeof(dahdip->ulaw_buffer)) { 00201 ast_log(LOG_ERROR, "Out of buffer space.\n"); 00202 return -1; 00203 } 00204 memcpy(&dahdip->ulaw_buffer[dahdip->samples_in_buffer], f->data.ptr, f->samples); 00205 dahdip->samples_in_buffer += f->samples; 00206 } 00207 00208 while (dahdip->samples_in_buffer > dahdip->required_samples) { 00209 dahdi_write_frame(dahdip, dahdip->ulaw_buffer, dahdip->required_samples); 00210 dahdip->samples_in_buffer -= dahdip->required_samples; 00211 if (dahdip->samples_in_buffer) { 00212 /* Shift any remaining bytes down. */ 00213 memmove(dahdip->ulaw_buffer, &dahdip->ulaw_buffer[dahdip->required_samples], 00214 dahdip->samples_in_buffer); 00215 } 00216 } 00217 pvt->samples += f->samples; 00218 pvt->datalen = 0; 00219 return -1; 00220 }
static struct ast_frame* dahdi_encoder_frameout | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 222 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().
00223 { 00224 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00225 int res; 00226 00227 if (2 == dahdip->fake) { 00228 dahdip->fake = 1; 00229 pvt->f.frametype = AST_FRAME_VOICE; 00230 pvt->f.subclass.codec = 0; 00231 pvt->f.samples = dahdip->required_samples; 00232 pvt->f.data.ptr = NULL; 00233 pvt->f.offset = 0; 00234 pvt->f.datalen = 0; 00235 pvt->f.mallocd = 0; 00236 pvt->samples = 0; 00237 00238 return ast_frisolate(&pvt->f); 00239 00240 } else if (1 == dahdip->fake) { 00241 dahdip->fake = 0; 00242 return NULL; 00243 } 00244 00245 res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen); 00246 if (-1 == res) { 00247 if (EWOULDBLOCK == errno) { 00248 /* Nothing waiting... */ 00249 return NULL; 00250 } else { 00251 ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno)); 00252 return NULL; 00253 } 00254 } else { 00255 pvt->f.datalen = res; 00256 pvt->f.samples = dahdip->required_samples; 00257 pvt->f.frametype = AST_FRAME_VOICE; 00258 pvt->f.subclass.codec = 1 << (pvt->t->dstfmt); 00259 pvt->f.mallocd = 0; 00260 pvt->f.offset = AST_FRIENDLY_OFFSET; 00261 pvt->f.src = pvt->t->name; 00262 pvt->f.data.ptr = pvt->outbuf.c; 00263 00264 pvt->samples = 0; 00265 pvt->datalen = 0; 00266 return ast_frisolate(&pvt->f); 00267 } 00268 00269 /* Shouldn't get here... */ 00270 return NULL; 00271 }
static int dahdi_new | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 447 of file codec_dahdi.c.
References dahdi_translate(), ast_translator::dstfmt, ast_translator::srcfmt, and ast_trans_pvt::t.
00448 { 00449 return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt); 00450 }
static int dahdi_translate | ( | struct ast_trans_pvt * | pvt, | |
int | dest, | |||
int | source | |||
) | [static] |
Definition at line 374 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().
00375 { 00376 /* Request translation through zap if possible */ 00377 int fd; 00378 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00379 int flags; 00380 int tried_once = 0; 00381 const char *dev_filename = "/dev/dahdi/transcode"; 00382 00383 if ((fd = open(dev_filename, O_RDWR)) < 0) { 00384 ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno)); 00385 return -1; 00386 } 00387 00388 dahdip->fmts.srcfmt = (1 << source); 00389 dahdip->fmts.dstfmt = (1 << dest); 00390 00391 ast_debug(1, "Opening transcoder channel from %d to %d.\n", source, dest); 00392 00393 retry: 00394 if (ioctl(fd, DAHDI_TC_ALLOCATE, &dahdip->fmts)) { 00395 if ((ENODEV == errno) && !tried_once) { 00396 /* We requested to translate to/from an unsupported 00397 * format. Most likely this is because signed linear 00398 * was not supported by any hardware devices even 00399 * though this module always registers signed linear 00400 * support. In this case we'll retry, requesting 00401 * support for ULAW instead of signed linear and then 00402 * we'll just convert from ulaw to signed linear in 00403 * software. */ 00404 if (AST_FORMAT_SLINEAR == dahdip->fmts.srcfmt) { 00405 ast_debug(1, "Using soft_slin support on source\n"); 00406 dahdip->softslin = 1; 00407 dahdip->fmts.srcfmt = AST_FORMAT_ULAW; 00408 } else if (AST_FORMAT_SLINEAR == dahdip->fmts.dstfmt) { 00409 ast_debug(1, "Using soft_slin support on destination\n"); 00410 dahdip->softslin = 1; 00411 dahdip->fmts.dstfmt = AST_FORMAT_ULAW; 00412 } 00413 tried_once = 1; 00414 goto retry; 00415 } 00416 ast_log(LOG_ERROR, "Unable to attach to transcoder: %s\n", strerror(errno)); 00417 close(fd); 00418 00419 return -1; 00420 } 00421 00422 flags = fcntl(fd, F_GETFL); 00423 if (flags > - 1) { 00424 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) 00425 ast_log(LOG_WARNING, "Could not set non-block mode!\n"); 00426 } 00427 00428 dahdip->fd = fd; 00429 00430 dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt)&AST_FORMAT_G723_1) ? G723_SAMPLES : G729_SAMPLES; 00431 00432 switch (dahdip->fmts.dstfmt) { 00433 case AST_FORMAT_G729A: 00434 ast_atomic_fetchadd_int(&channels.encoders, +1); 00435 break; 00436 case AST_FORMAT_G723_1: 00437 ast_atomic_fetchadd_int(&channels.encoders, +1); 00438 break; 00439 default: 00440 ast_atomic_fetchadd_int(&channels.decoders, +1); 00441 break; 00442 } 00443 00444 return 0; 00445 }
static void dahdi_write_frame | ( | struct codec_dahdi_pvt * | dahdip, | |
const uint8_t * | buffer, | |||
const ssize_t | count | |||
) | [static] |
Definition at line 159 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().
00160 { 00161 int res; 00162 struct pollfd p = {0}; 00163 if (!count) return; 00164 res = write(dahdip->fd, buffer, count); 00165 if (option_verbose > 10) { 00166 if (-1 == res) { 00167 ast_log(LOG_ERROR, "Failed to write to transcoder: %s\n", strerror(errno)); 00168 } 00169 if (count != res) { 00170 ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res); 00171 } 00172 } 00173 p.fd = dahdip->fd; 00174 p.events = POLLOUT; 00175 res = poll(&p, 1, 50); 00176 }
static void drop_translator | ( | int | dst, | |
int | src | |||
) | [static] |
Definition at line 515 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.
00516 { 00517 struct translator *cur; 00518 00519 AST_LIST_LOCK(&translators); 00520 AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) { 00521 if (cur->t.srcfmt != src) 00522 continue; 00523 00524 if (cur->t.dstfmt != dst) 00525 continue; 00526 00527 AST_LIST_REMOVE_CURRENT(entry); 00528 ast_unregister_translator(&cur->t); 00529 ast_free(cur); 00530 global_format_map.map[dst][src] = 0; 00531 break; 00532 } 00533 AST_LIST_TRAVERSE_SAFE_END; 00534 AST_LIST_UNLOCK(&translators); 00535 }
static struct ast_frame* fakesrc_sample | ( | void | ) | [static] |
Definition at line 452 of file codec_dahdi.c.
References AST_FRAME_VOICE, and f.
Referenced by register_translator().
00453 { 00454 /* Don't bother really trying to test hardware ones. */ 00455 static struct ast_frame f = { 00456 .frametype = AST_FRAME_VOICE, 00457 .samples = 160, 00458 .src = __PRETTY_FUNCTION__ 00459 }; 00460 00461 return &f; 00462 }
static int find_transcoders | ( | void | ) | [static] |
Definition at line 570 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().
00571 { 00572 struct dahdi_transcoder_info info = { 0, }; 00573 struct format_map map = { { { 0 } } }; 00574 int fd, res; 00575 unsigned int x, y; 00576 00577 if ((fd = open("/dev/dahdi/transcode", O_RDWR)) < 0) { 00578 ast_log(LOG_ERROR, "Failed to open /dev/dahdi/transcode: %s\n", strerror(errno)); 00579 return 0; 00580 } 00581 00582 for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) { 00583 if (option_verbose > 1) 00584 ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name); 00585 00586 /* Complex codecs need to support signed linear. If the 00587 * hardware transcoder does not natively support signed linear 00588 * format, we will emulate it in software directly in this 00589 * module. Also, do not allow direct ulaw/alaw to complex 00590 * codec translation, since that will prevent the generic PLC 00591 * functions from working. */ 00592 if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) { 00593 info.dstfmts |= AST_FORMAT_SLINEAR; 00594 info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW); 00595 } 00596 if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) { 00597 info.srcfmts |= AST_FORMAT_SLINEAR; 00598 info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW); 00599 } 00600 00601 build_translators(&map, info.dstfmts, info.srcfmts); 00602 ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2); 00603 00604 } 00605 00606 close(fd); 00607 00608 if (!info.tcnum && (option_verbose > 1)) 00609 ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n"); 00610 00611 for (x = 0; x < 32; x++) { 00612 for (y = 0; y < 32; y++) { 00613 if (!map.map[x][y] && global_format_map.map[x][y]) 00614 drop_translator(x, y); 00615 } 00616 } 00617 00618 return 0; 00619 }
static char * handle_cli_transcoder_show | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 131 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.
00132 { 00133 struct channel_usage copy; 00134 00135 switch (cmd) { 00136 case CLI_INIT: 00137 e->command = "transcoder show"; 00138 e->usage = 00139 "Usage: transcoder show\n" 00140 " Displays channel utilization of DAHDI transcoder(s).\n"; 00141 return NULL; 00142 case CLI_GENERATE: 00143 return NULL; 00144 } 00145 00146 if (a->argc != 2) 00147 return CLI_SHOWUSAGE; 00148 00149 copy = channels; 00150 00151 if (copy.total == 0) 00152 ast_cli(a->fd, "No DAHDI transcoders found.\n"); 00153 else 00154 ast_cli(a->fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total); 00155 00156 return CLI_SUCCESS; 00157 }
static int is_encoder | ( | struct translator * | zt | ) | [static] |
Definition at line 464 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().
00465 { 00466 if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) { 00467 return 1; 00468 } else { 00469 return 0; 00470 } 00471 }
static int lintoulaw | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 111 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.
00112 { 00113 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00114 int i = f->samples; 00115 uint8_t *dst = &dahdip->ulaw_buffer[dahdip->samples_in_buffer]; 00116 int16_t *src = f->data.ptr; 00117 00118 if (dahdip->samples_in_buffer + i > sizeof(dahdip->ulaw_buffer)) { 00119 ast_log(LOG_ERROR, "Out of buffer space!\n"); 00120 return -i; 00121 } 00122 00123 while (i--) { 00124 *dst++ = AST_LIN2MU(*src++); 00125 } 00126 00127 dahdip->samples_in_buffer += f->samples; 00128 return 0; 00129 }
static int load_module | ( | void | ) | [static] |
Definition at line 634 of file codec_dahdi.c.
References ARRAY_LEN, ast_cli_register_multiple(), AST_MODULE_LOAD_SUCCESS, ast_ulaw_init(), cli, and find_transcoders().
00635 { 00636 ast_ulaw_init(); 00637 find_transcoders(); 00638 ast_cli_register_multiple(cli, ARRAY_LEN(cli)); 00639 return AST_MODULE_LOAD_SUCCESS; 00640 }
static int register_translator | ( | int | dst, | |
int | src | |||
) | [static] |
Definition at line 473 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().
00474 { 00475 struct translator *zt; 00476 int res; 00477 00478 if (!(zt = ast_calloc(1, sizeof(*zt)))) { 00479 return -1; 00480 } 00481 00482 snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s", 00483 ast_getformatname((1 << src)), ast_getformatname((1 << dst))); 00484 zt->t.srcfmt = (1 << src); 00485 zt->t.dstfmt = (1 << dst); 00486 zt->t.buf_size = BUFFER_SIZE; 00487 if (is_encoder(zt)) { 00488 zt->t.framein = dahdi_encoder_framein; 00489 zt->t.frameout = dahdi_encoder_frameout; 00490 } else { 00491 zt->t.framein = dahdi_decoder_framein; 00492 zt->t.frameout = dahdi_decoder_frameout; 00493 } 00494 zt->t.destroy = dahdi_destroy; 00495 zt->t.buffer_samples = 0; 00496 zt->t.newpvt = dahdi_new; 00497 zt->t.sample = fakesrc_sample; 00498 zt->t.native_plc = 0; 00499 00500 zt->t.desc_size = sizeof(struct codec_dahdi_pvt); 00501 if ((res = ast_register_translator(&zt->t))) { 00502 ast_free(zt); 00503 return -1; 00504 } 00505 00506 AST_LIST_LOCK(&translators); 00507 AST_LIST_INSERT_HEAD(&translators, zt, entry); 00508 AST_LIST_UNLOCK(&translators); 00509 00510 global_format_map.map[dst][src] = 1; 00511 00512 return res; 00513 }
static int reload | ( | void | ) | [static] |
Definition at line 621 of file codec_dahdi.c.
References AST_MODULE_LOAD_SUCCESS.
00622 { 00623 return AST_MODULE_LOAD_SUCCESS; 00624 }
static int ulawtolin | ( | struct ast_trans_pvt * | pvt, | |
int | samples | |||
) | [static] |
Definition at line 95 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.
00096 { 00097 struct codec_dahdi_pvt *dahdip = pvt->pvt; 00098 int i = samples; 00099 uint8_t *src = &dahdip->ulaw_buffer[0]; 00100 int16_t *dst = pvt->outbuf.i16 + pvt->datalen; 00101 00102 /* convert and copy in outbuf */ 00103 while (i--) { 00104 *dst++ = AST_MULAW(*src++); 00105 } 00106 00107 return 0; 00108 }
static int unload_module | ( | void | ) | [static] |
Definition at line 626 of file codec_dahdi.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), cli, and unregister_translators().
00627 { 00628 ast_cli_unregister_multiple(cli, ARRAY_LEN(cli)); 00629 unregister_translators(); 00630 00631 return 0; 00632 }
static void unregister_translators | ( | void | ) | [static] |
Definition at line 537 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().
00538 { 00539 struct translator *cur; 00540 00541 AST_LIST_LOCK(&translators); 00542 while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) { 00543 ast_unregister_translator(&cur->t); 00544 ast_free(cur); 00545 } 00546 AST_LIST_UNLOCK(&translators); 00547 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 646 of file codec_dahdi.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 646 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 67 of file codec_dahdi.c.
Referenced by load_module(), and unload_module().
struct format_map global_format_map = { { { 0 } } } [static] |
Definition at line 75 of file codec_dahdi.c.
Referenced by build_translators(), drop_translator(), and register_translator().