Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:49:23 2009

## Asterisk developer's documentation

# translate.h File Reference

Translate via the use of pseudo channels. More...

`#include "asterisk/frame.h"`
`#include "asterisk/plc.h"`

Include dependency graph for translate.h:

Go to the source code of this file.

## Data Structures

struct | ast_translator

## Defines

#define | MAX_FORMAT 32

## Functions

int | ast_register_translator (struct ast_translator *t)
struct ast_frame * | ast_translate (struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
int | ast_translator_best_choice (int *dsts, int *srcs)
| Calculate our best translator source format, given costs, and a desired destination.
struct ast_trans_pvt * | ast_translator_build_path (int dest, int source)
void | ast_translator_free_path (struct ast_trans_pvt *tr)
int | ast_unregister_translator (struct ast_translator *t)
| unregister codec translator

## Detailed Description

Translate via the use of pseudo channels.

Definition in file translate.h.

## Define Documentation

#define MAX_FORMAT 32

Definition at line 26 of file translate.h.

Referenced by ast_register_translator(), ast_translator_best_choice(), and rebuild_matrix().

## Function Documentation

int ast_register_translator | ( | struct ast_translator * | t | ) |

Register a translator

Parameters:

  | t | populated ast_translator structure This registers a codec translator with asterisk Returns 0 on success, -1 on failure

Definition at line 396 of file translate.c.

References ast_cli_register(), ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), calc_cost(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::cost, ast_translator::dstfmt, LOG_WARNING, MAX_FORMAT, ast_translator::name, ast_translator::next, option_verbose, powerof(), rebuild_matrix(), ast_translator::srcfmt, term_color(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and register_translator().

    00397 {
    00398    char tmp[80];
    00399    t->srcfmt = powerof(t->srcfmt);
    00400    t->dstfmt = powerof(t->dstfmt);
    00401    if (t->srcfmt >= MAX_FORMAT) {
    00402       ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
    00403       return -1;
    00404    }
    00405    if (t->dstfmt >= MAX_FORMAT) {
    00406       ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt));
    00407       return -1;
    00408    }
    00409    calc_cost(t,1);
    00410    if (option_verbose > 1)
    00411       ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost);
    00412    ast_mutex_lock(&list_lock);
    00413    if (!added_cli) {
    00414       ast_cli_register(&show_trans);
    00415       added_cli++;
    00416    }
    00417    t->next = list;
    00418    list = t;
    00419    rebuild_matrix(0);
    00420    ast_mutex_unlock(&list_lock);
    00421    return 0;
    00422 }

struct ast_frame* ast_translate | ( | struct ast_trans_pvt * | tr,
|  | struct ast_frame * | f,
|  | int | consume |
| ) |  |  | `[read]`

translates one or more frames

Parameters:

  | tr | translator structure to use for translation
  | f | frame to translate
  | consume | Whether or not to free the original frame Apply an input frame into the translator and receive zero or one output frames. Consume determines whether the original frame should be freed Returns an ast_frame of the new translation format on success, NULL on failure

Definition at line 155 of file translate.c.

References AST_FRAME_CNG, ast_frfree(), ast_log(), ast_tvadd(), ast_tvsub(), ast_frame::delivery, ast_translator::framein, ast_frame::frametype, LOG_WARNING, ast_frame::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, ast_frame::samples, and ast_trans_pvt::step.

