#include "asterisk/frame.h"
#include "asterisk/plc.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) |
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. | |
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 |
Definition in file translate.h.
#define MAX_FORMAT 32 |
Definition at line 26 of file translate.h.
int ast_register_translator | ( | struct ast_translator * | t | ) |
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, list, LOG_WARNING, option_verbose, powerof(), rebuild_matrix(), show_trans, t, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module().
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 | |||
) |
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.
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_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 | |||
) |
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 | ) |
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(), iax2_destroy(), 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
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, list, ast_translator::next, ast_imager::next, option_verbose, rebuild_matrix(), t, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and unload_module().
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 }