Support for translation of data formats. translate.c. More...
#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(). | |
#define | MAX_AUDIO_FORMAT 47 |
#define | MAX_FORMAT 64 |
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 | |
format_t | ast_translate_available_formats (format_t dest, format_t src) |
Mask off unavailable formats from a format bitmask. | |
unsigned int | ast_translate_path_steps (format_t dest, format_t 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. | |
format_t | ast_translator_best_choice (format_t *dsts, format_t *srcs) |
Chooses the best translation path. | |
struct ast_trans_pvt * | ast_translator_build_path (format_t dest, format_t 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. |
Support for translation of data formats. translate.c.
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 170 of file translate.h.
Referenced by load_module(), and register_translator().
#define MAX_AUDIO_FORMAT 47 |
Definition at line 27 of file translate.h.
Referenced by ast_translator_best_choice().
#define MAX_FORMAT 64 |
Definition at line 28 of file translate.h.
Referenced by __ast_register_translator(), and rebuild_matrix().
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 853 of file translate.c.
References ast_translator::active, ARRAY_LEN, ast_cli_register_multiple(), 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, calc_cost(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::cost, default_frameout(), ast_translator::dstfmt, ast_translator::frameout, LOG_WARNING, MAX_FORMAT, ast_translator::module, ast_translator::name, powerof(), rebuild_matrix(), ast_translator::srcfmt, and term_color().
00854 { 00855 static int added_cli = 0; 00856 struct ast_translator *u; 00857 char tmp[80]; 00858 00859 if (!mod) { 00860 ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n"); 00861 return -1; 00862 } 00863 00864 if (!t->buf_size) { 00865 ast_log(LOG_WARNING, "empty buf size, you need to supply one\n"); 00866 return -1; 00867 } 00868 00869 t->module = mod; 00870 00871 t->srcfmt = powerof(t->srcfmt); 00872 t->dstfmt = powerof(t->dstfmt); 00873 t->active = 1; 00874 00875 if (t->srcfmt == -1 || t->dstfmt == -1) { 00876 ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->srcfmt == -1 ? "starting" : "ending"); 00877 return -1; 00878 } 00879 if (t->srcfmt >= MAX_FORMAT) { 00880 ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt)); 00881 return -1; 00882 } 00883 00884 if (t->dstfmt >= MAX_FORMAT) { 00885 ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt)); 00886 return -1; 00887 } 00888 00889 if (t->buf_size) { 00890 /* 00891 * Align buf_size properly, rounding up to the machine-specific 00892 * alignment for pointers. 00893 */ 00894 struct _test_align { void *a, *b; } p; 00895 int align = (char *)&p.b - (char *)&p.a; 00896 00897 t->buf_size = ((t->buf_size + align - 1) / align) * align; 00898 } 00899 00900 if (t->frameout == NULL) 00901 t->frameout = default_frameout; 00902 00903 calc_cost(t, 1); 00904 00905 ast_verb(2, "Registered translator '%s' from format %s to %s, cost %d\n", 00906 term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), 00907 ast_getformatname(1LL << t->srcfmt), ast_getformatname(1LL << t->dstfmt), t->cost); 00908 00909 if (!added_cli) { 00910 ast_cli_register_multiple(cli_translate, ARRAY_LEN(cli_translate)); 00911 added_cli++; 00912 } 00913 00914 AST_RWLIST_WRLOCK(&translators); 00915 00916 /* find any existing translators that provide this same srcfmt/dstfmt, 00917 and put this one in order based on cost */ 00918 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 00919 if ((u->srcfmt == t->srcfmt) && 00920 (u->dstfmt == t->dstfmt) && 00921 (u->cost > t->cost)) { 00922 AST_RWLIST_INSERT_BEFORE_CURRENT(t, list); 00923 t = NULL; 00924 break; 00925 } 00926 } 00927 AST_RWLIST_TRAVERSE_SAFE_END; 00928 00929 /* if no existing translator was found for this format combination, 00930 add it to the beginning of the list */ 00931 if (t) 00932 AST_RWLIST_INSERT_HEAD(&translators, t, list); 00933 00934 rebuild_matrix(0); 00935 00936 AST_RWLIST_UNLOCK(&translators); 00937 00938 return 0; 00939 }
struct ast_frame* ast_trans_frameout | ( | struct ast_trans_pvt * | pvt, | |
int | datalen, | |||
int | samples | |||
) | [read] |
generic frameout function
Definition at line 235 of file translate.c.
References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_trans_pvt::c, ast_frame_subclass::codec, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, ast_trans_pvt::f, f, 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().
00237 { 00238 struct ast_frame *f = &pvt->f; 00239 00240 if (samples) 00241 f->samples = samples; 00242 else { 00243 if (pvt->samples == 0) 00244 return NULL; 00245 f->samples = pvt->samples; 00246 pvt->samples = 0; 00247 } 00248 if (datalen) 00249 f->datalen = datalen; 00250 else { 00251 f->datalen = pvt->datalen; 00252 pvt->datalen = 0; 00253 } 00254 00255 f->frametype = AST_FRAME_VOICE; 00256 f->subclass.codec = 1LL << (pvt->t->dstfmt); 00257 f->mallocd = 0; 00258 f->offset = AST_FRIENDLY_OFFSET; 00259 f->src = pvt->t->name; 00260 f->data.ptr = pvt->outbuf.c; 00261 00262 return ast_frisolate(f); 00263 }
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 328 of file translate.c.
References ast_clear_flag, ast_debug, 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_subclass::codec, ast_frame::delivery, 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_audiohook_read_frame(), ast_slinfactory_feed(), ast_write(), ast_writestream(), audio_audiohook_write_list(), and conf_run().
00329 { 00330 struct ast_trans_pvt *p = path; 00331 struct ast_frame *out = f; 00332 struct timeval delivery; 00333 int has_timing_info; 00334 long ts; 00335 long len; 00336 int seqno; 00337 00338 has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO); 00339 ts = f->ts; 00340 len = f->len; 00341 seqno = f->seqno; 00342 00343 /* XXX hmmm... check this below */ 00344 if (!ast_tvzero(f->delivery)) { 00345 if (!ast_tvzero(path->nextin)) { 00346 /* Make sure this is in line with what we were expecting */ 00347 if (!ast_tveq(path->nextin, f->delivery)) { 00348 /* The time has changed between what we expected and this 00349 most recent time on the new packet. If we have a 00350 valid prediction adjust our output time appropriately */ 00351 if (!ast_tvzero(path->nextout)) { 00352 path->nextout = ast_tvadd(path->nextout, 00353 ast_tvsub(f->delivery, path->nextin)); 00354 } 00355 path->nextin = f->delivery; 00356 } 00357 } else { 00358 /* This is our first pass. Make sure the timing looks good */ 00359 path->nextin = f->delivery; 00360 path->nextout = f->delivery; 00361 } 00362 /* Predict next incoming sample */ 00363 path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, ast_format_rate(f->subclass.codec))); 00364 } 00365 delivery = f->delivery; 00366 for ( ; out && p ; p = p->next) { 00367 framein(p, out); 00368 if (out != f) 00369 ast_frfree(out); 00370 out = p->t->frameout(p); 00371 } 00372 if (out) { 00373 /* we have a frame, play with times */ 00374 if (!ast_tvzero(delivery)) { 00375 /* Regenerate prediction after a discontinuity */ 00376 if (ast_tvzero(path->nextout)) { 00377 path->nextout = ast_tvnow(); 00378 } 00379 00380 /* Use next predicted outgoing timestamp */ 00381 out->delivery = path->nextout; 00382 00383 /* Predict next outgoing timestamp from samples in this 00384 frame. */ 00385 path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(out->subclass.codec))); 00386 if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) { 00387 ast_debug(4, "Sample size different %d vs %d\n", f->samples, out->samples); 00388 ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO); 00389 } 00390 } else { 00391 out->delivery = ast_tv(0, 0); 00392 ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO); 00393 if (has_timing_info) { 00394 out->ts = ts; 00395 out->len = len; 00396 out->seqno = seqno; 00397 } 00398 } 00399 /* Invalidate prediction if we're entering a silence period */ 00400 if (out->frametype == AST_FRAME_CNG) { 00401 path->nextout = ast_tv(0, 0); 00402 } 00403 } 00404 if (consume) { 00405 ast_frfree(f); 00406 } 00407 return out; 00408 }
Mask off unavailable formats from a format bitmask.
The result will include all formats from 'dest' that are either present in 'src' or translatable from a format present in 'src'.
Definition at line 1081 of file translate.c.
References AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, powerof(), and tr_matrix.
Referenced by ast_rtp_instance_available_formats().
01082 { 01083 format_t res = dest; 01084 format_t x; 01085 format_t src_audio = src & AST_FORMAT_AUDIO_MASK; 01086 format_t src_video = src & AST_FORMAT_VIDEO_MASK; 01087 format_t x_bits; 01088 01089 /* if we don't have a source format, we just have to try all 01090 possible destination formats */ 01091 if (!src) 01092 return dest; 01093 01094 /* If we have a source audio format, get its format index */ 01095 if (src_audio) { 01096 src_audio = powerof(src_audio); 01097 } 01098 01099 /* If we have a source video format, get its format index */ 01100 if (src_video) { 01101 src_video = powerof(src_video); 01102 } 01103 01104 /* Note that src_audio and src_video are guaranteed to not be 01105 * negative at this point, as we ensured they were non-zero. It is 01106 * safe to use the return value of powerof as an index into tr_matrix. 01107 */ 01108 01109 AST_RWLIST_RDLOCK(&translators); 01110 01111 /* For a given source audio format, traverse the list of 01112 known audio formats to determine whether there exists 01113 a translation path from the source format to the 01114 destination format. */ 01115 for (x = 1LL; src_audio && x > 0; x <<= 1) { 01116 if (!(x & AST_FORMAT_AUDIO_MASK)) { 01117 continue; 01118 } 01119 01120 /* if this is not a desired format, nothing to do */ 01121 if (!(dest & x)) 01122 continue; 01123 01124 /* if the source is supplying this format, then 01125 we can leave it in the result */ 01126 if (src & x) 01127 continue; 01128 01129 /* if we don't have a translation path from the src 01130 to this format, remove it from the result. Note that x_bits 01131 cannot be less than 0 as x will always have one bit set to 1 */ 01132 x_bits = powerof(x); 01133 if (!tr_matrix[src_audio][x_bits].step) { 01134 res &= ~x; 01135 continue; 01136 } 01137 01138 /* now check the opposite direction */ 01139 if (!tr_matrix[x_bits][src_audio].step) 01140 res &= ~x; 01141 } 01142 01143 /* For a given source video format, traverse the list of 01144 known video formats to determine whether there exists 01145 a translation path from the source format to the 01146 destination format. */ 01147 for (x = 1LL; src_video && x > 0; x <<= 1) { 01148 if (!(x & AST_FORMAT_VIDEO_MASK)) { 01149 continue; 01150 } 01151 01152 /* if this is not a desired format, nothing to do */ 01153 if (!(dest & x)) 01154 continue; 01155 01156 /* if the source is supplying this format, then 01157 we can leave it in the result */ 01158 if (src & x) 01159 continue; 01160 01161 /* if we don't have a translation path from the src 01162 to this format, remove it from the result. Note that x_bits 01163 cannot be less than 0 as x will always have one bit set to 1 */ 01164 x_bits = powerof(x); 01165 if (!tr_matrix[src_video][x_bits].step) { 01166 res &= ~x; 01167 continue; 01168 } 01169 01170 /* now check the opposite direction */ 01171 if (!tr_matrix[x_bits][src_video].step) 01172 res &= ~x; 01173 } 01174 01175 AST_RWLIST_UNLOCK(&translators); 01176 01177 return res; 01178 }
Returns the number of steps required to convert from 'src' to 'dest'.
dest | destination format | |
src | source format |
Definition at line 1059 of file translate.c.
References ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, LOG_WARNING, translator_path::multistep, powerof(), and tr_matrix.
Referenced by ast_channel_make_compatible_helper().
01060 { 01061 unsigned int res = -1; 01062 01063 /* convert bitwise format numbers into array indices */ 01064 src = powerof(src); 01065 dest = powerof(dest); 01066 01067 if (src == -1 || dest == -1) { 01068 ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src == -1 ? "starting" : "ending"); 01069 return -1; 01070 } 01071 AST_RWLIST_RDLOCK(&translators); 01072 01073 if (tr_matrix[src][dest].step) 01074 res = tr_matrix[src][dest].multistep + 1; 01075 01076 AST_RWLIST_UNLOCK(&translators); 01077 01078 return res; 01079 }
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 630 of file translate.c.
References ast_getformatname(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_translator::dstfmt, ast_trans_pvt::next, ast_translator::srcfmt, and ast_trans_pvt::t.
Referenced by handle_showchan(), and serialize_showchan().
00631 { 00632 struct ast_trans_pvt *pn = p; 00633 00634 if (!p || !p->t) { 00635 return ""; 00636 } 00637 00638 ast_str_set(str, 0, "%s", ast_getformatname(1LL << p->t->srcfmt)); 00639 00640 while ( (p = pn) ) { 00641 pn = p->next; 00642 ast_str_append(str, 0, "->%s", ast_getformatname(1LL << p->t->dstfmt)); 00643 } 00644 00645 return ast_str_buffer(*str); 00646 }
void ast_translator_activate | ( | struct ast_translator * | t | ) |
Activate a previously deactivated translator.
t | translator to activate |
Enables the specified translator for use.
Definition at line 967 of file translate.c.
References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and rebuild_matrix().
00968 { 00969 AST_RWLIST_WRLOCK(&translators); 00970 t->active = 1; 00971 rebuild_matrix(0); 00972 AST_RWLIST_UNLOCK(&translators); 00973 }
Chooses the best translation path.
Given a list of sources, and a designed destination format, which should I choose?
Definition at line 984 of file translate.c.
References AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, translator_path::cost, ast_translator::cost, MAX_AUDIO_FORMAT, translator_path::multistep, translator_path::rate_change, and tr_matrix.
Referenced by ast_channel_make_compatible_helper(), ast_request(), iax2_request(), and set_format().
00985 { 00986 int x,y; 00987 int better = 0; 00988 int besttime = INT_MAX; 00989 int beststeps = INT_MAX; 00990 unsigned int best_rate_change = INT_MAX; 00991 format_t best = -1; 00992 format_t bestdst = 0; 00993 format_t cur, cursrc; 00994 format_t common = ((*dst) & (*srcs)) & AST_FORMAT_AUDIO_MASK; /* are there common formats ? */ 00995 00996 if (common) { /* yes, pick one and return */ 00997 for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) { 00998 if (!(cur & common)) { 00999 continue; 01000 } 01001 01002 /* We are guaranteed to find one common format. */ 01003 if (best == -1) { 01004 best = cur; 01005 continue; 01006 } 01007 /* If there are multiple common formats, pick the one with the highest sample rate */ 01008 if (ast_format_rate(best) < ast_format_rate(cur)) { 01009 best = cur; 01010 continue; 01011 } 01012 } 01013 /* We are done, this is a common format to both. */ 01014 *srcs = *dst = best; 01015 return 0; 01016 } else { /* No, we will need to translate */ 01017 AST_RWLIST_RDLOCK(&translators); 01018 for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) { 01019 if (! (cur & *dst)) { 01020 continue; 01021 } 01022 for (cursrc = 1, x = 0; x <= MAX_AUDIO_FORMAT; cursrc <<= 1, x++) { 01023 if (!(*srcs & cursrc) || !tr_matrix[x][y].step) { 01024 continue; 01025 } 01026 01027 /* This is a better choice if any of the following are true. 01028 * 1. The sample rate conversion is better than the current pick. 01029 * 2. the sample rate conversion is no worse than the current pick and the cost or multistep is better 01030 */ 01031 better = 0; 01032 if (tr_matrix[x][y].rate_change < best_rate_change) { 01033 better = 1; /* this match has a better rate conversion */ 01034 } 01035 if ((tr_matrix[x][y].rate_change <= best_rate_change) && 01036 (tr_matrix[x][y].cost < besttime || tr_matrix[x][y].multistep < beststeps)) { 01037 better = 1; /* this match has no worse rate conversion and the conversion cost is less */ 01038 } 01039 if (better) { 01040 /* better than what we have so far */ 01041 best = cursrc; 01042 bestdst = cur; 01043 besttime = tr_matrix[x][y].cost; 01044 beststeps = tr_matrix[x][y].multistep; 01045 best_rate_change = tr_matrix[x][y].rate_change; 01046 } 01047 } 01048 } 01049 AST_RWLIST_UNLOCK(&translators); 01050 if (best > -1) { 01051 *srcs = best; 01052 *dst = bestdst; 01053 best = 0; 01054 } 01055 return best; 01056 } 01057 }
struct ast_trans_pvt* ast_translator_build_path | ( | format_t | dest, | |
format_t | source | |||
) | [read] |
Builds a translator path Build a path (possibly NULL) from source to dest.
dest | destination format | |
source | source format |
Definition at line 282 of file translate.c.
References ast_getformatname(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_free_path(), ast_tv(), ast_translator::dstfmt, LOG_WARNING, newpvt(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, powerof(), translator_path::step, ast_trans_pvt::t, and tr_matrix.
Referenced by ast_audiohook_read_frame(), ast_slinfactory_feed(), ast_writestream(), audio_audiohook_write_list(), conf_run(), and set_format().
00283 { 00284 struct ast_trans_pvt *head = NULL, *tail = NULL; 00285 00286 source = powerof(source); 00287 dest = powerof(dest); 00288 00289 if (source == -1 || dest == -1) { 00290 ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", source == -1 ? "starting" : "ending"); 00291 return NULL; 00292 } 00293 00294 AST_RWLIST_RDLOCK(&translators); 00295 00296 while (source != dest) { 00297 struct ast_trans_pvt *cur; 00298 struct ast_translator *t = tr_matrix[source][dest].step; 00299 if (!t) { 00300 ast_log(LOG_WARNING, "No translator path from %s to %s\n", 00301 ast_getformatname(source), ast_getformatname(dest)); 00302 AST_RWLIST_UNLOCK(&translators); 00303 return NULL; 00304 } 00305 if (!(cur = newpvt(t))) { 00306 ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n", 00307 ast_getformatname(source), ast_getformatname(dest)); 00308 if (head) 00309 ast_translator_free_path(head); 00310 AST_RWLIST_UNLOCK(&translators); 00311 return NULL; 00312 } 00313 if (!head) 00314 head = cur; 00315 else 00316 tail->next = cur; 00317 tail = cur; 00318 cur->nextin = cur->nextout = ast_tv(0, 0); 00319 /* Keep going if this isn't the final destination */ 00320 source = cur->t->dstfmt; 00321 } 00322 00323 AST_RWLIST_UNLOCK(&translators); 00324 return head; 00325 }
void ast_translator_deactivate | ( | struct ast_translator * | t | ) |
Deactivate a translator.
t | translator to deactivate |
Disables the specified translator from being used.
Definition at line 975 of file translate.c.
References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and rebuild_matrix().
00976 { 00977 AST_RWLIST_WRLOCK(&translators); 00978 t->active = 0; 00979 rebuild_matrix(0); 00980 AST_RWLIST_UNLOCK(&translators); 00981 }
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 272 of file translate.c.
References destroy(), and ast_trans_pvt::next.
Referenced by ast_audiohook_destroy(), ast_audiohook_detach_list(), ast_audiohook_read_frame(), ast_channel_destructor(), ast_slinfactory_destroy(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_translator_build_path(), ast_writestream(), audio_audiohook_write_list(), conf_free(), filestream_destructor(), free_translation(), and set_format().
00273 { 00274 struct ast_trans_pvt *pn = p; 00275 while ( (p = pn) ) { 00276 pn = p->next; 00277 destroy(p); 00278 } 00279 }
int ast_unregister_translator | ( | struct ast_translator * | t | ) |
Unregister a translator Unregisters the given tranlator.
t | translator to unregister |
Definition at line 942 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::dstfmt, ast_translator::list, ast_translator::name, rebuild_matrix(), ast_translator::srcfmt, and term_color().
Referenced by drop_translator(), load_module(), unload_module(), and unregister_translators().
00943 { 00944 char tmp[80]; 00945 struct ast_translator *u; 00946 int found = 0; 00947 00948 AST_RWLIST_WRLOCK(&translators); 00949 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 00950 if (u == t) { 00951 AST_RWLIST_REMOVE_CURRENT(list); 00952 ast_verb(2, "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1LL << t->srcfmt), ast_getformatname(1LL << t->dstfmt)); 00953 found = 1; 00954 break; 00955 } 00956 } 00957 AST_RWLIST_TRAVERSE_SAFE_END; 00958 00959 if (found) 00960 rebuild_matrix(0); 00961 00962 AST_RWLIST_UNLOCK(&translators); 00963 00964 return (u ? 0 : -1); 00965 }