Sat Feb 11 06:36:57 2012

Asterisk developer's documentation


translate.h File Reference

Support for translation of data formats. translate.c. More...

#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. 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_frameast_trans_frameout (struct ast_trans_pvt *pvt, int datalen, int samples)
 generic frameout function
struct ast_frameast_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_pvtast_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.


Detailed Description

Support for translation of data formats. translate.c.

Definition in file translate.h.


Define Documentation

#define ast_register_translator (  )     __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().


Enumeration Type Documentation

Translator Cost Table definition.

Note:
The defined values in this table must be used to set the translator's table_cost value.

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.

This table is built in a way that allows translation paths to be built that guarantee the best possible balance between performance and quality. With this table direct translation paths between two formats will always take precedence over multi step paths, lossless intermediate steps will always be chosen over lossy intermediate steps, and preservation of sample rate across the translation will always have precedence over a path that involves any re-sampling.
Enumerator:
AST_TRANS_COST_LL_LL_ORIGSAMP  [lossless -> lossless] original sampling
AST_TRANS_COST_LL_LY_ORIGSAMP  [lossless -> lossy] original sampling
AST_TRANS_COST_LL_LL_UPSAMP  [lossless -> lossless] up sample
AST_TRANS_COST_LL_LY_UPSAMP  [lossless -> lossy] up sample
AST_TRANS_COST_LL_LL_DOWNSAMP  [lossless -> lossless] down sample
AST_TRANS_COST_LL_LY_DOWNSAMP  [lossless -> lossy] down sample
AST_TRANS_COST_LL_UNKNOWN  [lossless -> unknown] unknown. This value is for a lossless source translation with an unknown destination and or sample rate conversion.
AST_TRANS_COST_LY_LL_ORIGSAMP  [lossy -> lossless] original sampling
AST_TRANS_COST_LY_LY_ORIGSAMP  [lossy -> lossy] original sampling
AST_TRANS_COST_LY_LL_UPSAMP  [lossy -> lossless] up sample
AST_TRANS_COST_LY_LY_UPSAMP  [lossy -> lossy] up sample
AST_TRANS_COST_LY_LL_DOWNSAMP  [lossy -> lossless] down sample
AST_TRANS_COST_LY_LY_DOWNSAMP  [lossy -> lossy] down sample
AST_TRANS_COST_LY_UNKNOWN  [lossy -> unknown] unknown. This value is for a lossy source translation with an unknown destination and or sample rate conversion.

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 };


Function Documentation

int __ast_register_translator ( struct ast_translator t,
struct ast_module mod 
)

Register a translator This registers a codec translator with asterisk.

Parameters:
t populated ast_translator structure
module handle to the module that owns this translator
Returns:
0 on success, -1 on failure

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

Parameters:
tr translator structure to use for translation
f frame to translate
consume Whether or not to free the original frame
Returns:
an ast_frame of the new translation format on success, NULL on failure

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.

Parameters:
dest possible destination formats
src source formats
result capabilities structure to store available formats in
Returns:
the destination formats that are available in the source or translatable
The result will include all formats from 'dest' that are either present in 'src' or translatable from a format present in 'src'.

Note:
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 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.

Return values:
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'.

Parameters:
dest destination format
src source format
Returns:
the number of translation steps required, or -1 if no path is available

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.

Parameters:
translator structure containing the translation path
ast_str output buffer
Return values:
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.

Parameters:
t translator to activate
Returns:
nothing
Enables the specified translator for use.

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?

Parameters:
destination capabilities
source capabilities
destination format chosen out of destination capabilities
source format chosen out of source capabilities
Returns:
Returns 0 on success, -1 if no path could be found.
Note:
dst_cap and src_cap are not mondified.

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.

Parameters:
dest destination format
source source format
Returns:
ast_trans_pvt on success, NULL on failure

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.

Parameters:
t translator to deactivate
Returns:
nothing
Disables the specified translator from being used.

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  ) 

int ast_unregister_translator ( struct ast_translator t  ) 

Unregister a translator Unregisters the given tranlator.

Parameters:
t translator to unregister
Returns:
0 on success, -1 on failure

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 }


Generated on Sat Feb 11 06:36:57 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6