#include <asterisk/frame.h>Go to the source code of this file.
Defines | |
| #define | MAX_FORMAT 32 |
Functions | |
| int | ast_register_translator (struct ast_translator *t) |
| Register a translator. | |
| int | ast_unregister_translator (struct ast_translator *t) |
| Unregister a translator. | |
| int | ast_translator_best_choice (int *dsts, int *srcs) |
| Chooses the best translation path. | |
| ast_trans_pvt * | ast_translator_build_path (int dest, int source) |
| Builds a translator path. | |
| void | ast_translator_free_path (struct ast_trans_pvt *tr) |
| Frees a translator path. | |
| ast_frame * | ast_translate (struct ast_trans_pvt *tr, struct ast_frame *f, int consume) |
| translates one or more frames | |
|
|
Definition at line 17 of file translate.h. |
|
|
Register a translator.
Definition at line 389 of file translate.c. References ast_cli_register(), ast_getformatname(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::cost, ast_translator::dstfmt, LOG_WARNING, ast_translator::name, ast_translator::next, option_verbose, ast_translator::srcfmt, term_color(), and VERBOSE_PREFIX_2. 00390 {
00391 char tmp[80];
00392 t->srcfmt = powerof(t->srcfmt);
00393 t->dstfmt = powerof(t->dstfmt);
00394 if ((t->srcfmt >= MAX_FORMAT) || (t->dstfmt >= MAX_FORMAT)) {
00395 ast_log(LOG_WARNING, "Format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
00396 return -1;
00397 }
00398 calc_cost(t,1);
00399 if (option_verbose > 1)
00400 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);
00401 ast_mutex_lock(&list_lock);
00402 if (!added_cli) {
00403 ast_cli_register(&show_trans);
00404 added_cli++;
00405 }
00406 t->next = list;
00407 list = t;
00408 rebuild_matrix(0);
00409 ast_mutex_unlock(&list_lock);
00410 return 0;
00411 }
|
|
||||||||||||||||
|
translates one or more frames
Definition at line 137 of file translate.c. References ast_frfree(), ast_log(), ast_frame::delivery, ast_translator::framein, 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_write(), and ast_writestream(). 00138 {
00139 struct ast_trans_pvt *p;
00140 struct ast_frame *out;
00141 struct timeval delivery;
00142 p = path;
00143 /* Feed the first frame into the first translator */
00144 p->step->framein(p->state, f);
00145 if (f->delivery.tv_sec || f->delivery.tv_usec) {
00146 if (path->nextin.tv_sec || path->nextin.tv_usec) {
00147 /* Make sure this is in line with what we were expecting */
00148 if ((path->nextin.tv_sec != f->delivery.tv_sec) ||
00149 (path->nextin.tv_usec != f->delivery.tv_usec)) {
00150 /* The time has changed between what we expected and this
00151 most recent time on the new packet. Adjust our output
00152 time appropriately */
00153 long sdiff;
00154 long udiff;
00155 sdiff = f->delivery.tv_sec - path->nextin.tv_sec;
00156 udiff = f->delivery.tv_usec - path->nextin.tv_usec;
00157 path->nextin.tv_sec = f->delivery.tv_sec;
00158 path->nextin.tv_usec = f->delivery.tv_usec;
00159 path->nextout.tv_sec += sdiff;
00160 path->nextout.tv_usec += udiff;
00161 if (path->nextout.tv_usec < 0) {
00162 path->nextout.tv_usec += 1000000;
00163 path->nextout.tv_sec--;
00164 } else if (path->nextout.tv_usec >= 1000000) {
00165 path->nextout.tv_usec -= 1000000;
00166 path->nextout.tv_sec++;
00167 }
00168 }
00169 } else {
00170 /* This is our first pass. Make sure the timing looks good */
00171 path->nextin.tv_sec = f->delivery.tv_sec;
00172 path->nextin.tv_usec = f->delivery.tv_usec;
00173 path->nextout.tv_sec = f->delivery.tv_sec;
00174 path->nextout.tv_usec = f->delivery.tv_usec;
00175 }
00176 /* Predict next incoming sample */
00177 path->nextin.tv_sec += (f->samples / 8000);
00178 path->nextin.tv_usec += ((f->samples % 8000) * 125);
00179 if (path->nextin.tv_usec >= 1000000) {
00180 path->nextin.tv_usec -= 1000000;
00181 path->nextin.tv_sec++;
00182 }
00183 }
00184 delivery.tv_sec = f->delivery.tv_sec;
00185 delivery.tv_usec = f->delivery.tv_usec;
00186 if (consume)
00187 ast_frfree(f);
00188 while(p) {
00189 out = p->step->frameout(p->state);
00190 /* If we get nothing out, return NULL */
00191 if (!out)
00192 return NULL;
00193 /* If there is a next state, feed it in there. If not,
00194 return this frame */
00195 if (p->next)
00196 p->next->step->framein(p->next->state, out);
00197 else {
00198 if (delivery.tv_sec || delivery.tv_usec) {
00199 /* Use next predicted outgoing timestamp */
00200 out->delivery.tv_sec = path->nextout.tv_sec;
00201 out->delivery.tv_usec = path->nextout.tv_usec;
00202
00203 /* Predict next outgoing timestamp from samples in this
00204 frame. */
00205 path->nextout.tv_sec += (out->samples / 8000);
00206 path->nextout.tv_usec += ((out->samples % 8000) * 125);
00207 if (path->nextout.tv_usec >= 1000000) {
00208 path->nextout.tv_sec++;
00209 path->nextout.tv_usec -= 1000000;
00210 }
00211 } else {
00212 out->delivery.tv_sec = 0;
00213 out->delivery.tv_usec = 0;
00214 }
00215 return out;
00216 }
00217 p = p->next;
00218 }
00219 ast_log(LOG_WARNING, "I should never get here...\n");
00220 return NULL;
00221 }
|
|
||||||||||||
|
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 437 of file translate.c. References ast_mutex_lock, ast_mutex_unlock, and ast_translator_dir::cost. Referenced by ast_channel_make_compatible(), ast_request(), ast_set_read_format(), and ast_set_write_format(). 00438 {
00439 /* Calculate our best source format, given costs, and a desired destination */
00440 int x,y;
00441 int best=-1;
00442 int bestdst=0;
00443 int cur = 1;
00444 int besttime=999999999;
00445 ast_mutex_lock(&list_lock);
00446 for (y=0;y<MAX_FORMAT;y++) {
00447 if ((cur & *dst) && (cur & *srcs)) {
00448 /* This is a common format to both. Pick it if we don't have one already */
00449 besttime=0;
00450 bestdst = cur;
00451 best = cur;
00452 break;
00453 }
00454 if (cur & *dst)
00455 for (x=0;x<MAX_FORMAT;x++) {
00456 if (tr_matrix[x][y].step && /* There's a step */
00457 (tr_matrix[x][y].cost < besttime) && /* We're better than what exists now */
00458 (*srcs & (1 << x))) /* x is a valid source format */
00459 {
00460 best = 1 << x;
00461 bestdst = cur;
00462 besttime = tr_matrix[x][y].cost;
00463 }
00464 }
00465 cur = cur << 1;
00466 }
00467 if (best > -1) {
00468 *srcs = best;
00469 *dst = bestdst;
00470 best = 0;
00471 }
00472 ast_mutex_unlock(&list_lock);
00473 return best;
00474 }
|
|
||||||||||||
|
Builds a translator path.
Definition at line 87 of file translate.c. References ast_getformatname(), ast_log(), ast_translator::dstfmt, free, LOG_WARNING, malloc, ast_translator::newpvt, ast_translator_dir::step, and ast_trans_pvt::step. Referenced by ast_set_read_format(), ast_set_write_format(), and ast_writestream(). 00088 {
00089 struct ast_trans_pvt *tmpr = NULL, *tmp = NULL;
00090 /* One of the hardest parts: Build a set of translators based upon
00091 the given source and destination formats */
00092 source = powerof(source);
00093 dest = powerof(dest);
00094 while(source != dest) {
00095 if (tr_matrix[source][dest].step) {
00096 if (tmp) {
00097 tmp->next = malloc(sizeof(struct ast_trans_pvt));
00098 tmp = tmp->next;
00099 } else
00100 tmp = malloc(sizeof(struct ast_trans_pvt));
00101
00102
00103 if (tmp) {
00104 tmp->next = NULL;
00105 tmp->nextin.tv_sec = 0;
00106 tmp->nextin.tv_usec = 0;
00107 tmp->nextout.tv_sec = 0;
00108 tmp->nextout.tv_usec = 0;
00109 tmp->step = tr_matrix[source][dest].step;
00110 tmp->state = tmp->step->newpvt();
00111 if (!tmp->state) {
00112 ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
00113 free(tmp);
00114 tmp = NULL;
00115 return NULL;
00116 }
00117 /* Set the root, if it doesn't exist yet... */
00118 if (!tmpr)
00119 tmpr = tmp;
00120 /* Keep going if this isn't the final destination */
00121 source = tmp->step->dstfmt;
00122 } else {
00123 /* XXX This could leak XXX */
00124 ast_log(LOG_WARNING, "Out of memory\n");
00125 return NULL;
00126 }
00127 } else {
00128 /* We shouldn't have allocated any memory */
00129 ast_log(LOG_WARNING, "No translator path from %s to %s\n",
00130 ast_getformatname(source), ast_getformatname(dest));
00131 return NULL;
00132 }
00133 }
00134 return tmpr;
00135 }
|
|
|
Frees a translator path.
Definition at line 74 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_set_read_format(), ast_set_write_format(), and ast_writestream(). 00075 {
00076 struct ast_trans_pvt *pl, *pn;
00077 pn = p;
00078 while(pn) {
00079 pl = pn;
00080 pn = pn->next;
00081 if (pl->state && pl->step->destroy)
00082 pl->step->destroy(pl->state);
00083 free(pl);
00084 }
00085 }
|
|
|
Unregister a translator.
Definition at line 413 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, ast_translator::srcfmt, term_color(), and VERBOSE_PREFIX_2. 00414 {
00415 char tmp[80];
00416 struct ast_translator *u, *ul = NULL;
00417 ast_mutex_lock(&list_lock);
00418 u = list;
00419 while(u) {
00420 if (u == t) {
00421 if (ul)
00422 ul->next = u->next;
00423 else
00424 list = u->next;
00425 if (option_verbose > 1)
00426 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));
00427 break;
00428 }
00429 ul = u;
00430 u = u->next;
00431 }
00432 rebuild_matrix(0);
00433 ast_mutex_unlock(&list_lock);
00434 return (u ? 0 : -1);
00435 }
|
1.4.2