Mon May 14 04:53:38 2007

Asterisk developer's documentation


translate.h File Reference

Support for translation of data formats. 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. 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_frameast_trans_frameout (struct ast_trans_pvt *pvt, int datalen, int samples)
 generic frameout function
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
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_pvtast_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.


Detailed Description

Support for translation of data formats.

Definition in file translate.h.


Define Documentation

#define ast_register_translator ( t   )     __ast_register_translator(t, ast_module_info->self)

Definition at line 160 of file translate.h.

Referenced by load_module(), and register_translator().

#define MAX_FORMAT   32

Definition at line 27 of file translate.h.

Referenced by __ast_register_translator(), ast_translator_best_choice(), and rebuild_matrix().


Function Documentation

int __ast_register_translator ( struct ast_translator t,
struct ast_module module 
)

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

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

Parameters:
dest possible destination formats
src source formats
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 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'.

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

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.

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

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?

Returns:
Returns 0 on success, -1 if no path could be found.
Note:
Modifies dests and srcs in place

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.

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

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.

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

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.

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

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

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 }


Generated on Mon May 14 04:53:39 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1