#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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 716 of file codec_dahdi.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 716 of file codec_dahdi.c.
static void build_translators | ( | struct format_map * | map, | |
unsigned int | dstfmts, | |||
unsigned int | srcfmts | |||
) | [static] |
Definition at line 608 of file codec_dahdi.c.
References global_format_map, map, format_map::map, and register_translator().
00609 { 00610 unsigned int src, dst; 00611 00612 for (src = 0; src < 32; src++) { 00613 for (dst = 0; dst < 32; dst++) { 00614 if (!(srcfmts & (1 << src))) 00615 continue; 00616 00617 if (!(dstfmts & (1 << dst))) 00618 continue; 00619 00620 if (global_format_map.map[dst][src]) 00621 continue; 00622 00623 if (!register_translator(dst, src)) 00624 map->map[dst][src] = 1; 00625 } 00626 } 00627 }
static int dahdi_decoder_framein | ( | struct ast_trans_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 291 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().
00292 { 00293 struct codec_dahdi_pvt *ztp = pvt->pvt; 00294 00295 if (!f->subclass) { 00296 /* We're just faking a return for calculation purposes. */ 00297 ztp->fake = 2; 00298 pvt->samples = f->samples; 00299 return 0; 00300 } 00301 00302 if (!f->datalen) { 00303 if (f->samples != ztp->required_samples) { 00304 ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, ztp->required_samples, f->datalen); 00305 } 00306 } 00307 dahdi_write_frame(ztp, f->data, f->datalen); 00308 pvt->samples += f->samples; 00309 pvt->datalen = 0; 00310 return -1; 00311 }
static struct ast_frame* dahdi_decoder_frameout | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 313 of file codec_dahdi.c.
References AST_FRAME_VOICE, AST_FRFLAG_FROM_TRANSLATOR, AST_FRIENDLY_OFFSET, ast_log(), ast_set_flag, 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().
00314 { 00315 int res; 00316 struct codec_dahdi_pvt *ztp = pvt->pvt; 00317 00318 if (2 == ztp->fake) { 00319 ztp->fake = 1; 00320 pvt->f.frametype = AST_FRAME_VOICE; 00321 pvt->f.subclass = 0; 00322 pvt->f.samples = ztp->required_samples; 00323 pvt->f.data = NULL; 00324 pvt->f.offset = 0; 00325 pvt->f.datalen = 0; 00326 pvt->f.mallocd = 0; 00327 ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR); 00328 pvt->samples = 0; 00329 return &pvt->f; 00330 } else if (1 == ztp->fake) { 00331 pvt->samples = 0; 00332 ztp->fake = 0; 00333 return NULL; 00334 } 00335 00336 /* Let's check to see if there is a new frame for us.... */ 00337 if (ztp->softslin) { 00338 res = read(ztp->fd, ztp->ulaw_buffer, sizeof(ztp->ulaw_buffer)); 00339 } else { 00340 res = read(ztp->fd, pvt->outbuf + pvt->datalen, pvt->t->buf_size - pvt->datalen); 00341 } 00342 00343 if (-1 == res) { 00344 if (EWOULDBLOCK == errno) { 00345 /* Nothing waiting... */ 00346 return NULL; 00347 } else { 00348 ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno)); 00349 return NULL; 00350 } 00351 } else { 00352 if (ztp->softslin) { 00353 ulawtolin(pvt); 00354 pvt->f.datalen = res * 2; 00355 } else { 00356 pvt->f.datalen = res; 00357 } 00358 pvt->datalen = 0; 00359 pvt->f.frametype = AST_FRAME_VOICE; 00360 pvt->f.subclass = 1 << (pvt->t->dstfmt); 00361 pvt->f.mallocd = 0; 00362 pvt->f.offset = AST_FRIENDLY_OFFSET; 00363 pvt->f.src = pvt->t->name; 00364 pvt->f.data = pvt->outbuf; 00365 pvt->f.samples = ztp->required_samples; 00366 ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR); 00367 pvt->samples = 0; 00368 00369 return &pvt->f; 00370 } 00371 00372 /* Shouldn't get here... */ 00373 return NULL; 00374 }
static void dahdi_destroy | ( | struct ast_trans_pvt * | pvt | ) | [static] |
Definition at line 377 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().
00378 { 00379 struct codec_dahdi_pvt *ztp = pvt->pvt; 00380 00381 switch (ztp->fmts.dstfmt) { 00382 case AST_FORMAT_G729A: 00383 case AST_FORMAT_G723_1: 00384 ast_atomic_fetchadd_int(&channels.encoders, -1); 00385 break; 00386 default: 00387 ast_atomic_fetchadd_int(&channels.decoders, -1); 00388 break; 00389 } 00390 00391 close(ztp->fd); 00392 }
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_FRFLAG_FROM_TRANSLATOR, AST_FRIENDLY_OFFSET, ast_log(), ast_set_flag, 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 ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR); 00253 pvt->samples = 0; 00254 00255 return &pvt->f; 00256 00257 } else if (1 == ztp->fake) { 00258 ztp->fake = 0; 00259 return NULL; 00260 } 00261 00262 res = read(ztp->fd, pvt->outbuf + pvt->datalen, pvt->t->buf_size - pvt->datalen); 00263 if (-1 == res) { 00264 if (EWOULDBLOCK == errno) { 00265 /* Nothing waiting... */ 00266 return NULL; 00267 } else { 00268 ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno)); 00269 return NULL; 00270 } 00271 } else { 00272 pvt->f.datalen = res; 00273 pvt->f.samples = ztp->required_samples; 00274 pvt->f.frametype = AST_FRAME_VOICE; 00275 pvt->f.subclass = 1 << (pvt->t->dstfmt); 00276 pvt->f.mallocd = 0; 00277 pvt->f.offset = AST_FRIENDLY_OFFSET; 00278 pvt->f.src = pvt->t->name; 00279 pvt->f.data = pvt->outbuf; 00280 ast_set_flag(&pvt->f, AST_FRFLAG_FROM_TRANSLATOR); 00281 00282 pvt->samples = 0; 00283 pvt->datalen = 0; 00284 return &pvt->f; 00285 } 00286 00287 /* Shouldn't get here... */ 00288 return NULL; 00289 }
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 394 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, ast_trans_pvt::pvt, codec_dahdi_pvt::required_samples, and codec_dahdi_pvt::softslin.
Referenced by dahdi_new().
00395 { 00396 /* Request translation through zap if possible */ 00397 int fd; 00398 struct codec_dahdi_pvt *ztp = pvt->pvt; 00399 int flags; 00400 int tried_once = 0; 00401 #ifdef HAVE_ZAPTEL 00402 const char *dev_filename = "/dev/zap/transcode"; 00403 #else 00404 const char *dev_filename = "/dev/dahdi/transcode"; 00405 #endif 00406 00407 if ((fd = open(dev_filename, O_RDWR)) < 0) { 00408 ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno)); 00409 return -1; 00410 } 00411 00412 ztp->fmts.srcfmt = (1 << source); 00413 ztp->fmts.dstfmt = (1 << dest); 00414 00415 ast_log(LOG_DEBUG, "Opening transcoder channel from %d to %d.\n", source, dest); 00416 00417 retry: 00418 if (ioctl(fd, DAHDI_TC_ALLOCATE, &ztp->fmts)) { 00419 if ((ENODEV == errno) && !tried_once) { 00420 /* We requested to translate to/from an unsupported 00421 * format. Most likely this is because signed linear 00422 * was not supported by any hardware devices even 00423 * though this module always registers signed linear 00424 * support. In this case we'll retry, requesting 00425 * support for ULAW instead of signed linear and then 00426 * we'll just convert from ulaw to signed linear in 00427 * software. */ 00428 if (AST_FORMAT_SLINEAR == ztp->fmts.srcfmt) { 00429 ast_log(LOG_DEBUG, "Using soft_slin support on source\n"); 00430 ztp->softslin = 1; 00431 ztp->fmts.srcfmt = AST_FORMAT_ULAW; 00432 } else if (AST_FORMAT_SLINEAR == ztp->fmts.dstfmt) { 00433 ast_log(LOG_DEBUG, "Using soft_slin support on destination\n"); 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 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 554 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.
00555 { 00556 struct translator *cur; 00557 00558 AST_LIST_LOCK(&translators); 00559 AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) { 00560 if (cur->t.srcfmt != src) 00561 continue; 00562 00563 if (cur->t.dstfmt != dst) 00564 continue; 00565 00566 AST_LIST_REMOVE_CURRENT(&translators, entry); 00567 ast_unregister_translator(&cur->t); 00568 free(cur); 00569 global_format_map.map[dst][src] = 0; 00570 break; 00571 } 00572 AST_LIST_TRAVERSE_SAFE_END; 00573 AST_LIST_UNLOCK(&translators); 00574 }
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 629 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().
00630 { 00631 struct dahdi_transcoder_info info = { 0, }; 00632 struct format_map map = { { { 0 } } }; 00633 int fd, res; 00634 unsigned int x, y; 00635 00636 if ((fd = open(DAHDI_FILE_TRANSCODE, O_RDWR)) < 0) { 00637 ast_log(LOG_ERROR, "Failed to open " DAHDI_FILE_TRANSCODE ": %s\n", strerror(errno)); 00638 return 0; 00639 } 00640 00641 for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) { 00642 if (option_verbose > 1) 00643 ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name); 00644 00645 /* Complex codecs need to support signed linear. If the 00646 * hardware transcoder does not natively support signed linear 00647 * format, we will emulate it in software directly in this 00648 * module. Also, do not allow direct ulaw/alaw to complex 00649 * codec translation, since that will prevent the generic PLC 00650 * functions from working. */ 00651 if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) { 00652 info.dstfmts |= AST_FORMAT_SLINEAR; 00653 info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW); 00654 } 00655 if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) { 00656 info.srcfmts |= AST_FORMAT_SLINEAR; 00657 info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW); 00658 } 00659 00660 build_translators(&map, info.dstfmts, info.srcfmts); 00661 ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2); 00662 00663 } 00664 00665 close(fd); 00666 00667 if (!info.tcnum && (option_verbose > 1)) 00668 ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n"); 00669 00670 for (x = 0; x < 32; x++) { 00671 for (y = 0; y < 32; y++) { 00672 if (!map.map[x][y] && global_format_map.map[x][y]) 00673 drop_translator(x, y); 00674 } 00675 } 00676 00677 return 0; 00678 }
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 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 702 of file codec_dahdi.c.
References ast_cli_register_multiple(), ast_ulaw_init(), cli, find_transcoders(), and parse_config().
00703 { 00704 ast_ulaw_init(); 00705 parse_config(); 00706 find_transcoders(); 00707 ast_cli_register_multiple(cli, sizeof(cli) / sizeof(cli[0])); 00708 00709 return 0; 00710 }
static void parse_config | ( | void | ) | [static] |
Definition at line 588 of file codec_dahdi.c.
References ast_config_load(), ast_true(), ast_variable_browse(), ast_verbose(), option_verbose, var, and VERBOSE_PREFIX_3.
00589 { 00590 struct ast_variable *var; 00591 struct ast_config *cfg = ast_config_load("codecs.conf"); 00592 00593 if (!cfg) 00594 return; 00595 00596 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 00597 if (!strcasecmp(var->name, "genericplc")) { 00598 global_useplc = ast_true(var->value); 00599 if (option_verbose > 2) 00600 ast_verbose(VERBOSE_PREFIX_3 "codec_zap: %susing generic PLC\n", 00601 global_useplc ? "" : "not "); 00602 } 00603 } 00604 00605 ast_config_destroy(cfg); 00606 }
static int register_translator | ( | int | dst, | |
int | src | |||
) | [static] |
Definition at line 497 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().
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 #if 0 00515 zt->t.buffer_samples = 0; 00516 #endif 00517 } else { 00518 zt->t.framein = dahdi_decoder_framein; 00519 zt->t.frameout = dahdi_decoder_frameout; 00520 #if 0 00521 if (AST_FORMAT_G723_1 == zt->t.srcfmt) { 00522 zt->t.plc_samples = G723_SAMPLES; 00523 } else { 00524 zt->t.plc_samples = G729_SAMPLES; 00525 } 00526 zt->t.buffer_samples = zt->t.plc_samples * 8; 00527 #endif 00528 } 00529 zt->t.destroy = dahdi_destroy; 00530 zt->t.buffer_samples = 0; 00531 zt->t.newpvt = dahdi_new; 00532 zt->t.sample = fakesrc_sample; 00533 #if 0 00534 zt->t.useplc = global_useplc; 00535 #endif 00536 zt->t.useplc = 0; 00537 zt->t.native_plc = 0; 00538 00539 zt->t.desc_size = sizeof(struct codec_dahdi_pvt); 00540 if ((res = ast_register_translator(&zt->t))) { 00541 free(zt); 00542 return -1; 00543 } 00544 00545 AST_LIST_LOCK(&translators); 00546 AST_LIST_INSERT_HEAD(&translators, zt, entry); 00547 AST_LIST_UNLOCK(&translators); 00548 00549 global_format_map.map[dst][src] = 1; 00550 00551 return res; 00552 }
static int reload | ( | void | ) | [static] |
Definition at line 680 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.
00681 { 00682 struct translator *cur; 00683 00684 parse_config(); 00685 00686 AST_LIST_LOCK(&translators); 00687 AST_LIST_TRAVERSE(&translators, cur, entry) 00688 cur->t.useplc = global_useplc; 00689 AST_LIST_UNLOCK(&translators); 00690 00691 return 0; 00692 }
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 694 of file codec_dahdi.c.
References ast_cli_unregister_multiple(), cli, and unregister_translators().
00695 { 00696 ast_cli_unregister_multiple(cli, sizeof(cli) / sizeof(cli[0])); 00697 unregister_translators(); 00698 00699 return 0; 00700 }
static void unregister_translators | ( | void | ) | [static] |
Definition at line 576 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().
00577 { 00578 struct translator *cur; 00579 00580 AST_LIST_LOCK(&translators); 00581 while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) { 00582 ast_unregister_translator(&cur->t); 00583 free(cur); 00584 } 00585 AST_LIST_UNLOCK(&translators); 00586 }
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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 716 of file codec_dahdi.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 716 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.