#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. Referenced by ast_register_translator(), and ast_translator_best_choice(). |
|
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, MAX_FORMAT, 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_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, ast_translator_dir::cost, and MAX_FORMAT. 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_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, 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 }
|