add ExtenSpy variant of ChanSpy
[asterisk-bristuff.git] / translate.c
blob59d566db0e793ca46565b00b69c86ea4b193c96a
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
19 /*! \file
21 * \brief Translate via the use of pseudo channels
23 * \author Mark Spencer <markster@digium.com>
26 #define MOD_LOADER /* not really a module */
27 #include "asterisk.h"
29 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <sys/time.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
39 #include "asterisk/lock.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/logger.h"
42 #include "asterisk/translate.h"
43 #include "asterisk/module.h"
44 #include "asterisk/options.h"
45 #include "asterisk/frame.h"
46 #include "asterisk/sched.h"
47 #include "asterisk/cli.h"
48 #include "asterisk/term.h"
50 #define MAX_RECALC 200 /* max sample recalc */
52 /*! \brief the list of translators */
53 static AST_LIST_HEAD_STATIC(translators, ast_translator);
55 struct translator_path {
56 struct ast_translator *step; /*!< Next step translator */
57 unsigned int cost; /*!< Complete cost to destination */
58 unsigned int multistep; /*!< Multiple conversions required for this translation */
61 /*! \brief a matrix that, for any pair of supported formats,
62 * indicates the total cost of translation and the first step.
63 * The full path can be reconstricted iterating on the matrix
64 * until step->dstfmt == desired_format.
66 * Array indexes are 'src' and 'dest', in that order.
68 static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT];
70 /*! \todo
71 * TODO: sample frames for each supported input format.
72 * We build this on the fly, by taking an SLIN frame and using
73 * the existing converter to play with it.
76 /*! \brief returns the index of the lowest bit set */
77 static force_inline int powerof(unsigned int d)
79 int x = ffs(d);
81 if (x)
82 return x - 1;
84 ast_log(LOG_WARNING, "No bits set? %d\n", d);
86 return -1;
90 * wrappers around the translator routines.
93 /*!
94 * \brief Allocate the descriptor, required outbuf space,
95 * and possibly also plc and desc.
97 static void *newpvt(struct ast_translator *t)
99 struct ast_trans_pvt *pvt;
100 int len;
101 int useplc = t->plc_samples > 0 && t->useplc; /* cache, because it can change on the fly */
102 char *ofs;
103 struct module_symbols *ms = t->module;
106 * compute the required size adding private descriptor,
107 * plc, buffer, AST_FRIENDLY_OFFSET.
109 len = sizeof(*pvt) + t->desc_size;
110 if (useplc)
111 len += sizeof(plc_state_t);
112 if (t->buf_size)
113 len += AST_FRIENDLY_OFFSET + t->buf_size;
114 pvt = ast_calloc(1, len);
115 if (!pvt)
116 return NULL;
117 pvt->t = t;
118 ofs = (char *)(pvt + 1); /* pointer to data space */
119 if (t->desc_size) { /* first comes the descriptor */
120 pvt->pvt = ofs;
121 ofs += t->desc_size;
123 if (useplc) { /* then plc state */
124 pvt->plc = (plc_state_t *)ofs;
125 ofs += sizeof(plc_state_t);
127 if (t->buf_size) /* finally buffer and header */
128 pvt->outbuf = ofs + AST_FRIENDLY_OFFSET;
129 /* call local init routine, if present */
130 if (t->newpvt && t->newpvt(pvt)) {
131 free(pvt);
132 return NULL;
134 ast_atomic_fetchadd_int(&ms->usecnt, +1);
135 ast_update_use_count();
136 return pvt;
139 static void destroy(struct ast_trans_pvt *pvt)
141 struct ast_translator *t = pvt->t;
142 struct module_symbols *ms = t->module;
144 if (t->destroy)
145 t->destroy(pvt);
146 free(pvt);
147 ast_atomic_fetchadd_int(&ms->usecnt, -1);
148 ast_update_use_count();
151 /*! \brief framein wrapper, deals with plc and bound checks. */
152 static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
154 int16_t *dst = (int16_t *)pvt->outbuf;
155 int ret;
156 int samples = pvt->samples; /* initial value */
158 /* Copy the last in jb timing info to the pvt */
159 pvt->f.has_timing_info = f->has_timing_info;
160 pvt->f.ts = f->ts;
161 pvt->f.len = f->len;
162 pvt->f.seqno = f->seqno;
164 if (f->samples == 0) {
165 ast_log(LOG_WARNING, "no samples for %s\n", pvt->t->name);
167 if (pvt->t->buffer_samples) { /* do not pass empty frames to callback */
168 if (f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */
169 if (pvt->plc) {
170 int l = pvt->t->plc_samples;
171 if (pvt->samples + l > pvt->t->buffer_samples) {
172 ast_log(LOG_WARNING, "Out of buffer space\n");
173 return -1;
175 l = plc_fillin(pvt->plc, dst + pvt->samples, l);
176 pvt->samples += l;
178 return 0;
180 if (pvt->samples + f->samples > pvt->t->buffer_samples) {
181 ast_log(LOG_WARNING, "Out of buffer space\n");
182 return -1;
185 /* we require a framein routine, wouldn't know how to do
186 * it otherwise.
188 ret = pvt->t->framein(pvt, f);
189 /* possibly store data for plc */
190 if (!ret && pvt->plc) {
191 int l = pvt->t->plc_samples;
192 if (pvt->samples < l)
193 l = pvt->samples;
194 plc_rx(pvt->plc, dst + pvt->samples - l, l);
196 /* diagnostic ... */
197 if (pvt->samples == samples)
198 ast_log(LOG_WARNING, "%s did not update samples %d\n",
199 pvt->t->name, pvt->samples);
200 return ret;
203 /*! \brief generic frameout routine.
204 * If samples and datalen are 0, take whatever is in pvt
205 * and reset them, otherwise take the values in the caller and
206 * leave alone the pvt values.
208 struct ast_frame *ast_trans_frameout(struct ast_trans_pvt *pvt,
209 int datalen, int samples)
211 struct ast_frame *f = &pvt->f;
213 if (samples)
214 f->samples = samples;
215 else {
216 if (pvt->samples == 0)
217 return NULL;
218 f->samples = pvt->samples;
219 pvt->samples = 0;
221 if (datalen)
222 f->datalen = datalen;
223 else {
224 f->datalen = pvt->datalen;
225 pvt->datalen = 0;
228 f->frametype = AST_FRAME_VOICE;
229 f->subclass = 1 << (pvt->t->dstfmt);
230 f->mallocd = 0;
231 f->offset = AST_FRIENDLY_OFFSET;
232 f->src = pvt->t->name;
233 f->data = pvt->outbuf;
234 return f;
237 static struct ast_frame *default_frameout(struct ast_trans_pvt *pvt)
239 return ast_trans_frameout(pvt, 0, 0);
242 /* end of callback wrappers and helpers */
244 void ast_translator_free_path(struct ast_trans_pvt *p)
246 struct ast_trans_pvt *pn = p;
247 while ( (p = pn) ) {
248 pn = p->next;
249 destroy(p);
253 /*! \brief Build a chain of translators based upon the given source and dest formats */
254 struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
256 struct ast_trans_pvt *head = NULL, *tail = NULL;
258 source = powerof(source);
259 dest = powerof(dest);
261 while (source != dest) {
262 struct ast_trans_pvt *cur;
263 struct ast_translator *t = tr_matrix[source][dest].step;
264 if (!t) {
265 ast_log(LOG_WARNING, "No translator path from %s to %s\n",
266 ast_getformatname(source), ast_getformatname(dest));
267 return NULL;
269 if (!(cur = newpvt(t))) {
270 ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
271 if (head)
272 ast_translator_free_path(head);
273 return NULL;
275 if (!head)
276 head = cur;
277 else
278 tail->next = cur;
279 tail = cur;
280 cur->nextin = cur->nextout = ast_tv(0, 0);
281 /* Keep going if this isn't the final destination */
282 source = cur->t->dstfmt;
284 return head;
287 /*! \brief do the actual translation */
288 struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
290 struct ast_trans_pvt *p = path;
291 struct ast_frame *out = f;
292 struct timeval delivery;
293 int has_timing_info;
294 long ts;
295 long len;
296 int seqno;
298 has_timing_info = f->has_timing_info;
299 ts = f->ts;
300 len = f->len;
301 seqno = f->seqno;
303 /* XXX hmmm... check this below */
304 if (!ast_tvzero(f->delivery)) {
305 if (!ast_tvzero(path->nextin)) {
306 /* Make sure this is in line with what we were expecting */
307 if (!ast_tveq(path->nextin, f->delivery)) {
308 /* The time has changed between what we expected and this
309 most recent time on the new packet. If we have a
310 valid prediction adjust our output time appropriately */
311 if (!ast_tvzero(path->nextout)) {
312 path->nextout = ast_tvadd(path->nextout,
313 ast_tvsub(f->delivery, path->nextin));
315 path->nextin = f->delivery;
317 } else {
318 /* This is our first pass. Make sure the timing looks good */
319 path->nextin = f->delivery;
320 path->nextout = f->delivery;
322 /* Predict next incoming sample */
323 path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000));
325 delivery = f->delivery;
326 for ( ; out && p ; p = p->next) {
327 framein(p, out);
328 out = p->t->frameout(p);
330 if (consume)
331 ast_frfree(f);
332 if (out == NULL)
333 return NULL;
334 /* we have a frame, play with times */
335 if (!ast_tvzero(delivery)) {
336 /* Regenerate prediction after a discontinuity */
337 if (ast_tvzero(path->nextout))
338 path->nextout = ast_tvnow();
340 /* Use next predicted outgoing timestamp */
341 out->delivery = path->nextout;
343 /* Predict next outgoing timestamp from samples in this
344 frame. */
345 path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000));
346 } else {
347 out->delivery = ast_tv(0, 0);
348 out->has_timing_info = has_timing_info;
349 if (has_timing_info) {
350 out->ts = ts;
351 out->len = len;
352 out->seqno = seqno;
355 /* Invalidate prediction if we're entering a silence period */
356 if (out->frametype == AST_FRAME_CNG)
357 path->nextout = ast_tv(0, 0);
358 return out;
361 /*! \brief compute the cost of a single translation step */
362 static void calc_cost(struct ast_translator *t, int seconds)
364 int sofar=0;
365 struct ast_trans_pvt *pvt;
366 struct timeval start;
367 int cost;
369 if (!seconds)
370 seconds = 1;
372 /* If they don't make samples, give them a terrible score */
373 if (!t->sample) {
374 ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
375 t->cost = 99999;
376 return;
378 pvt = newpvt(t);
379 if (!pvt) {
380 ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
381 t->cost = 99999;
382 return;
384 start = ast_tvnow();
385 /* Call the encoder until we've processed the required number of samples */
386 while (sofar < seconds * 8000) {
387 struct ast_frame *f = t->sample();
388 if (!f) {
389 ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
390 destroy(pvt);
391 t->cost = 99999;
392 return;
394 framein(pvt, f);
395 ast_frfree(f);
396 while ((f = t->frameout(pvt))) {
397 sofar += f->samples;
398 ast_frfree(f);
401 cost = ast_tvdiff_ms(ast_tvnow(), start);
402 destroy(pvt);
403 t->cost = cost / seconds;
404 if (!t->cost)
405 t->cost = 1;
409 * \brief rebuild a translation matrix.
410 * \note This function expects the list of translators to be locked
412 static void rebuild_matrix(int samples)
414 struct ast_translator *t;
415 int x; /* source format index */
416 int y; /* intermediate format index */
417 int z; /* destination format index */
419 if (option_debug)
420 ast_log(LOG_DEBUG, "Resetting translation matrix\n");
422 bzero(tr_matrix, sizeof(tr_matrix));
424 /* first, compute all direct costs */
425 AST_LIST_TRAVERSE(&translators, t, list) {
426 x = t->srcfmt;
427 z = t->dstfmt;
429 if (samples)
430 calc_cost(t, samples);
432 if (!tr_matrix[x][z].step || t->cost < tr_matrix[x][z].cost) {
433 tr_matrix[x][z].step = t;
434 tr_matrix[x][z].cost = t->cost;
439 * For each triple x, y, z of distinct formats, check if there is
440 * a path from x to z through y which is cheaper than what is
441 * currently known, and in case, update the matrix.
442 * Repeat until the matrix is stable.
444 for (;;) {
445 int changed = 0;
446 for (x = 0; x < MAX_FORMAT; x++) { /* source format */
447 for (y=0; y < MAX_FORMAT; y++) { /* intermediate format */
448 if (x == y) /* skip ourselves */
449 continue;
451 for (z=0; z<MAX_FORMAT; z++) { /* dst format */
452 int newcost;
454 if (z == x || z == y) /* skip null conversions */
455 continue;
456 if (!tr_matrix[x][y].step) /* no path from x to y */
457 continue;
458 if (!tr_matrix[y][z].step) /* no path from y to z */
459 continue;
460 newcost = tr_matrix[x][y].cost + tr_matrix[y][z].cost;
461 if (tr_matrix[x][z].step && newcost >= tr_matrix[x][z].cost)
462 continue; /* x->y->z is more expensive than
463 * the existing path */
464 /* ok, we can get from x to z via y with a cost that
465 is the sum of the transition from x to y and
466 from y to z */
468 tr_matrix[x][z].step = tr_matrix[x][y].step;
469 tr_matrix[x][z].cost = newcost;
470 tr_matrix[x][z].multistep = 1;
471 if (option_debug)
472 ast_log(LOG_DEBUG, "Discovered %d cost path from %s to %s, via %d\n", tr_matrix[x][z].cost, ast_getformatname(x), ast_getformatname(z), y);
473 changed++;
477 if (!changed)
478 break;
482 /*! \brief CLI "show translation" command handler */
483 static int show_translation(int fd, int argc, char *argv[])
485 #define SHOW_TRANS 11
486 int x, y, z;
488 if (argc > 4)
489 return RESULT_SHOWUSAGE;
491 AST_LIST_LOCK(&translators);
493 if (argv[2] && !strcasecmp(argv[2], "recalc")) {
494 z = argv[3] ? atoi(argv[3]) : 1;
496 if (z <= 0) {
497 ast_cli(fd, " C'mon let's be serious here... defaulting to 1.\n");
498 z = 1;
501 if (z > MAX_RECALC) {
502 ast_cli(fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
503 z = MAX_RECALC;
505 ast_cli(fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
506 rebuild_matrix(z);
509 ast_cli(fd, " Translation times between formats (in milliseconds)\n");
510 ast_cli(fd, " Source Format (Rows) Destination Format(Columns)\n\n");
511 for (x = -1; x < SHOW_TRANS; x++) {
512 char line[80];
513 char *buf = line;
514 size_t left = sizeof(line) - 1; /* one initial space */
515 /* next 2 lines run faster than using ast_build_string() */
516 *buf++ = ' ';
517 *buf = '\0';
518 for (y = -1; y < SHOW_TRANS; y++) {
519 if (x >= 0 && y >= 0 && tr_matrix[x][y].step) /* XXX what is 99999 ? */
520 ast_build_string(&buf, &left, " %5d", tr_matrix[x][y].cost >= 99999 ? 0 : tr_matrix[x][y].cost);
521 else if (((x == -1 && y >= 0) || (y == -1 && x >= 0))) {
522 ast_build_string(&buf, &left, " %5s", ast_getformatname(1 << (x + y + 1)) );
523 } else if (x != -1 && y != -1) {
524 ast_build_string(&buf, &left, " -");
525 } else {
526 ast_build_string(&buf, &left, " ");
529 ast_build_string(&buf, &left, "\n");
530 ast_cli(fd, line);
532 AST_LIST_UNLOCK(&translators);
533 return RESULT_SUCCESS;
537 static char show_trans_usage[] =
538 "Usage: show translation [recalc] [<recalc seconds>]\n"
539 " Displays known codec translators and the cost associated\n"
540 "with each conversion. If the argument 'recalc' is supplied along\n"
541 "with optional number of seconds to test a new test will be performed\n"
542 "as the chart is being displayed.\n";
544 static struct ast_cli_entry show_trans =
545 { { "show", "translation", NULL }, show_translation, "Display translation matrix", show_trans_usage };
547 /*! \brief register codec translator */
548 int ast_register_translator(struct ast_translator *t, void *module)
550 static int added_cli = 0;
552 if (module == NULL) {
553 ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
554 return -1;
556 t->module = module;
557 if (t->buf_size == 0) {
558 ast_log(LOG_WARNING, "empty buf size, you need to supply one\n");
559 return -1;
561 if (t->plc_samples) {
562 if (t->buffer_samples < t->plc_samples) {
563 ast_log(LOG_WARNING, "plc_samples %d buffer_samples %d\n",
564 t->plc_samples, t->buffer_samples);
565 return -1;
567 if (t->dstfmt != AST_FORMAT_SLINEAR)
568 ast_log(LOG_WARNING, "plc_samples %d format %x\n",
569 t->plc_samples, t->dstfmt);
571 t->srcfmt = powerof(t->srcfmt);
572 t->dstfmt = powerof(t->dstfmt);
573 /* XXX maybe check that it is not existing yet ? */
574 if (t->srcfmt >= MAX_FORMAT) {
575 ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
576 return -1;
578 if (t->dstfmt >= MAX_FORMAT) {
579 ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt));
580 return -1;
582 if (t->buf_size) {
584 * Align buf_size properly, rounding up to the machine-specific
585 * alignment for pointers.
587 struct _test_align { void *a, *b; } p;
588 int align = (char *)&p.b - (char *)&p.a;
589 t->buf_size = ((t->buf_size + align - 1) / align) * align;
591 if (t->frameout == NULL)
592 t->frameout = default_frameout;
594 calc_cost(t, 1);
595 if (option_verbose > 1) {
596 char tmp[80];
597 ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n",
598 term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
599 ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost);
601 AST_LIST_LOCK(&translators);
602 if (!added_cli) {
603 ast_cli_register(&show_trans);
604 added_cli++;
606 AST_LIST_INSERT_HEAD(&translators, t, list);
607 rebuild_matrix(0);
608 AST_LIST_UNLOCK(&translators);
609 return 0;
612 /*! \brief unregister codec translator */
613 int ast_unregister_translator(struct ast_translator *t)
615 char tmp[80];
616 struct ast_translator *u;
617 AST_LIST_LOCK(&translators);
618 AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
619 if (u == t) {
620 AST_LIST_REMOVE_CURRENT(&translators, list);
621 if (option_verbose > 1)
622 ast_verbose(VERBOSE_PREFIX_2 "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt));
623 break;
626 AST_LIST_TRAVERSE_SAFE_END
627 rebuild_matrix(0);
628 AST_LIST_UNLOCK(&translators);
629 return (u ? 0 : -1);
632 /*! \brief Calculate our best translator source format, given costs, and a desired destination */
633 int ast_translator_best_choice(int *dst, int *srcs)
635 int x,y;
636 int best = -1;
637 int bestdst = 0;
638 int cur, cursrc;
639 int besttime = INT_MAX;
640 int beststeps = INT_MAX;
641 int common = (*dst) & (*srcs); /* are there common formats ? */
643 if (common) { /* yes, pick one and return */
644 for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) {
645 if (cur & common) /* guaranteed to find one */
646 break;
648 /* We are done, this is a common format to both. */
649 *srcs = *dst = cur;
650 return 0;
651 } else { /* No, we will need to translate */
652 AST_LIST_LOCK(&translators);
653 for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) {
654 if (! (cur & *dst))
655 continue;
656 for (cursrc = 1, x = 0; x < MAX_FORMAT; cursrc <<= 1, x++) {
657 if (!(*srcs & cursrc) || !tr_matrix[x][y].step ||
658 tr_matrix[x][y].cost > besttime)
659 continue; /* not existing or no better */
660 if (tr_matrix[x][y].cost < besttime ||
661 tr_matrix[x][y].multistep < beststeps) {
662 /* better than what we have so far */
663 best = cursrc;
664 bestdst = cur;
665 besttime = tr_matrix[x][y].cost;
666 beststeps = tr_matrix[x][y].multistep;
670 AST_LIST_UNLOCK(&translators);
671 if (best > -1) {
672 *srcs = best;
673 *dst = bestdst;
674 best = 0;
676 return best;
680 unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src)
682 /* convert bitwise format numbers into array indices */
683 src = powerof(src);
684 dest = powerof(dest);
685 if (!tr_matrix[src][dest].step)
686 return -1;
687 else
688 return tr_matrix[src][dest].multistep + 1;