#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 in file translate.h.
#define ast_register_translator | ( | t | ) | __ast_register_translator(t, ast_module_info->self) |
#define MAX_FORMAT 32 |
Definition at line 27 of file translate.h.
Referenced by __ast_register_translator(), ast_translator_best_choice(), and rebuild_matrix().
int __ast_register_translator | ( | struct ast_translator * | t, | |
struct ast_module * | module | |||
) |
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 651 of file translate.c.
References ast_cli_register_multiple(), AST_FORMAT_SLINEAR, ast_getformatname(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), calc_cost(), cli_translate, COLOR_BLACK, COLOR_MAGENTA, ast_translator::cost, default_frameout(), ast_translator::dstfmt, LOG_WARNING, MAX_FORMAT, option_verbose, powerof(), rebuild_matrix(), ast_translator::srcfmt, t, term_color(), and VERBOSE_PREFIX_2.
00652 { 00653 static int added_cli = 0; 00654 struct ast_translator *u; 00655 00656 if (!mod) { 00657 ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n"); 00658 return -1; 00659 } 00660 00661 if (!t->buf_size) { 00662 ast_log(LOG_WARNING, "empty buf size, you need to supply one\n"); 00663 return -1; 00664 } 00665 00666 t->module = mod; 00667 00668 t->srcfmt = powerof(t->srcfmt); 00669 t->dstfmt = powerof(t->dstfmt); 00670 t->active = 1; 00671 00672 if (t->plc_samples) { 00673 if (t->buffer_samples < t->plc_samples) { 00674 ast_log(LOG_WARNING, "plc_samples %d buffer_samples %d\n", 00675 t->plc_samples, t->buffer_samples); 00676 return -1; 00677 } 00678 if (t->dstfmt != AST_FORMAT_SLINEAR) 00679 ast_log(LOG_WARNING, "plc_samples %d format %x\n", 00680 t->plc_samples, t->dstfmt); 00681 } 00682 if (t->srcfmt >= MAX_FORMAT) { 00683 ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt)); 00684 return -1; 00685 } 00686 00687 if (t->dstfmt >= MAX_FORMAT) { 00688 ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt)); 00689 return -1; 00690 } 00691 00692 if (t->buf_size) { 00693 /* 00694 * Align buf_size properly, rounding up to the machine-specific 00695 * alignment for pointers. 00696 */ 00697 struct _test_align { void *a, *b; } p; 00698 int align = (char *)&p.b - (char *)&p.a; 00699 00700 t->buf_size = ((t->buf_size + align - 1) / align) * align; 00701 } 00702 00703 if (t->frameout == NULL) 00704 t->frameout = default_frameout; 00705 00706 calc_cost(t, 1); 00707 00708 if (option_verbose > 1) { 00709 char tmp[80]; 00710 00711 ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n", 00712 term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), 00713 ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost); 00714 } 00715 00716 if (!added_cli) { 00717 ast_cli_register_multiple(cli_translate, sizeof(cli_translate) / sizeof(struct ast_cli_entry)); 00718 added_cli++; 00719 } 00720 00721 AST_LIST_LOCK(&translators); 00722 00723 /* find any existing translators that provide this same srcfmt/dstfmt, 00724 and put this one in order based on cost */ 00725 AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 00726 if ((u->srcfmt == t->srcfmt) && 00727 (u->dstfmt == t->dstfmt) && 00728 (u->cost > t->cost)) { 00729 AST_LIST_INSERT_BEFORE_CURRENT(&translators, t, list); 00730 t = NULL; 00731 } 00732 } 00733 AST_LIST_TRAVERSE_SAFE_END; 00734 00735 /* if no existing translator was found for this format combination, 00736 add it to the beginning of the list */ 00737 if (t) 00738 AST_LIST_INSERT_HEAD(&translators, t, list); 00739 00740 rebuild_matrix(0); 00741 00742 AST_LIST_UNLOCK(&translators); 00743 00744 return 0; 00745 }
struct ast_frame* ast_trans_frameout | ( | struct ast_trans_pvt * | pvt, | |
int | datalen, | |||
int | samples | |||
) |
generic frameout function
Definition at line 211 of file translate.c.
References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_trans_pvt::datalen, ast_translator::dstfmt, ast_trans_pvt::f, f, ast_translator::name, ast_trans_pvt::outbuf, ast_trans_pvt::samples, and ast_trans_pvt::t.
Referenced by default_frameout(), lintoadpcm_frameout(), lintogsm_frameout(), lintoilbc_frameout(), and lintolpc10_frameout().
00213 { 00214 struct ast_frame *f = &pvt->f; 00215 00216 if (samples) 00217 f->samples = samples; 00218 else { 00219 if (pvt->samples == 0) 00220 return NULL; 00221 f->samples = pvt->samples; 00222 pvt->samples = 0; 00223 } 00224 if (datalen) 00225 f->datalen = datalen; 00226 else { 00227 f->datalen = pvt->datalen; 00228 pvt->datalen = 0; 00229 } 00230 00231 f->frametype = AST_FRAME_VOICE; 00232 f->subclass = 1 << (pvt->t->dstfmt); 00233 f->mallocd = 0; 00234 f->offset = AST_FRIENDLY_OFFSET; 00235 f->src = pvt->t->name; 00236 f->data = pvt->outbuf; 00237 return f; 00238 }
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
tr | translator structure to use for translation | |
f | frame to translate | |
consume | Whether or not to free the original frame |
Definition at line 297 of file translate.c.
References AST_FRAME_CNG, ast_frfree(), ast_tvadd(), ast_tvsub(), ast_frame::delivery, f, framein(), ast_frame::frametype, 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(), conf_run(), process_ast_dsp(), and queue_frame_to_spies().
00298 { 00299 struct ast_trans_pvt *p = path; 00300 struct ast_frame *out = f; 00301 struct timeval delivery; 00302 int has_timing_info; 00303 long ts; 00304 long len; 00305 int seqno; 00306 00307 has_timing_info = f->has_timing_info; 00308 ts = f->ts; 00309 len = f->len; 00310 seqno = f->seqno; 00311 00312 /* XXX hmmm... check this below */ 00313 if (!ast_tvzero(f->delivery)) { 00314 if (!ast_tvzero(path->nextin)) { 00315 /* Make sure this is in line with what we were expecting */ 00316 if (!ast_tveq(path->nextin, f->delivery)) { 00317 /* The time has changed between what we expected and this 00318 most recent time on the new packet. If we have a 00319 valid prediction adjust our output time appropriately */ 00320 if (!ast_tvzero(path->nextout)) { 00321 path->nextout = ast_tvadd(path->nextout, 00322 ast_tvsub(f->delivery, path->nextin)); 00323 } 00324 path->nextin = f->delivery; 00325 } 00326 } else { 00327 /* This is our first pass. Make sure the timing looks good */ 00328 path->nextin = f->delivery; 00329 path->nextout = f->delivery; 00330 } 00331 /* Predict next incoming sample */ 00332 path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000)); 00333 } 00334 delivery = f->delivery; 00335 for ( ; out && p ; p = p->next) { 00336 framein(p, out); 00337 out = p->t->frameout(p); 00338 } 00339 if (consume) 00340 ast_frfree(f); 00341 if (out == NULL) 00342 return NULL; 00343 /* we have a frame, play with times */ 00344 if (!ast_tvzero(delivery)) { 00345 /* Regenerate prediction after a discontinuity */ 00346 if (ast_tvzero(path->nextout)) 00347 path->nextout = ast_tvnow(); 00348 00349 /* Use next predicted outgoing timestamp */ 00350 out->delivery = path->nextout; 00351 00352 /* Predict next outgoing timestamp from samples in this 00353 frame. */ 00354 path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000)); 00355 } else { 00356 out->delivery = ast_tv(0, 0); 00357 out->has_timing_info = has_timing_info; 00358 if (has_timing_info) { 00359 out->ts = ts; 00360 out->len = len; 00361 out->seqno = seqno; 00362 } 00363 } 00364 /* Invalidate prediction if we're entering a silence period */ 00365 if (out->frametype == AST_FRAME_CNG) 00366 path->nextout = ast_tv(0, 0); 00367 return out; 00368 }
unsigned int ast_translate_available_formats | ( | unsigned int | dest, | |
unsigned int | src | |||
) |
Mask off unavailable formats from a format bitmask.
dest | possible destination formats | |
src | source formats |
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 856 of file translate.c.
References AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, AST_LIST_LOCK, AST_LIST_UNLOCK, powerof(), and tr_matrix.
Referenced by sip_call().
00857 { 00858 unsigned int res = dest; 00859 unsigned int x; 00860 unsigned int src_audio = src & AST_FORMAT_AUDIO_MASK; 00861 unsigned int src_video = src & AST_FORMAT_VIDEO_MASK; 00862 00863 /* if we don't have a source format, we just have to try all 00864 possible destination formats */ 00865 if (!src) 00866 return dest; 00867 00868 /* If we have a source audio format, get its format index */ 00869 if (src_audio) 00870 src_audio = powerof(src_audio); 00871 00872 /* If we have a source video format, get its format index */ 00873 if (src_video) 00874 src_video = powerof(src_video); 00875 00876 AST_LIST_LOCK(&translators); 00877 00878 /* For a given source audio format, traverse the list of 00879 known audio formats to determine whether there exists 00880 a translation path from the source format to the 00881 destination format. */ 00882 for (x = 1; src_audio && x < AST_FORMAT_MAX_AUDIO; x <<= 1) { 00883 /* if this is not a desired format, nothing to do */ 00884 if (!dest & x) 00885 continue; 00886 00887 /* if the source is supplying this format, then 00888 we can leave it in the result */ 00889 if (src & x) 00890 continue; 00891 00892 /* if we don't have a translation path from the src 00893 to this format, remove it from the result */ 00894 if (!tr_matrix[src_audio][powerof(x)].step) { 00895 res &= ~x; 00896 continue; 00897 } 00898 00899 /* now check the opposite direction */ 00900 if (!tr_matrix[powerof(x)][src_audio].step) 00901 res &= ~x; 00902 } 00903 00904 /* For a given source video format, traverse the list of 00905 known video formats to determine whether there exists 00906 a translation path from the source format to the 00907 destination format. */ 00908 for (; src_video && x < AST_FORMAT_MAX_VIDEO; x <<= 1) { 00909 /* if this is not a desired format, nothing to do */ 00910 if (!dest & x) 00911 continue; 00912 00913 /* if the source is supplying this format, then 00914 we can leave it in the result */ 00915 if (src & x) 00916 continue; 00917 00918 /* if we don't have a translation path from the src 00919 to this format, remove it from the result */ 00920 if (!tr_matrix[src_video][powerof(x)].step) { 00921 res &= ~x; 00922 continue; 00923 } 00924 00925 /* now check the opposite direction */ 00926 if (!tr_matrix[powerof(x)][src_video].step) 00927 res &= ~x; 00928 } 00929 00930 AST_LIST_UNLOCK(&translators); 00931 00932 return res; 00933 }
unsigned int ast_translate_path_steps | ( | unsigned int | dest, | |
unsigned int | src | |||
) |
Returns the number of steps required to convert from 'src' to 'dest'.
dest | destination format | |
src | source format |
Definition at line 838 of file translate.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, translator_path::multistep, powerof(), and tr_matrix.
Referenced by ast_channel_make_compatible().
00839 { 00840 unsigned int res = -1; 00841 00842 /* convert bitwise format numbers into array indices */ 00843 src = powerof(src); 00844 dest = powerof(dest); 00845 00846 AST_LIST_LOCK(&translators); 00847 00848 if (tr_matrix[src][dest].step) 00849 res = tr_matrix[src][dest].multistep + 1; 00850 00851 AST_LIST_UNLOCK(&translators); 00852 00853 return res; 00854 }
void ast_translator_activate | ( | struct ast_translator * | t | ) |
Activate a previously deactivated translator.
t | translator to activate |
Definition at line 774 of file translate.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, rebuild_matrix(), and t.
00775 { 00776 AST_LIST_LOCK(&translators); 00777 t->active = 1; 00778 rebuild_matrix(0); 00779 AST_LIST_UNLOCK(&translators); 00780 }
int ast_translator_best_choice | ( | int * | dsts, | |
int * | srcs | |||
) |
Chooses the best translation path.
Given a list of sources, and a designed destination format, which should I choose?
Definition at line 791 of file translate.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, translator_path::cost, ast_translator::cost, MAX_FORMAT, translator_path::multistep, and tr_matrix.
Referenced by ast_channel_make_compatible(), ast_request(), iax2_request(), and set_format().
00792 { 00793 int x,y; 00794 int best = -1; 00795 int bestdst = 0; 00796 int cur, cursrc; 00797 int besttime = INT_MAX; 00798 int beststeps = INT_MAX; 00799 int common = (*dst) & (*srcs); /* are there common formats ? */ 00800 00801 if (common) { /* yes, pick one and return */ 00802 for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) { 00803 if (cur & common) /* guaranteed to find one */ 00804 break; 00805 } 00806 /* We are done, this is a common format to both. */ 00807 *srcs = *dst = cur; 00808 return 0; 00809 } else { /* No, we will need to translate */ 00810 AST_LIST_LOCK(&translators); 00811 for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) { 00812 if (! (cur & *dst)) 00813 continue; 00814 for (cursrc = 1, x = 0; x < MAX_FORMAT; cursrc <<= 1, x++) { 00815 if (!(*srcs & cursrc) || !tr_matrix[x][y].step || 00816 tr_matrix[x][y].cost > besttime) 00817 continue; /* not existing or no better */ 00818 if (tr_matrix[x][y].cost < besttime || 00819 tr_matrix[x][y].multistep < beststeps) { 00820 /* better than what we have so far */ 00821 best = cursrc; 00822 bestdst = cur; 00823 besttime = tr_matrix[x][y].cost; 00824 beststeps = tr_matrix[x][y].multistep; 00825 } 00826 } 00827 } 00828 AST_LIST_UNLOCK(&translators); 00829 if (best > -1) { 00830 *srcs = best; 00831 *dst = bestdst; 00832 best = 0; 00833 } 00834 return best; 00835 } 00836 }
struct ast_trans_pvt* ast_translator_build_path | ( | int | dest, | |
int | source | |||
) |
Builds a translator path Build a path (possibly NULL) from source to dest.
dest | destination format | |
source | source format |
Definition at line 257 of file translate.c.
References ast_getformatname(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), 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, t, and tr_matrix.
Referenced by ast_slinfactory_feed(), ast_write(), ast_writestream(), conf_run(), misdn_set_opt_exec(), queue_frame_to_spies(), read_config(), and set_format().
00258 { 00259 struct ast_trans_pvt *head = NULL, *tail = NULL; 00260 00261 source = powerof(source); 00262 dest = powerof(dest); 00263 00264 AST_LIST_LOCK(&translators); 00265 00266 while (source != dest) { 00267 struct ast_trans_pvt *cur; 00268 struct ast_translator *t = tr_matrix[source][dest].step; 00269 if (!t) { 00270 ast_log(LOG_WARNING, "No translator path from %s to %s\n", 00271 ast_getformatname(source), ast_getformatname(dest)); 00272 AST_LIST_UNLOCK(&translators); 00273 return NULL; 00274 } 00275 if (!(cur = newpvt(t))) { 00276 ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest); 00277 if (head) 00278 ast_translator_free_path(head); 00279 AST_LIST_UNLOCK(&translators); 00280 return NULL; 00281 } 00282 if (!head) 00283 head = cur; 00284 else 00285 tail->next = cur; 00286 tail = cur; 00287 cur->nextin = cur->nextout = ast_tv(0, 0); 00288 /* Keep going if this isn't the final destination */ 00289 source = cur->t->dstfmt; 00290 } 00291 00292 AST_LIST_UNLOCK(&translators); 00293 return head; 00294 }
void ast_translator_deactivate | ( | struct ast_translator * | t | ) |
Deactivate a translator.
t | translator to deactivate |
Definition at line 782 of file translate.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, rebuild_matrix(), and t.
00783 { 00784 AST_LIST_LOCK(&translators); 00785 t->active = 0; 00786 rebuild_matrix(0); 00787 AST_LIST_UNLOCK(&translators); 00788 }
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 247 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(), conf_free(), free_translation(), queue_frame_to_spies(), set_format(), and spy_cleanup().
00248 { 00249 struct ast_trans_pvt *pn = p; 00250 while ( (p = pn) ) { 00251 pn = p->next; 00252 destroy(p); 00253 } 00254 }
int ast_unregister_translator | ( | struct ast_translator * | t | ) |
Unregister a translator Unregisters the given tranlator.
t | translator to unregister |
Definition at line 748 of file translate.c.
References ast_getformatname(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), COLOR_BLACK, COLOR_MAGENTA, option_verbose, rebuild_matrix(), t, term_color(), and VERBOSE_PREFIX_2.
Referenced by drop_translator(), load_module(), unload_module(), and unregister_translators().
00749 { 00750 char tmp[80]; 00751 struct ast_translator *u; 00752 int found = 0; 00753 00754 AST_LIST_LOCK(&translators); 00755 AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) { 00756 if (u == t) { 00757 AST_LIST_REMOVE_CURRENT(&translators, list); 00758 if (option_verbose > 1) 00759 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)); 00760 found = 1; 00761 break; 00762 } 00763 } 00764 AST_LIST_TRAVERSE_SAFE_END; 00765 00766 if (found) 00767 rebuild_matrix(0); 00768 00769 AST_LIST_UNLOCK(&translators); 00770 00771 return (u ? 0 : -1); 00772 }