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


Go to the source code of this file.
Data Structures | |
| struct | ast_trans_pvt |
| Default structure for translators, with the basic fields and buffers, all allocated as part of the same chunk of memory. The buffer is preceded by AST_FRIENDLY_OFFSET bytes in front of the user portion. 'buf' points right after this space. More... | |
| struct | ast_translator |
| Descriptor of a translator. More... | |
Defines | |
| #define | ast_register_translator(t) __ast_register_translator(t, ast_module_info->self) |
| See __ast_register_translator(). | |
Enumerations | |
| enum | ast_trans_cost_table { AST_TRANS_COST_LL_LL_ORIGSAMP = 400000, AST_TRANS_COST_LL_LY_ORIGSAMP = 600000, AST_TRANS_COST_LL_LL_UPSAMP = 800000, AST_TRANS_COST_LL_LY_UPSAMP = 825000, AST_TRANS_COST_LL_LL_DOWNSAMP = 850000, AST_TRANS_COST_LL_LY_DOWNSAMP = 875000, AST_TRANS_COST_LL_UNKNOWN = 885000, AST_TRANS_COST_LY_LL_ORIGSAMP = 900000, AST_TRANS_COST_LY_LY_ORIGSAMP = 915000, AST_TRANS_COST_LY_LL_UPSAMP = 930000, AST_TRANS_COST_LY_LY_UPSAMP = 945000, AST_TRANS_COST_LY_LL_DOWNSAMP = 960000, AST_TRANS_COST_LY_LY_DOWNSAMP = 975000, AST_TRANS_COST_LY_UNKNOWN = 985000 } |
| Translator Cost Table definition. More... | |
Functions | |
| int | __ast_register_translator (struct ast_translator *t, struct ast_module *module) |
| Register a translator This registers a codec translator with asterisk. | |
| struct ast_frame * | ast_trans_frameout (struct ast_trans_pvt *pvt, int datalen, int samples) |
| generic frameout function | |
| struct ast_frame * | ast_translate (struct ast_trans_pvt *tr, struct ast_frame *f, int consume) |
| translates one or more frames Apply an input frame into the translator and receive zero or one output frames. Consume determines whether the original frame should be freed | |
| void | ast_translate_available_formats (struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result) |
| Find available formats. | |
| int | ast_translate_init (void) |
| Initialize the translation matrix and index to format conversion table. | |
| unsigned int | ast_translate_path_steps (struct ast_format *dest, struct ast_format *src) |
| Returns the number of steps required to convert from 'src' to 'dest'. | |
| const char * | ast_translate_path_to_str (struct ast_trans_pvt *t, struct ast_str **str) |
| Puts a string representation of the translation path into outbuf. | |
| void | ast_translator_activate (struct ast_translator *t) |
| Activate a previously deactivated translator. | |
| int | ast_translator_best_choice (struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, struct ast_format *dst_fmt_out, struct ast_format *src_fmt_out) |
| Chooses the best translation path. | |
| struct ast_trans_pvt * | ast_translator_build_path (struct ast_format *dest, struct ast_format *source) |
| Builds a translator path Build a path (possibly NULL) from source to dest. | |
| void | ast_translator_deactivate (struct ast_translator *t) |
| Deactivate a translator. | |
| void | ast_translator_free_path (struct ast_trans_pvt *tr) |
| Frees a translator path Frees the given translator path structure. | |
| int | ast_unregister_translator (struct ast_translator *t) |
| Unregister a translator Unregisters the given tranlator. | |
Definition in file translate.h.
| #define ast_register_translator | ( | t | ) | __ast_register_translator(t, ast_module_info->self) |
See __ast_register_translator().
Definition at line 245 of file translate.h.
Referenced by load_module(), and register_translator().
| enum ast_trans_cost_table |
Translator Cost Table definition.
The cost value of the first two values must always add up to be greater than the largest value defined in this table. This is done to guarantee a direct translation will always have precedence over a multi step translation.
Definition at line 59 of file translate.h.
00059 { 00060 00061 /* Lossless Source Translation Costs */ 00062 00063 /*! [lossless -> lossless] original sampling */ 00064 AST_TRANS_COST_LL_LL_ORIGSAMP = 400000, 00065 /*! [lossless -> lossy] original sampling */ 00066 AST_TRANS_COST_LL_LY_ORIGSAMP = 600000, 00067 00068 /*! [lossless -> lossless] up sample */ 00069 AST_TRANS_COST_LL_LL_UPSAMP = 800000, 00070 /*! [lossless -> lossy] up sample */ 00071 AST_TRANS_COST_LL_LY_UPSAMP = 825000, 00072 00073 /*! [lossless -> lossless] down sample */ 00074 AST_TRANS_COST_LL_LL_DOWNSAMP = 850000, 00075 /*! [lossless -> lossy] down sample */ 00076 AST_TRANS_COST_LL_LY_DOWNSAMP = 875000, 00077 00078 /*! [lossless -> unknown] unknown. 00079 * This value is for a lossless source translation 00080 * with an unknown destination and or sample rate conversion. */ 00081 AST_TRANS_COST_LL_UNKNOWN = 885000, 00082 00083 /* Lossy Source Translation Costs */ 00084 00085 /*! [lossy -> lossless] original sampling */ 00086 AST_TRANS_COST_LY_LL_ORIGSAMP = 900000, 00087 /*! [lossy -> lossy] original sampling */ 00088 AST_TRANS_COST_LY_LY_ORIGSAMP = 915000, 00089 00090 /*! [lossy -> lossless] up sample */ 00091 AST_TRANS_COST_LY_LL_UPSAMP = 930000, 00092 /*! [lossy -> lossy] up sample */ 00093 AST_TRANS_COST_LY_LY_UPSAMP = 945000, 00094 00095 /*! [lossy -> lossless] down sample */ 00096 AST_TRANS_COST_LY_LL_DOWNSAMP = 960000, 00097 /*! [lossy -> lossy] down sample */ 00098 AST_TRANS_COST_LY_LY_DOWNSAMP = 975000, 00099 00100 /*! [lossy -> unknown] unknown. 00101 * This value is for a lossy source translation 00102 * with an unknown destination and or sample rate conversion. */ 00103 AST_TRANS_COST_LY_UNKNOWN = 985000, 00104 00105 };
| int __ast_register_translator | ( | struct ast_translator * | t, | |
| struct ast_module * | mod | |||
| ) |
Register a translator This registers a codec translator with asterisk.
| t | populated ast_translator structure | |
| module | handle to the module that owns this translator |
Definition at line 1040 of file translate.c.
References ast_translator::active, add_format2index(), ast_getformatname(), ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_translator::buf_size, COLOR_BLACK, COLOR_MAGENTA, ast_translator::comp_cost, default_frameout(), ast_translator::dst_fmt_index, ast_translator::dst_format, format2index(), ast_translator::frameout, generate_computational_cost(), generate_table_cost(), ast_format::id, LOG_WARNING, matrix_rebuild(), matrix_resize(), ast_translator::module, ast_translator::name, ast_translator::src_fmt_index, ast_translator::src_format, ast_translator::table_cost, and term_color().
01041 { 01042 struct ast_translator *u; 01043 char tmp[80]; 01044 01045 if (add_format2index(t->src_format.id) || add_format2index(t->dst_format.id)) { 01046 if (matrix_resize(0)) { 01047 ast_log(LOG_WARNING, "Translator matrix can not represent any more translators. Out of resources.\n"); 01048 return -1; 01049 } 01050 add_format2index(t->src_format.id); 01051 add_format2index(t->dst_format.id); 01052 } 01053 01054 if (!mod) { 01055 ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n"); 01056 return -1; 01057 } 01058 01059 if (!t->buf_size) { 01060 ast_log(LOG_WARNING, "empty buf size, you need to supply one\n"); 01061 return -1; 01062 } 01063 if (!t->table_cost && !(t->table_cost = generate_table_cost(&t->src_format, &t->dst_format))) { 01064 ast_log(LOG_WARNING, "Table cost could not be generated for %s, " 01065 "Please set table_cost variable on translator.\n", t->name); 01066 return -1; 01067 } 01068 01069 t->module = mod; 01070 t->src_fmt_index = format2index(t->src_format.id); 01071 t->dst_fmt_index = format2index(t->dst_format.id); 01072 t->active = 1; 01073 01074 if (t->src_fmt_index == -1 || t->dst_fmt_index == -1) { 01075 ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->src_fmt_index == -1 ? "starting" : "ending"); 01076 return -1; 01077 } 01078 if (t->src_fmt_index >= cur_max_index) { 01079 ast_log(LOG_WARNING, "Source format %s is larger than cur_max_index\n", ast_getformatname(&t->src_format)); 01080 return -1; 01081 } 01082 01083 if (t->dst_fmt_index >= cur_max_index) { 01084 ast_log(LOG_WARNING, "Destination format %s is larger than cur_max_index\n", ast_getformatname(&t->dst_format)); 01085 return -1; 01086 } 01087 01088 if (t->buf_size) { 01089 /* 01090 * Align buf_size properly, rounding up to the machine-specific 01091 * alignment for pointers. 01092 */ 01093 struct _test_align { void *a, *b; } p; 01094 int align = (char *)&p.b - (char *)&p.a; 01095 01096 t->buf_size = ((t->buf_size + align - 1) / align) * align; 01097 } 01098 01099 if (t->frameout == NULL) { 01100 t->frameout = default_frameout; 01101 } 01102 01103 generate_computational_cost(t, 1); 01104 01105 ast_verb(2, "Registered translator '%s' from format %s to %s, table cost, %d, computational cost %d\n", 01106 term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), 01107 ast_getformatname(&t->src_format), ast_getformatname(&t->dst_format), t->table_cost, t->comp_cost); 01108 01109 AST_RWLIST_WRLOCK(&translators); 01110 01111 /* find any existing translators that provide this same srcfmt/dstfmt, 01112 and put this one in order based on computational cost */ 01113 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 01114 if ((u->src_fmt_index == t->src_fmt_index) && 01115 (u->dst_fmt_index == t->dst_fmt_index) && 01116 (u->comp_cost > t->comp_cost)) { 01117 AST_RWLIST_INSERT_BEFORE_CURRENT(t, list); 01118 t = NULL; 01119 break; 01120 } 01121 } 01122 AST_RWLIST_TRAVERSE_SAFE_END; 01123 01124 /* if no existing translator was found for this format combination, 01125 add it to the beginning of the list */ 01126 if (t) { 01127 AST_RWLIST_INSERT_HEAD(&translators, t, list); 01128 } 01129 01130 matrix_rebuild(0); 01131 01132 AST_RWLIST_UNLOCK(&translators); 01133 01134 return 0; 01135 }
| struct ast_frame* ast_trans_frameout | ( | struct ast_trans_pvt * | pvt, | |
| int | datalen, | |||
| int | samples | |||
| ) | [read] |
generic frameout function
Definition at line 368 of file translate.c.
References ast_format_copy(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_trans_pvt::c, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dst_format, ast_trans_pvt::f, f, ast_frame_subclass::format, ast_frame::frametype, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::samples, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_trans_pvt::t.
Referenced by default_frameout(), lintoadpcm_frameout(), lintogsm_frameout(), lintoilbc_frameout(), lintolpc10_frameout(), and lintospeex_frameout().
00370 { 00371 struct ast_frame *f = &pvt->f; 00372 00373 if (samples) { 00374 f->samples = samples; 00375 } else { 00376 if (pvt->samples == 0) 00377 return NULL; 00378 f->samples = pvt->samples; 00379 pvt->samples = 0; 00380 } 00381 if (datalen) { 00382 f->datalen = datalen; 00383 } else { 00384 f->datalen = pvt->datalen; 00385 pvt->datalen = 0; 00386 } 00387 00388 f->frametype = AST_FRAME_VOICE; 00389 ast_format_copy(&f->subclass.format, &pvt->t->dst_format); 00390 f->mallocd = 0; 00391 f->offset = AST_FRIENDLY_OFFSET; 00392 f->src = pvt->t->name; 00393 f->data.ptr = pvt->outbuf.c; 00394 00395 return ast_frisolate(f); 00396 }
| struct ast_frame* ast_translate | ( | struct ast_trans_pvt * | path, | |
| struct ast_frame * | f, | |||
| int | consume | |||
| ) | [read] |
translates one or more frames Apply an input frame into the translator and receive zero or one output frames. Consume determines whether the original frame should be freed
| tr | translator structure to use for translation | |
| f | frame to translate | |
| consume | Whether or not to free the original frame |
Definition at line 476 of file translate.c.
References ast_format_rate(), AST_FRAME_CNG, AST_FRFLAG_HAS_TIMING_INFO, ast_frfree, ast_samp2tv(), ast_set2_flag, ast_test_flag, ast_tv(), ast_tvadd(), ast_tveq(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_frame::delivery, ast_frame_subclass::format, framein(), ast_frame::frametype, ast_frame::len, len(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, ast_frame::samples, ast_frame::seqno, ast_frame::subclass, and ast_frame::ts.
Referenced by __ast_read(), ast_slinfactory_feed(), ast_write(), ast_writestream(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), audiohook_read_frame_helper(), conf_run(), fax_gateway_framehook(), and softmix_process_write_audio().
00477 { 00478 struct ast_trans_pvt *p = path; 00479 struct ast_frame *out; 00480 struct timeval delivery; 00481 int has_timing_info; 00482 long ts; 00483 long len; 00484 int seqno; 00485 00486 has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO); 00487 ts = f->ts; 00488 len = f->len; 00489 seqno = f->seqno; 00490 00491 if (!ast_tvzero(f->delivery)) { 00492 if (!ast_tvzero(path->nextin)) { 00493 /* Make sure this is in line with what we were expecting */ 00494 if (!ast_tveq(path->nextin, f->delivery)) { 00495 /* The time has changed between what we expected and this 00496 most recent time on the new packet. If we have a 00497 valid prediction adjust our output time appropriately */ 00498 if (!ast_tvzero(path->nextout)) { 00499 path->nextout = ast_tvadd(path->nextout, 00500 ast_tvsub(f->delivery, path->nextin)); 00501 } 00502 path->nextin = f->delivery; 00503 } 00504 } else { 00505 /* This is our first pass. Make sure the timing looks good */ 00506 path->nextin = f->delivery; 00507 path->nextout = f->delivery; 00508 } 00509 /* Predict next incoming sample */ 00510 path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, ast_format_rate(&f->subclass.format))); 00511 } 00512 delivery = f->delivery; 00513 for (out = f; out && p ; p = p->next) { 00514 framein(p, out); 00515 if (out != f) { 00516 ast_frfree(out); 00517 } 00518 out = p->t->frameout(p); 00519 } 00520 if (consume) { 00521 ast_frfree(f); 00522 } 00523 if (out == NULL) { 00524 return NULL; 00525 } 00526 /* we have a frame, play with times */ 00527 if (!ast_tvzero(delivery)) { 00528 /* Regenerate prediction after a discontinuity */ 00529 if (ast_tvzero(path->nextout)) { 00530 path->nextout = ast_tvnow(); 00531 } 00532 00533 /* Use next predicted outgoing timestamp */ 00534 out->delivery = path->nextout; 00535 00536 /* Predict next outgoing timestamp from samples in this 00537 frame. */ 00538 path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format))); 00539 } else { 00540 out->delivery = ast_tv(0, 0); 00541 ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO); 00542 if (has_timing_info) { 00543 out->ts = ts; 00544 out->len = len; 00545 out->seqno = seqno; 00546 } 00547 } 00548 /* Invalidate prediction if we're entering a silence period */ 00549 if (out->frametype == AST_FRAME_CNG) { 00550 path->nextout = ast_tv(0, 0); 00551 } 00552 return out; 00553 }
| void ast_translate_available_formats | ( | struct ast_format_cap * | dest, | |
| struct ast_format_cap * | src, | |||
| struct ast_format_cap * | result | |||
| ) |
Find available formats.
| dest | possible destination formats | |
| src | source formats | |
| result | capabilities structure to store available formats in |
Definition at line 1282 of file translate.c.
References ast_format_cap_copy(), ast_format_cap_iscompatible(), ast_format_cap_iter_end(), ast_format_cap_iter_next(), ast_format_cap_iter_start(), ast_format_cap_remove_byid(), AST_FORMAT_GET_TYPE, ast_format_set(), AST_FORMAT_TYPE_AUDIO, AST_FORMAT_TYPE_VIDEO, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, format2index(), ast_format::id, index2format(), and matrix_get().
Referenced by ast_rtp_instance_available_formats().
01283 { 01284 struct ast_format tmp_fmt; 01285 struct ast_format cur_src; 01286 int src_audio = 0; 01287 int src_video = 0; 01288 int index; 01289 01290 ast_format_cap_copy(result, dest); 01291 01292 /* if we don't have a source format, we just have to try all 01293 possible destination formats */ 01294 if (!src) { 01295 return; 01296 } 01297 01298 ast_format_cap_iter_start(src); 01299 while (!ast_format_cap_iter_next(src, &cur_src)) { 01300 /* If we have a source audio format, get its format index */ 01301 if (AST_FORMAT_GET_TYPE(cur_src.id) == AST_FORMAT_TYPE_AUDIO) { 01302 src_audio = format2index(cur_src.id); 01303 } 01304 01305 /* If we have a source video format, get its format index */ 01306 if (AST_FORMAT_GET_TYPE(cur_src.id) == AST_FORMAT_TYPE_VIDEO) { 01307 src_video = format2index(cur_src.id); 01308 } 01309 01310 AST_RWLIST_RDLOCK(&translators); 01311 01312 /* For a given source audio format, traverse the list of 01313 known audio formats to determine whether there exists 01314 a translation path from the source format to the 01315 destination format. */ 01316 for (index = 0; (src_audio >= 0) && index < cur_max_index; index++) { 01317 ast_format_set(&tmp_fmt, index2format(index), 0); 01318 01319 if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO) { 01320 continue; 01321 } 01322 01323 /* if this is not a desired format, nothing to do */ 01324 if (!ast_format_cap_iscompatible(dest, &tmp_fmt)) { 01325 continue; 01326 } 01327 01328 /* if the source is supplying this format, then 01329 we can leave it in the result */ 01330 if (ast_format_cap_iscompatible(src, &tmp_fmt)) { 01331 continue; 01332 } 01333 01334 /* if we don't have a translation path from the src 01335 to this format, remove it from the result */ 01336 if (!matrix_get(src_audio, index)->step) { 01337 ast_format_cap_remove_byid(result, tmp_fmt.id); 01338 continue; 01339 } 01340 01341 /* now check the opposite direction */ 01342 if (!matrix_get(index, src_audio)->step) { 01343 ast_format_cap_remove_byid(result, tmp_fmt.id); 01344 } 01345 } 01346 01347 /* For a given source video format, traverse the list of 01348 known video formats to determine whether there exists 01349 a translation path from the source format to the 01350 destination format. */ 01351 for (index = 0; (src_video >= 0) && index < cur_max_index; index++) { 01352 ast_format_set(&tmp_fmt, index2format(index), 0); 01353 if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_VIDEO) { 01354 continue; 01355 } 01356 01357 /* if this is not a desired format, nothing to do */ 01358 if (!ast_format_cap_iscompatible(dest, &tmp_fmt)) { 01359 continue; 01360 } 01361 01362 /* if the source is supplying this format, then 01363 we can leave it in the result */ 01364 if (ast_format_cap_iscompatible(src, &tmp_fmt)) { 01365 continue; 01366 } 01367 01368 /* if we don't have a translation path from the src 01369 to this format, remove it from the result */ 01370 if (!matrix_get(src_video, index)->step) { 01371 ast_format_cap_remove_byid(result, tmp_fmt.id); 01372 continue; 01373 } 01374 01375 /* now check the opposite direction */ 01376 if (!matrix_get(index, src_video)->step) { 01377 ast_format_cap_remove_byid(result, tmp_fmt.id); 01378 } 01379 } 01380 AST_RWLIST_UNLOCK(&translators); 01381 } 01382 ast_format_cap_iter_end(src); 01383 }
| int ast_translate_init | ( | void | ) |
Initialize the translation matrix and index to format conversion table.
| 0 | on success | |
| -1 | on failure |
Definition at line 1385 of file translate.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_rwlock_init, and matrix_resize().
Referenced by main().
01386 { 01387 int res = 0; 01388 ast_rwlock_init(&tablelock); 01389 res = matrix_resize(1); 01390 res |= ast_cli_register_multiple(cli_translate, ARRAY_LEN(cli_translate)); 01391 return res; 01392 }
| unsigned int ast_translate_path_steps | ( | struct ast_format * | dest, | |
| struct ast_format * | src | |||
| ) |
Returns the number of steps required to convert from 'src' to 'dest'.
| dest | destination format | |
| src | source format |
Definition at line 1259 of file translate.c.
References ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, format2index(), ast_format::id, LOG_WARNING, matrix_get(), and translator_path::multistep.
Referenced by ast_channel_make_compatible_helper().
01260 { 01261 unsigned int res = -1; 01262 int src, dest; 01263 /* convert bitwise format numbers into array indices */ 01264 src = format2index(src_format->id); 01265 dest = format2index(dst_format->id); 01266 01267 if (src == -1 || dest == -1) { 01268 ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src == -1 ? "starting" : "ending"); 01269 return -1; 01270 } 01271 AST_RWLIST_RDLOCK(&translators); 01272 01273 if (matrix_get(src, dest)->step) { 01274 res = matrix_get(src, dest)->multistep + 1; 01275 } 01276 01277 AST_RWLIST_UNLOCK(&translators); 01278 01279 return res; 01280 }
| const char* ast_translate_path_to_str | ( | struct ast_trans_pvt * | t, | |
| struct ast_str ** | str | |||
| ) |
Puts a string representation of the translation path into outbuf.
| translator | structure containing the translation path | |
| ast_str | output buffer |
| on | success pointer to beginning of outbuf. on failure "". |
Definition at line 784 of file translate.c.
References ast_getformatname_multiple_byid(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_translator::dst_format, ast_format::id, ast_trans_pvt::next, ast_translator::src_format, and ast_trans_pvt::t.
Referenced by handle_showchan(), and serialize_showchan().
00785 { 00786 struct ast_trans_pvt *pn = p; 00787 char tmp[256]; 00788 00789 if (!p || !p->t) { 00790 return ""; 00791 } 00792 00793 ast_str_set(str, 0, "%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), p->t->src_format.id)); 00794 00795 while ( (p = pn) ) { 00796 pn = p->next; 00797 ast_str_append(str, 0, "->%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), p->t->dst_format.id)); 00798 } 00799 00800 return ast_str_buffer(*str); 00801 }
| void ast_translator_activate | ( | struct ast_translator * | t | ) |
Activate a previously deactivated translator.
| t | translator to activate |
Definition at line 1167 of file translate.c.
References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and matrix_rebuild().
01168 { 01169 AST_RWLIST_WRLOCK(&translators); 01170 t->active = 1; 01171 matrix_rebuild(0); 01172 AST_RWLIST_UNLOCK(&translators); 01173 }
| int ast_translator_best_choice | ( | struct ast_format_cap * | dst_cap, | |
| struct ast_format_cap * | src_cap, | |||
| struct ast_format * | dst_fmt_out, | |||
| struct ast_format * | src_fmt_out | |||
| ) |
Chooses the best translation path.
Given a list of sources, and a designed destination format, which should I choose?
| destination | capabilities | |
| source | capabilities | |
| destination | format chosen out of destination capabilities | |
| source | format chosen out of source capabilities |
Definition at line 1184 of file translate.c.
References ast_format_cap_destroy(), ast_format_cap_iter_end(), ast_format_cap_iter_next(), ast_format_cap_iter_start(), ast_format_cap_joint(), ast_format_clear(), ast_format_copy(), ast_format_rate(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, format2index(), ast_format::id, matrix_get(), translator_path::multistep, and translator_path::table_cost.
Referenced by ast_channel_make_compatible_helper(), ast_request(), iax2_request(), and set_format().
01188 { 01189 unsigned int besttablecost = INT_MAX; 01190 unsigned int beststeps = INT_MAX; 01191 struct ast_format best; 01192 struct ast_format bestdst; 01193 struct ast_format_cap *joint_cap = ast_format_cap_joint(dst_cap, src_cap); 01194 ast_format_clear(&best); 01195 ast_format_clear(&bestdst); 01196 01197 if (joint_cap) { /* yes, pick one and return */ 01198 struct ast_format tmp_fmt; 01199 ast_format_cap_iter_start(joint_cap); 01200 while (!ast_format_cap_iter_next(joint_cap, &tmp_fmt)) { 01201 /* We are guaranteed to find one common format. */ 01202 if (!best.id) { 01203 ast_format_copy(&best, &tmp_fmt); 01204 continue; 01205 } 01206 /* If there are multiple common formats, pick the one with the highest sample rate */ 01207 if (ast_format_rate(&best) < ast_format_rate(&tmp_fmt)) { 01208 ast_format_copy(&best, &tmp_fmt); 01209 continue; 01210 } 01211 01212 } 01213 ast_format_cap_iter_end(joint_cap); 01214 01215 /* We are done, this is a common format to both. */ 01216 ast_format_copy(dst_fmt_out, &best); 01217 ast_format_copy(src_fmt_out, &best); 01218 ast_format_cap_destroy(joint_cap); 01219 return 0; 01220 } else { /* No, we will need to translate */ 01221 struct ast_format cur_dst; 01222 struct ast_format cur_src; 01223 AST_RWLIST_RDLOCK(&translators); 01224 01225 ast_format_cap_iter_start(dst_cap); 01226 while (!ast_format_cap_iter_next(dst_cap, &cur_dst)) { 01227 ast_format_cap_iter_start(src_cap); 01228 while (!ast_format_cap_iter_next(src_cap, &cur_src)) { 01229 int x = format2index(cur_src.id); 01230 int y = format2index(cur_dst.id); 01231 if (x < 0 || y < 0) { 01232 continue; 01233 } 01234 if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) { 01235 continue; 01236 } 01237 if (((matrix_get(x, y)->table_cost < besttablecost) || (matrix_get(x, y)->multistep < beststeps))) { 01238 /* better than what we have so far */ 01239 ast_format_copy(&best, &cur_src); 01240 ast_format_copy(&bestdst, &cur_dst); 01241 besttablecost = matrix_get(x, y)->table_cost; 01242 beststeps = matrix_get(x, y)->multistep; 01243 } 01244 } 01245 ast_format_cap_iter_end(src_cap); 01246 } 01247 01248 ast_format_cap_iter_end(dst_cap); 01249 AST_RWLIST_UNLOCK(&translators); 01250 if (best.id) { 01251 ast_format_copy(dst_fmt_out, &bestdst); 01252 ast_format_copy(src_fmt_out, &best); 01253 return 0; 01254 } 01255 return -1; 01256 } 01257 }
| struct ast_trans_pvt* ast_translator_build_path | ( | struct ast_format * | dst, | |
| struct ast_format * | src | |||
| ) | [read] |
Builds a translator path Build a path (possibly NULL) from source to dest.
| dest | destination format | |
| source | source format |
Definition at line 415 of file translate.c.
References ast_format_set(), ast_getformatname(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_free_path(), ast_tv(), ast_translator::dst_fmt_index, format2index(), ast_format::id, index2format(), LOG_WARNING, matrix_get(), newpvt(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, translator_path::step, and ast_trans_pvt::t.
Referenced by ast_slinfactory_feed(), ast_writestream(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), audiohook_read_frame_helper(), conf_run(), set_format(), softmix_process_write_audio(), and softmix_translate_helper_change_rate().
00416 { 00417 struct ast_trans_pvt *head = NULL, *tail = NULL; 00418 int src_index, dst_index; 00419 struct ast_format tmp_fmt1; 00420 struct ast_format tmp_fmt2; 00421 00422 src_index = format2index(src->id); 00423 dst_index = format2index(dst->id); 00424 00425 if (src_index == -1 || dst_index == -1) { 00426 ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src_index == -1 ? "starting" : "ending"); 00427 return NULL; 00428 } 00429 00430 AST_RWLIST_RDLOCK(&translators); 00431 00432 while (src_index != dst_index) { 00433 struct ast_trans_pvt *cur; 00434 struct ast_format *explicit_dst = NULL; 00435 struct ast_translator *t = matrix_get(src_index, dst_index)->step; 00436 if (!t) { 00437 int src_id = index2format(src_index); 00438 int dst_id = index2format(dst_index); 00439 ast_log(LOG_WARNING, "No translator path from %s to %s\n", 00440 ast_getformatname(ast_format_set(&tmp_fmt1, src_id, 0)), 00441 ast_getformatname(ast_format_set(&tmp_fmt2, dst_id, 0))); 00442 AST_RWLIST_UNLOCK(&translators); 00443 return NULL; 00444 } 00445 if (dst_index == t->dst_fmt_index) { 00446 explicit_dst = dst; 00447 } 00448 if (!(cur = newpvt(t, explicit_dst))) { 00449 int src_id = index2format(src_index); 00450 int dst_id = index2format(dst_index); 00451 ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n", 00452 ast_getformatname(ast_format_set(&tmp_fmt1, src_id, 0)), 00453 ast_getformatname(ast_format_set(&tmp_fmt2, dst_id, 0))); 00454 if (head) { 00455 ast_translator_free_path(head); 00456 } 00457 AST_RWLIST_UNLOCK(&translators); 00458 return NULL; 00459 } 00460 if (!head) { 00461 head = cur; 00462 } else { 00463 tail->next = cur; 00464 } 00465 tail = cur; 00466 cur->nextin = cur->nextout = ast_tv(0, 0); 00467 /* Keep going if this isn't the final destination */ 00468 src_index = cur->t->dst_fmt_index; 00469 } 00470 00471 AST_RWLIST_UNLOCK(&translators); 00472 return head; 00473 }
| void ast_translator_deactivate | ( | struct ast_translator * | t | ) |
Deactivate a translator.
| t | translator to deactivate |
Definition at line 1175 of file translate.c.
References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and matrix_rebuild().
01176 { 01177 AST_RWLIST_WRLOCK(&translators); 01178 t->active = 0; 01179 matrix_rebuild(0); 01180 AST_RWLIST_UNLOCK(&translators); 01181 }
| void ast_translator_free_path | ( | struct ast_trans_pvt * | tr | ) |
Frees a translator path Frees the given translator path structure.
| tr | translator path to get rid of |
Definition at line 405 of file translate.c.
References destroy(), and ast_trans_pvt::next.
Referenced by ast_audiohook_destroy(), ast_audiohook_detach_list(), ast_channel_destructor(), ast_slinfactory_destroy(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_translator_build_path(), ast_writestream(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), audiohook_read_frame_helper(), conf_free(), filestream_destructor(), free_translation(), set_format(), softmix_translate_helper_change_rate(), and softmix_translate_helper_free_entry().
00406 { 00407 struct ast_trans_pvt *pn = p; 00408 while ( (p = pn) ) { 00409 pn = p->next; 00410 destroy(p); 00411 } 00412 }
| int ast_unregister_translator | ( | struct ast_translator * | t | ) |
Unregister a translator Unregisters the given tranlator.
| t | translator to unregister |
Definition at line 1138 of file translate.c.
References ast_getformatname(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, COLOR_BLACK, COLOR_MAGENTA, ast_translator::dst_format, ast_translator::list, matrix_rebuild(), ast_translator::name, ast_translator::src_format, and term_color().
Referenced by drop_translator(), load_module(), unload_module(), and unregister_translators().
01139 { 01140 char tmp[80]; 01141 struct ast_translator *u; 01142 int found = 0; 01143 01144 AST_RWLIST_WRLOCK(&translators); 01145 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 01146 if (u == t) { 01147 AST_RWLIST_REMOVE_CURRENT(list); 01148 ast_verb(2, "Unregistered translator '%s' from format %s to %s\n", 01149 term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), 01150 ast_getformatname(&t->src_format), 01151 ast_getformatname(&t->dst_format)); 01152 found = 1; 01153 break; 01154 } 01155 } 01156 AST_RWLIST_TRAVERSE_SAFE_END; 01157 01158 if (found) { 01159 matrix_rebuild(0); 01160 } 01161 01162 AST_RWLIST_UNLOCK(&translators); 01163 01164 return (u ? 0 : -1); 01165 }
1.5.6