Referenced by ast_read(), ast_slinfactory_feed(), ast_write(), ast_writestream(), process_ast_dsp(), and queue_frame_to_spies().

    00156 {
    00157    struct ast_trans_pvt *p;
    00158    struct ast_frame *out;
    00159    struct timeval delivery;
    00160    p = path;
    00161    /* Feed the first frame into the first translator */
    00162    p->step->framein(p->state, f);
    00163    if (!ast_tvzero(f->delivery)) {
    00164       if (!ast_tvzero(path->nextin)) {
    00165          /* Make sure this is in line with what we were expecting */
    00166          if (!ast_tveq(path->nextin, f->delivery)) {
    00167             /* The time has changed between what we expected and this
    00168                most recent time on the new packet.  If we have a
    00169                valid prediction adjust our output time appropriately */
    00170             if (!ast_tvzero(path->nextout)) {
    00171                path->nextout = ast_tvadd(path->nextout,
    00172                           ast_tvsub(f->delivery, path->nextin));
    00173             }
    00174             path->nextin = f->delivery;
    00175          }
    00176       } else {
    00177          /* This is our first pass.  Make sure the timing looks good */
    00178          path->nextin = f->delivery;
    00179          path->nextout = f->delivery;
    00180       }
    00181       /* Predict next incoming sample */
    00182       path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000));
    00183    }
    00184    delivery = f->delivery;
    00185    if (consume)
    00186       ast_frfree(f);
    00187    while(p) {
    00188       out = p->step->frameout(p->state);
    00189       /* If we get nothing out, return NULL */
    00190       if (!out)
    00191          return NULL;
    00192       /* If there is a next state, feed it in there.  If not,
    00193          return this frame  */
    00194       if (p->next)
    00195          p->next->step->framein(p->next->state, out);
    00196       else {
    00197          if (!ast_tvzero(delivery)) {
    00198             /* Regenerate prediction after a discontinuity */
    00199             if (ast_tvzero(path->nextout))
    00200                path->nextout = ast_tvnow();
    00201
    00202             /* Use next predicted outgoing timestamp */
    00203             out->delivery = path->nextout;
    00204
    00205             /* Predict next outgoing timestamp from samples in this
    00206                frame. */
    00207             path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000));
    00208          } else {
    00209             out->delivery = ast_tv(0, 0);
    00210          }
    00211          /* Invalidate prediction if we're entering a silence period */
    00212          if (out->frametype == AST_FRAME_CNG)
    00213             path->nextout = ast_tv(0, 0);
    00214          return out;
    00215       }
    00216       p = p->next;
    00217    }
    00218    ast_log(LOG_WARNING, "I should never get here...\n");
    00219    return NULL;
    00220 }

int ast_translator_best_choice | ( | int * | dsts,
|  | int * | srcs |
| ) |  |  |

Calculate our best translator source format, given costs, and a desired destination.

Chooses the best translation path

Given a list of sources, and a designed destination format, which should I choose? Returns 0 on success, -1 if no path could be found. Modifies dests and srcs in place

Definition at line 450 of file translate.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_translator_dir::cost, ast_translator::cost, MAX_FORMAT, ast_translator_dir::multistep, and tr_matrix.

Referenced by ast_channel_make_compatible(), ast_request(), iax2_request(), and set_format().

    00451 {
    00452    int x,y;
    00453    int best = -1;
    00454    int bestdst = 0;
    00455    int cur = 1;
    00456    int besttime = INT_MAX;
    00457    int beststeps = INT_MAX;
    00458    int common;
    00459
    00460    if ((common = (*dst) & (*srcs))) {
    00461       /* We have a format in common */
    00462       for (y = 0; y < MAX_FORMAT; y++) {
    00463          if (cur & common) {
    00464             /* This is a common format to both.  Pick it if we don't have one already */
    00465             bestdst = cur;
    00466             best = cur;
    00467          }
    00468          cur = cur << 1;
    00469       }
    00470    } else {
    00471       /* We will need to translate */
    00472       ast_mutex_lock(&list_lock);
    00473       for (y = 0; y < MAX_FORMAT; y++) {
    00474          if (!(cur & *dst)) {
    00475             cur = cur << 1;
    00476             continue;
    00477          }
    00478
    00479          for (x = 0; x < MAX_FORMAT; x++) {
    00480             if ((*srcs & (1 << x)) &&        /* x is a valid source format */
    00481                 tr_matrix[x][y].step) {         /* There's a step */
    00482                if (tr_matrix[x][y].cost > besttime)
    00483                   continue;         /* It's more expensive, skip it */
    00484
    00485                if (tr_matrix[x][y].cost == besttime &&
    00486                    tr_matrix[x][y].multistep >= beststeps)
    00487                   continue;         /* It requires the same (or more) steps,
    00488                                  skip it */
    00489
    00490                /* It's better than what we have so far */
    00491                best = 1 << x;
    00492                bestdst = cur;
    00493                besttime = tr_matrix[x][y].cost;
    00494                beststeps = tr_matrix[x][y].multistep;
    00495             }
    00496          }
    00497          cur = cur << 1;
    00498       }
    00499       ast_mutex_unlock(&list_lock);
    00500    }
    00501
    00502    if (best > -1) {
    00503       *srcs = best;
    00504       *dst = bestdst;
    00505       best = 0;
    00506    }
    00507
    00508    return best;
    00509 }

struct ast_trans_pvt* ast_translator_build_path | ( | int | dest,
|  | int | source |
| ) |  |  | `[read]`

Builds a translator path

