![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
translate.h File Reference
Definition in file translate.h.
#include "asterisk/frame.h"
#include "asterisk/plc.h"
#include "asterisk/linkedlists.h"
Include dependency graph for translate.h:

This graph shows which files directly or indirectly include this file:

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. Name, callbacks, and various options related to run-time operation (size of buffers, auxiliary descriptors, etc). More... | |
Defines | |
| #define | ast_register_translator(t) __ast_register_translator(t, ast_module_info->self) |
| #define | MAX_FORMAT 32 |
Functions | |
| int | __ast_register_translator (struct ast_translator *t, struct ast_module *module) |
| Register a translator This registers a codec translator with asterisk. | |
| ast_frame * | ast_trans_frameout (struct ast_trans_pvt *pvt, int datalen, int samples) |
| generic frameout function | |
| 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 | |
| unsigned int | ast_translate_available_formats (unsigned int dest, unsigned int src) |
| Mask off unavailable formats from a format bitmask. | |
| unsigned int | ast_translate_path_steps (unsigned int dest, unsigned int src) |
| Returns the number of steps required to convert from 'src' to 'dest'. | |
| void | ast_translator_activate (struct ast_translator *t) |
| Activate a previously deactivated 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 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 at line 160 of file translate.h. |
|
|
Definition at line 27 of file translate.h. Referenced by __ast_register_translator(), ast_translator_best_choice(), and rebuild_matrix(). |
|
||||||||||||
|
Register a translator This registers a codec translator with asterisk.
Definition at line 572 of file translate.c. References ast_translator::active, ast_cli_register_multiple(), AST_FORMAT_SLINEAR, 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_verbose(), ast_translator::buf_size, ast_translator::buffer_samples, calc_cost(), cli_translate, 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, option_verbose, ast_translator::plc_samples, powerof(), rebuild_matrix(), ast_translator::srcfmt, term_color(), and VERBOSE_PREFIX_2. 00573 { 00574 static int added_cli = 0; 00575 struct ast_translator *u; 00576 00577 if (!mod) { 00578 ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n"); 00579 return -1; 00580 } 00581 00582 if (!t->buf_size) { 00583 ast_log(LOG_WARNING, "empty buf size, you need to supply one\n"); 00584 return -1; 00585 } 00586 00587 t->module = mod; 00588 00589 t->srcfmt = powerof(t->srcfmt); 00590 t->dstfmt = powerof(t->dstfmt); 00591 t->active = 1; 00592 00593 if (t->plc_samples) { 00594 if (t->buffer_samples < t->plc_samples) { 00595 ast_log(LOG_WARNING, "plc_samples %d buffer_samples %d\n", 00596 t->plc_samples, t->buffer_samples); 00597 return -1; 00598 } 00599 if (t->dstfmt != AST_FORMAT_SLINEAR) 00600 ast_log(LOG_WARNING, "plc_samples %d format %x\n", 00601 t->plc_samples, t->dstfmt); 00602 } 00603 if (t->srcfmt >= MAX_FORMAT) { 00604 ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt)); 00605 return -1; 00606 } 00607 00608 if (t->dstfmt >= MAX_FORMAT) { 00609 ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt)); 00610 return -1; 00611 } 00612 00613 if (t->buf_size) { 00614 /* 00615 * Align buf_size properly, rounding up to the machine-specific 00616 * alignment for pointers. 00617 */ 00618 struct _test_align { void *a, *b; } p; 00619 int align = (char *)&p.b - (char *)&p.a; 00620 00621 t->buf_size = ((t->buf_size + align - 1) / align) * align; 00622 } 00623 00624 if (t->frameout == NULL) 00625 t->frameout = default_frameout; 00626 00627 calc_cost(t, 1); 00628 00629 if (option_verbose > 1) { 00630 char tmp[80]; 00631 00632 ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n", 00633 term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), 00634 ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost); 00635 } 00636 00637 if (!added_cli) { 00638 ast_cli_register_multiple(cli_translate, sizeof(cli_translate) / sizeof(struct ast_cli_entry)); 00639 added_cli++; 00640 } 00641 00642 AST_RWLIST_WRLOCK(&translators); 00643 00644 /* find any existing translators that provide this same srcfmt/dstfmt, 00645 and put this one in order based on cost */ 00646 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 00647 if ((u->srcfmt == t->srcfmt) && 00648 (u->dstfmt == t->dstfmt) && 00649 (u->cost > t->cost)) { 00650 AST_RWLIST_INSERT_BEFORE_CURRENT(&translators, t, list); 00651 t = NULL; 00652 } 00653 } 00654 AST_RWLIST_TRAVERSE_SAFE_END; 00655 00656 /* if no existing translator was found for this format combination, 00657 add it to the beginning of the list */ 00658 if (t) 00659 AST_RWLIST_INSERT_HEAD(&translators, t, list); 00660 00661 rebuild_matrix(0); 00662 00663 AST_RWLIST_UNLOCK(&translators); 00664 00665 return 0; 00666 }
|
|
||||||||||||||||
|
||||||||||||||||
|
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
Definition at line 293 of file translate.c. References ast_tvadd(), ast_tvsub(), ast_frame::delivery, framein(), ast_frame::has_timing_info, ast_frame::len, len, ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, ast_frame::samples, ast_frame::seqno, and ast_frame::ts. Referenced by __ast_read(), ast_slinfactory_feed(), ast_write(), ast_writestream(), process_ast_dsp(), and queue_frame_to_spies(). 00294 { 00295 struct ast_trans_pvt *p = path; 00296 struct ast_frame *out = f; 00297 struct timeval delivery; 00298 int has_timing_info; 00299 long ts; 00300 long len; 00301 int seqno; 00302 00303 has_timing_info = f->has_timing_info; 00304 ts = f->ts; 00305 len = f->len; 00306 seqno = f->seqno; 00307 00308 /* XXX hmmm... check this below */ 00309 if (!ast_tvzero(f->delivery)) { 00310 if (!ast_tvzero(path->nextin)) { 00311 /* Make sure this is in line with what we were expecting */ 00312 if (!ast_tveq(path->nextin, f->delivery)) { 00313 /* The time has changed between what we expected and this 00314 most recent time on the new packet. If we have a 00315 valid prediction adjust our output time appropriately */ 00316 if (!ast_tvzero(path->nextout)) { 00317 path->nextout = ast_tvadd(path->nextout, 00318 ast_tvsub(f->delivery, path->nextin)); 00319 } 00320 path->nextin = f->delivery; 00321 } 00322 } else { 00323 /* This is our first pass. Make sure the timing looks good */ 00324 path->nextin = f->delivery; 00325 path->nextout = f->delivery; 00326 } 00327 /* Predict next incoming sample */ 00328 path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000)); 00329 } 00330 delivery = f->delivery; 00331 for ( ; out && p ; p = p->next) { 00332 framein(p, out); 00333 out = p->t->frameout(p); 00334 } 00335 if (consume) 00336 ast_frfree(f); 00337 if (out == NULL) 00338 return NULL; 00339 /* we have a frame, play with times */ 00340 if (!ast_tvzero(delivery)) { 00341 /* Regenerate prediction after a discontinuity */ 00342 if (ast_tvzero(path->nextout)) 00343 path->nextout = ast_tvnow(); 00344 00345 /* Use next predicted outgoing timestamp */ 00346 out->delivery = path->nextout; 00347 00348 /* Predict next outgoing timestamp from samples in this 00349 frame. */ 00350 path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000)); 00351 } else { 00352 out->delivery = ast_tv(0, 0); 00353 out->has_timing_info = has_timing_info; 00354 if (has_timing_info) { 00355 out->ts = ts; 00356 out->len = len; 00357 out->seqno = seqno; 00358 } 00359 } 00360 /* Invalidate prediction if we're entering a silence period */ 00361 if (out->frametype == AST_FRAME_CNG) 00362 path->nextout = ast_tv(0, 0); 00363 return out; 00364 }
|
|
||||||||||||
|
Mask off unavailable formats from a format bitmask.
Note that only a single audio format and a single video format can be present in 'src', or the function will produce unexpected results. Definition at line 777 of file translate.c. References AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_VIDEO_MASK, AST_RWLIST_RDLOCK, powerof(), and tr_matrix. Referenced by sip_call(). 00778 { 00779 unsigned int res = dest; 00780 unsigned int x; 00781 unsigned int src_audio = src & AST_FORMAT_AUDIO_MASK; 00782 unsigned int src_video = src & AST_FORMAT_VIDEO_MASK; 00783 00784 /* if we don't have a source format, we just have to try all 00785 possible destination formats */ 00786 if (!src) 00787 return dest; 00788 00789 /* If we have a source audio format, get its format index */ 00790 if (src_audio) 00791 src_audio = powerof(src_audio); 00792 00793 /* If we have a source video format, get its format index */ 00794 if (src_video) 00795 src_video = powerof(src_video); 00796 00797 AST_RWLIST_RDLOCK(&translators); 00798 00799 /* For a given source audio format, traverse the list of 00800 known audio formats to determine whether there exists 00801 a translation path from the source format to the 00802 destination format. */ 00803 for (x = 1; src_audio && x < AST_FORMAT_MAX_AUDIO; x <<= 1) { 00804 /* if this is not a desired format, nothing to do */ 00805 if (!dest & x) 00806 continue; 00807 00808 /* if the source is supplying this format, then 00809 we can leave it in the result */ 00810 if (src & x) 00811 continue; 00812 00813 /* if we don't have a translation path from the src 00814 to this format, remove it from the result */ 00815 if (!tr_matrix[src_audio][powerof(x)].step) { 00816 res &= ~x; 00817 continue; 00818 } 00819 00820 /* now check the opposite direction */ 00821 if (!tr_matrix[powerof(x)][src_audio].step) 00822 res &= ~x; 00823 } 00824 00825 /* For a given source video format, traverse the list of 00826 known video formats to determine whether there exists 00827 a translation path from the source format to the 00828 destination format. */ 00829 for (; src_video && x < AST_FORMAT_MAX_VIDEO; x <<= 1) { 00830 /* if this is not a desired format, nothing to do */ 00831 if (!dest & x) 00832 continue; 00833 00834 /* if the source is supplying this format, then 00835 we can leave it in the result */ 00836 if (src & x) 00837 continue; 00838 00839 /* if we don't have a translation path from the src 00840 to this format, remove it from the result */ 00841 if (!tr_matrix[src_video][powerof(x)].step) { 00842 res &= ~x; 00843 continue; 00844 } 00845 00846 /* now check the opposite direction */ 00847 if (!tr_matrix[powerof(x)][src_video].step) 00848 res &= ~x; 00849 } 00850 00851 AST_RWLIST_UNLOCK(&translators); 00852 00853 return res; 00854 }
|
|
||||||||||||
|
Returns the number of steps required to convert from 'src' to 'dest'.
Definition at line 759 of file translate.c. References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, translator_path::multistep, powerof(), and tr_matrix. Referenced by ast_channel_make_compatible_helper(). 00760 { 00761 unsigned int res = -1; 00762 00763 /* convert bitwise format numbers into array indices */ 00764 src = powerof(src); 00765 dest = powerof(dest); 00766 00767 AST_RWLIST_RDLOCK(&translators); 00768 00769 if (tr_matrix[src][dest].step) 00770 res = tr_matrix[src][dest].multistep + 1; 00771 00772 AST_RWLIST_UNLOCK(&translators); 00773 00774 return res; 00775 }
|
|
|
Activate a previously deactivated translator.
Definition at line 695 of file translate.c. References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and rebuild_matrix(). 00696 { 00697 AST_RWLIST_WRLOCK(&translators); 00698 t->active = 1; 00699 rebuild_matrix(0); 00700 AST_RWLIST_UNLOCK(&translators); 00701 }
|
|
||||||||||||
|
Chooses the best translation path. Given a list of sources, and a designed destination format, which should I choose?
Definition at line 712 of file translate.c. References MAX_FORMAT. Referenced by ast_channel_make_compatible_helper(), ast_request(), iax2_request(), and set_format(). 00713 { 00714 int x,y; 00715 int best = -1; 00716 int bestdst = 0; 00717 int cur, cursrc; 00718 int besttime = INT_MAX; 00719 int beststeps = INT_MAX; 00720 int common = (*dst) & (*srcs); /* are there common formats ? */ 00721 00722 if (common) { /* yes, pick one and return */ 00723 for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) { 00724 if (cur & common) /* guaranteed to find one */ 00725 break; 00726 } 00727 /* We are done, this is a common format to both. */ 00728 *srcs = *dst = cur; 00729 return 0; 00730 } else { /* No, we will need to translate */ 00731 AST_RWLIST_RDLOCK(&translators); 00732 for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) { 00733 if (! (cur & *dst)) 00734 continue; 00735 for (cursrc = 1, x = 0; x < MAX_FORMAT; cursrc <<= 1, x++) { 00736 if (!(*srcs & cursrc) || !tr_matrix[x][y].step || 00737 tr_matrix[x][y].cost > besttime) 00738 continue; /* not existing or no better */ 00739 if (tr_matrix[x][y].cost < besttime || 00740 tr_matrix[x][y].multistep < beststeps) { 00741 /* better than what we have so far */ 00742 best = cursrc; 00743 bestdst = cur; 00744 besttime = tr_matrix[x][y].cost; 00745 beststeps = tr_matrix[x][y].multistep; 00746 } 00747 } 00748 } 00749 AST_RWLIST_UNLOCK(&translators); 00750 if (best > -1) { 00751 *srcs = best; 00752 *dst = bestdst; 00753 best = 0; 00754 } 00755 return best; 00756 } 00757 }
|
|
||||||||||||
|
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition at line 253 of file translate.c. References ast_getformatname(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_free_path(), 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_slinfactory_feed(), ast_write(), ast_writestream(), queue_frame_to_spies(), read_config(), and set_format(). 00254 { 00255 struct ast_trans_pvt *head = NULL, *tail = NULL; 00256 00257 source = powerof(source); 00258 dest = powerof(dest); 00259 00260 AST_RWLIST_RDLOCK(&translators); 00261 00262 while (source != dest) { 00263 struct ast_trans_pvt *cur; 00264 struct ast_translator *t = tr_matrix[source][dest].step; 00265 if (!t) { 00266 ast_log(LOG_WARNING, "No translator path from %s to %s\n", 00267 ast_getformatname(source), ast_getformatname(dest)); 00268 AST_RWLIST_UNLOCK(&translators); 00269 return NULL; 00270 } 00271 if (!(cur = newpvt(t))) { 00272 ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest); 00273 if (head) 00274 ast_translator_free_path(head); 00275 AST_RWLIST_UNLOCK(&translators); 00276 return NULL; 00277 } 00278 if (!head) 00279 head = cur; 00280 else 00281 tail->next = cur; 00282 tail = cur; 00283 cur->nextin = cur->nextout = ast_tv(0, 0); 00284 /* Keep going if this isn't the final destination */ 00285 source = cur->t->dstfmt; 00286 } 00287 00288 AST_RWLIST_UNLOCK(&translators); 00289 return head; 00290 }
|
|
|
Deactivate a translator.
Definition at line 703 of file translate.c. References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and rebuild_matrix(). 00704 { 00705 AST_RWLIST_WRLOCK(&translators); 00706 t->active = 0; 00707 rebuild_matrix(0); 00708 AST_RWLIST_UNLOCK(&translators); 00709 }
|
|
|
Frees a translator path Frees the given translator path structure.
Definition at line 243 of file translate.c. References destroy(), and ast_trans_pvt::next. Referenced by ast_channel_free(), ast_channel_whisper_stop(), ast_closestream(), ast_slinfactory_destroy(), ast_slinfactory_feed(), ast_translator_build_path(), ast_write(), ast_writestream(), cl_dequeue_chan(), free_translation(), queue_frame_to_spies(), set_format(), and spy_cleanup(). 00244 { 00245 struct ast_trans_pvt *pn = p; 00246 while ( (p = pn) ) { 00247 pn = p->next; 00248 destroy(p); 00249 } 00250 }
|
|
|
Unregister a translator Unregisters the given tranlator.
Definition at line 669 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_verbose(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::dstfmt, ast_translator::name, option_verbose, rebuild_matrix(), ast_translator::srcfmt, term_color(), and VERBOSE_PREFIX_2. 00670 { 00671 char tmp[80]; 00672 struct ast_translator *u; 00673 int found = 0; 00674 00675 AST_RWLIST_WRLOCK(&translators); 00676 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 00677 if (u == t) { 00678 AST_RWLIST_REMOVE_CURRENT(&translators, list); 00679 if (option_verbose > 1) 00680 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)); 00681 found = 1; 00682 break; 00683 } 00684 } 00685 AST_RWLIST_TRAVERSE_SAFE_END; 00686 00687 if (found) 00688 rebuild_matrix(0); 00689 00690 AST_RWLIST_UNLOCK(&translators); 00691 00692 return (u ? 0 : -1); 00693 }
|