Parameters:

  | dest | destination format
  | source | source format Build a path (possibly NULL) from source to dest Returns ast_trans_pvt on success, NULL on failure

Build a set of translators based upon the given source and destination formats

Definition at line 106 of file translate.c.

References ast_getformatname(), ast_log(), ast_translator_free_path(), LOG_WARNING, malloc, ast_translator::newpvt, ast_trans_pvt::next, ast_trans_pvt::nextin, powerof(), ast_translator_dir::step, ast_trans_pvt::step, and tr_matrix.

Referenced by ast_slinfactory_feed(), ast_writestream(), misdn_set_opt_exec(), queue_frame_to_spies(), and set_format().

    00107 {
    00108    struct ast_trans_pvt *tmpr = NULL, *tmp = NULL;
    00109
    00110    source = powerof(source);
    00111    dest = powerof(dest);
    00112
    00113    while(source != dest) {
    00114       if (!tr_matrix[source][dest].step) {
    00115          /* We shouldn't have allocated any memory */
    00116          ast_log(LOG_WARNING, "No translator path from %s to %s\n",
    00117             ast_getformatname(source), ast_getformatname(dest));
    00118          return NULL;
    00119       }
    00120
    00121       if (tmp) {
    00122          tmp->next = malloc(sizeof(*tmp));
    00123          tmp = tmp->next;
    00124       } else
    00125          tmp = malloc(sizeof(*tmp));
    00126
    00127       if (!tmp) {
    00128          ast_log(LOG_WARNING, "Out of memory\n");
    00129          if (tmpr)
    00130             ast_translator_free_path(tmpr);
    00131          return NULL;
    00132       }
    00133
    00134       /* Set the root, if it doesn't exist yet... */
    00135       if (!tmpr)
    00136          tmpr = tmp;
    00137
    00138       tmp->next = NULL;
    00139       tmp->nextin = tmp->nextout = ast_tv(0, 0);
    00140       tmp->step = tr_matrix[source][dest].step;
    00141       tmp->state = tmp->step->newpvt();
    00142
    00143       if (!tmp->state) {
    00144          ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
    00145          ast_translator_free_path(tmpr);
    00146          return NULL;
    00147       }
    00148
    00149       /* Keep going if this isn't the final destination */
    00150       source = tmp->step->dstfmt;
    00151    }
    00152    return tmpr;
    00153 }

void ast_translator_free_path | ( | struct ast_trans_pvt * | tr | ) |

Frees a translator path

Parameters:

  | tr | translator path to get rid of Frees the given translator path structure

Definition at line 92 of file translate.c.

References ast_translator::destroy, free, ast_trans_pvt::next, ast_trans_pvt::state, and ast_trans_pvt::step.

Referenced by ast_channel_free(), ast_closestream(), ast_slinfactory_destroy(), ast_slinfactory_feed(), ast_translator_build_path(), ast_writestream(), cl_dequeue_chan(), free_translation(), pvt_destructor(), queue_frame_to_spies(), set_format(), and spy_cleanup().

    00093 {
    00094    struct ast_trans_pvt *pl, *pn;
    00095    pn = p;
    00096    while(pn) {
    00097       pl = pn;
    00098       pn = pn->next;
    00099       if (pl->state && pl->step->destroy)
    00100          pl->step->destroy(pl->state);
    00101       free(pl);
    00102    }
    00103 }

int ast_unregister_translator | ( | struct ast_translator * | t | ) |

unregister codec translator

Unregister a translator

Parameters:

  | t | translator to unregister Unregisters the given tranlator Returns 0 on success, -1 on failure

Definition at line 425 of file translate.c.

References ast_getformatname(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::dstfmt, ast_translator::name, ast_translator::next, option_verbose, rebuild_matrix(), ast_translator::srcfmt, term_color(), and VERBOSE_PREFIX_2.

Referenced by drop_translator(), load_module(), unload_module(), and unregister_translators().

    00426 {
    00427    char tmp[80];
    00428    struct ast_translator *u, *ul = NULL;
    00429    ast_mutex_lock(&list_lock);
    00430    u = list;
    00431    while(u) {
    00432       if (u == t) {
    00433          if (ul)
    00434             ul->next = u->next;
    00435          else
    00436             list = u->next;
    00437          if (option_verbose > 1)
    00438             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));
    00439          break;
    00440       }
    00441       ul = u;
    00442       u = u->next;
    00443    }
    00444    rebuild_matrix(0);
    00445    ast_mutex_unlock(&list_lock);
    00446    return (u ? 0 : -1);
    00447 }