Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


translate.c File Reference

Translate via the use of pseudo channels. More...

#include "asterisk.h"
#include <sys/time.h>
#include <sys/resource.h>
#include <math.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/translate.h"
#include "asterisk/module.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/cli.h"
#include "asterisk/term.h"

Go to the source code of this file.

Data Structures

struct  translator_path
 
struct  translators
 the list of translators More...
 

Macros

#define MAX_RECALC   1000 /* max sample recalc */
 
#define SHOW_TRANS   64
 

Enumerations

enum  path_samp_change {
  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
}
 these values indicate how a translation path will affect the sample rate More...
 

Functions

int __ast_register_translator (struct ast_translator *t, struct ast_module *mod)
 register codec translator More...
 
struct ast_frameast_trans_frameout (struct ast_trans_pvt *pvt, int datalen, int samples)
 generic frameout routine. If samples and datalen are 0, take whatever is in pvt and reset them, otherwise take the values in the caller and leave alone the pvt values. More...
 
struct ast_frameast_translate (struct ast_trans_pvt *path, struct ast_frame *f, int consume)
 do the actual translation More...
 
format_t ast_translate_available_formats (format_t dest, format_t src)
 Mask off unavailable formats from a format bitmask. More...
 
unsigned int ast_translate_path_steps (format_t dest, format_t src)
 Returns the number of steps required to convert from 'src' to 'dest'. More...
 
const char * ast_translate_path_to_str (struct ast_trans_pvt *p, struct ast_str **str)
 Puts a string representation of the translation path into outbuf. More...
 
void ast_translator_activate (struct ast_translator *t)
 Activate a previously deactivated translator. More...
 
format_t ast_translator_best_choice (format_t *dst, format_t *srcs)
 Calculate our best translator source format, given costs, and a desired destination. More...
 
struct ast_trans_pvtast_translator_build_path (format_t dest, format_t source)
 Build a chain of translators based upon the given source and dest formats. More...
 
void ast_translator_deactivate (struct ast_translator *t)
 Deactivate a translator. More...
 
void ast_translator_free_path (struct ast_trans_pvt *p)
 Frees a translator path Frees the given translator path structure. More...
 
int ast_unregister_translator (struct ast_translator *t)
 unregister codec translator More...
 
static void calc_cost (struct ast_translator *t, int seconds)
 compute the cost of a single translation step More...
 
static char * complete_trans_path_choice (const char *line, const char *word, int pos, int state)
 
static struct ast_framedefault_frameout (struct ast_trans_pvt *pvt)
 
static void destroy (struct ast_trans_pvt *pvt)
 
static int framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 framein wrapper, deals with bound checks. More...
 
static enum path_samp_change get_rate_change_result (format_t src, format_t dst)
 
static char * handle_cli_core_show_translation (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void * newpvt (struct ast_translator *t)
 Allocate the descriptor, required outbuf space, and possibly desc. More...
 
static force_inline int powerof (format_t d)
 returns the index of the lowest bit set More...
 
static void rebuild_matrix (int samples)
 rebuild a translation matrix. More...
 

Variables

static struct ast_cli_entry cli_translate []
 
static struct translator_path tr_matrix [MAX_FORMAT][MAX_FORMAT]
 a matrix that, for any pair of supported formats, indicates the total cost of translation and the first step. The full path can be reconstricted iterating on the matrix until step->dstfmt == desired_format. More...
 
static struct translators translators = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 

Detailed Description

Translate via the use of pseudo channels.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file translate.c.

Macro Definition Documentation

#define MAX_RECALC   1000 /* max sample recalc */

Definition at line 47 of file translate.c.

Referenced by handle_cli_core_show_translation().

#define SHOW_TRANS   64

Enumeration Type Documentation

these values indicate how a translation path will affect the sample rate

Note
These must stay in this order. They are ordered by most optimal selection first.
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 57 of file translate.c.

57  {
58 
59  /* Lossless Source Translation Costs */
60 
61  /*! [lossless -> lossless] original sampling */
63  /*! [lossless -> lossy] original sampling */
65 
66  /*! [lossless -> lossless] up sample */
68  /*! [lossless -> lossy] up sample */
70 
71  /*! [lossless -> lossless] down sample */
73  /*! [lossless -> lossy] down sample */
75 
76  /*! [lossless -> unknown] unknown.
77  * This value is for a lossless source translation
78  * with an unknown destination and or sample rate conversion. */
80 
81  /* Lossy Source Translation Costs */
82 
83  /*! [lossy -> lossless] original sampling */
85  /*! [lossy -> lossy] original sampling */
87 
88  /*! [lossy -> lossless] up sample */
90  /*! [lossy -> lossy] up sample */
92 
93  /*! [lossy -> lossless] down sample */
95  /*! [lossy -> lossy] down sample */
97 
98  /*! [lossy -> unknown] unknown.
99  * This value is for a lossy source translation
100  * with an unknown destination and or sample rate conversion. */
101  AST_TRANS_COST_LY_UNKNOWN = 985000,
102 };

Function Documentation

int __ast_register_translator ( struct ast_translator t,
struct ast_module mod 
)

register codec translator

Register a translator This registers a codec translator with asterisk.

Definition at line 853 of file translate.c.

References ast_translator::active, ARRAY_LEN, ast_cli_register_multiple(), ast_getformatname(), ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_translator::buf_size, calc_cost(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::cost, default_frameout(), ast_translator::dstfmt, ast_translator::frameout, LOG_WARNING, MAX_FORMAT, ast_translator::module, ast_translator::name, powerof(), rebuild_matrix(), ast_translator::srcfmt, and term_color().

854 {
855  static int added_cli = 0;
856  struct ast_translator *u;
857  char tmp[80];
858 
859  if (!mod) {
860  ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
861  return -1;
862  }
863 
864  if (!t->buf_size) {
865  ast_log(LOG_WARNING, "empty buf size, you need to supply one\n");
866  return -1;
867  }
868 
869  t->module = mod;
870 
871  t->srcfmt = powerof(t->srcfmt);
872  t->dstfmt = powerof(t->dstfmt);
873  t->active = 1;
874 
875  if (t->srcfmt == -1 || t->dstfmt == -1) {
876  ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->srcfmt == -1 ? "starting" : "ending");
877  return -1;
878  }
879  if (t->srcfmt >= MAX_FORMAT) {
880  ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
881  return -1;
882  }
883 
884  if (t->dstfmt >= MAX_FORMAT) {
885  ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt));
886  return -1;
887  }
888 
889  if (t->buf_size) {
890  /*
891  * Align buf_size properly, rounding up to the machine-specific
892  * alignment for pointers.
893  */
894  struct _test_align { void *a, *b; } p;
895  int align = (char *)&p.b - (char *)&p.a;
896 
897  t->buf_size = ((t->buf_size + align - 1) / align) * align;
898  }
899 
900  if (t->frameout == NULL)
902 
903  calc_cost(t, 1);
904 
905  ast_verb(2, "Registered translator '%s' from format %s to %s, cost %d\n",
906  term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
907  ast_getformatname(1LL << t->srcfmt), ast_getformatname(1LL << t->dstfmt), t->cost);
908 
909  if (!added_cli) {
911  added_cli++;
912  }
913 
915 
916  /* find any existing translators that provide this same srcfmt/dstfmt,
917  and put this one in order based on cost */
919  if ((u->srcfmt == t->srcfmt) &&
920  (u->dstfmt == t->dstfmt) &&
921  (u->cost > t->cost)) {
923  t = NULL;
924  break;
925  }
926  }
928 
929  /* if no existing translator was found for this format combination,
930  add it to the beginning of the list */
931  if (t)
933 
934  rebuild_matrix(0);
935 
937 
938  return 0;
939 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry cli_translate[]
Definition: translate.c:848
Descriptor of a translator.
Definition: translate.h:71
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static void calc_cost(struct ast_translator *t, int seconds)
compute the cost of a single translation step
Definition: translate.c:411
static struct ast_frame * default_frameout(struct ast_trans_pvt *pvt)
Definition: translate.c:265
const char name[80]
Definition: translate.h:72
#define ast_verb(level,...)
Definition: logger.h:243
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
Definition: translate.h:85
struct ast_module * module
Definition: translate.h:110
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:595
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
Definition: translate.h:105
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
#define COLOR_BLACK
Definition: term.h:47
the list of translators
Definition: codec_dahdi.c:84
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
format_t dstfmt
Definition: translate.h:75
#define MAX_FORMAT
Definition: translate.h:28
static force_inline int powerof(format_t d)
returns the index of the lowest bit set
Definition: translate.c:130
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
format_t srcfmt
Definition: translate.h:73
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
#define COLOR_MAGENTA
Definition: term.h:57
static void rebuild_matrix(int samples)
rebuild a translation matrix.
Definition: translate.c:515
struct ast_frame* ast_trans_frameout ( struct ast_trans_pvt pvt,
int  datalen,
int  samples 
)

generic frameout routine. If samples and datalen are 0, take whatever is in pvt and reset them, otherwise take the values in the caller and leave alone the pvt values.

generic frameout function

Definition at line 235 of file translate.c.

References AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frisolate(), ast_trans_pvt::c, ast_frame_subclass::codec, ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, ast_translator::dstfmt, ast_trans_pvt::f, f, ast_frame::frametype, ast_frame::mallocd, ast_translator::name, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::samples, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_trans_pvt::t.

Referenced by default_frameout(), lintoadpcm_frameout(), lintogsm_frameout(), lintoilbc_frameout(), lintolpc10_frameout(), and lintospeex_frameout().

237 {
238  struct ast_frame *f = &pvt->f;
239 
240  if (samples)
241  f->samples = samples;
242  else {
243  if (pvt->samples == 0)
244  return NULL;
245  f->samples = pvt->samples;
246  pvt->samples = 0;
247  }
248  if (datalen)
249  f->datalen = datalen;
250  else {
251  f->datalen = pvt->datalen;
252  pvt->datalen = 0;
253  }
254 
256  f->subclass.codec = 1LL << (pvt->t->dstfmt);
257  f->mallocd = 0;
259  f->src = pvt->t->name;
260  f->data.ptr = pvt->outbuf.c;
261 
262  return ast_frisolate(f);
263 }
union ast_frame_subclass subclass
Definition: frame.h:146
int datalen
actual space used in outbuf
Definition: translate.h:140
int offset
Definition: frame.h:156
union ast_trans_pvt::@213 outbuf
void * ptr
Definition: frame.h:160
struct ast_frame f
Definition: translate.h:137
const char name[80]
Definition: translate.h:72
struct ast_frame * ast_frisolate(struct ast_frame *fr)
Makes a frame independent of any static storage.
Definition: frame.c:391
format_t codec
Definition: frame.h:137
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
const char * src
Definition: frame.h:158
int datalen
Definition: frame.h:148
format_t dstfmt
Definition: translate.h:75
static struct ast_format f[]
Definition: format_g726.c:181
int mallocd
Definition: frame.h:152
Data structure associated with a single frame of data.
Definition: frame.h:142
struct ast_translator * t
Definition: translate.h:136
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
int samples
Definition: frame.h:150
struct ast_frame* ast_translate ( struct ast_trans_pvt path,
struct ast_frame f,
int  consume 
)

do the actual translation

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 328 of file translate.c.

References ast_clear_flag, ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRFLAG_HAS_TIMING_INFO, ast_frfree, ast_samp2tv(), ast_set2_flag, ast_test_flag, ast_tv(), ast_tvadd(), ast_tveq(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_frame_subclass::codec, ast_frame::delivery, f, framein(), ast_frame::frametype, ast_frame::len, len(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, ast_frame::samples, ast_frame::seqno, ast_frame::subclass, and ast_frame::ts.

Referenced by __ast_read(), ast_audiohook_read_frame(), ast_slinfactory_feed(), ast_write(), ast_writestream(), audio_audiohook_write_list(), and conf_run().

329 {
330  struct ast_trans_pvt *p = path;
331  struct ast_frame *out = f;
332  struct timeval delivery;
333  int has_timing_info;
334  long ts;
335  long len;
336  int seqno;
337 
338  has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
339  ts = f->ts;
340  len = f->len;
341  seqno = f->seqno;
342 
343  /* XXX hmmm... check this below */
344  if (!ast_tvzero(f->delivery)) {
345  if (!ast_tvzero(path->nextin)) {
346  /* Make sure this is in line with what we were expecting */
347  if (!ast_tveq(path->nextin, f->delivery)) {
348  /* The time has changed between what we expected and this
349  most recent time on the new packet. If we have a
350  valid prediction adjust our output time appropriately */
351  if (!ast_tvzero(path->nextout)) {
352  path->nextout = ast_tvadd(path->nextout,
353  ast_tvsub(f->delivery, path->nextin));
354  }
355  path->nextin = f->delivery;
356  }
357  } else {
358  /* This is our first pass. Make sure the timing looks good */
359  path->nextin = f->delivery;
360  path->nextout = f->delivery;
361  }
362  /* Predict next incoming sample */
364  }
365  delivery = f->delivery;
366  for ( ; out && p ; p = p->next) {
367  framein(p, out);
368  if (out != f)
369  ast_frfree(out);
370  out = p->t->frameout(p);
371  }
372  if (out) {
373  /* we have a frame, play with times */
374  if (!ast_tvzero(delivery)) {
375  /* Regenerate prediction after a discontinuity */
376  if (ast_tvzero(path->nextout)) {
377  path->nextout = ast_tvnow();
378  }
379 
380  /* Use next predicted outgoing timestamp */
381  out->delivery = path->nextout;
382 
383  /* Predict next outgoing timestamp from samples in this
384  frame. */
386  if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
387  ast_debug(4, "Sample size different %d vs %d\n", f->samples, out->samples);
389  }
390  } else {
391  out->delivery = ast_tv(0, 0);
392  ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
393  if (has_timing_info) {
394  out->ts = ts;
395  out->len = len;
396  out->seqno = seqno;
397  }
398  }
399  /* Invalidate prediction if we're entering a silence period */
400  if (out->frametype == AST_FRAME_CNG) {
401  path->nextout = ast_tv(0, 0);
402  }
403  }
404  if (consume) {
405  ast_frfree(f);
406  }
407  return out;
408 }
union ast_frame_subclass subclass
Definition: frame.h:146
int seqno
Definition: frame.h:172
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_tveq(struct timeval _a, struct timeval _b)
Returns true if the two struct timeval arguments are equal.
Definition: time.h:130
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
long ts
Definition: frame.h:168
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
struct ast_trans_pvt * next
Definition: translate.h:149
format_t codec
Definition: frame.h:137
struct timeval nextin
Definition: translate.h:150
static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
Definition: translate.c:194
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:191
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct timeval nextout
Definition: translate.h:151
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static struct ast_format f[]
Definition: format_g726.c:181
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct timeval delivery
Definition: frame.h:162
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
Data structure associated with a single frame of data.
Definition: frame.h:142
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: utils.c:1601
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
long len
Definition: frame.h:170
int samples
Definition: frame.h:150
format_t ast_translate_available_formats ( format_t  dest,
format_t  src 
)

Mask off unavailable formats from a format bitmask.

Parameters
destpossible destination formats
srcsource 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
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 1081 of file translate.c.

References AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, powerof(), and tr_matrix.

Referenced by ast_rtp_instance_available_formats().

1082 {
1083  format_t res = dest;
1084  format_t x;
1085  format_t src_audio = src & AST_FORMAT_AUDIO_MASK;
1086  format_t src_video = src & AST_FORMAT_VIDEO_MASK;
1087  format_t x_bits;
1088 
1089  /* if we don't have a source format, we just have to try all
1090  possible destination formats */
1091  if (!src)
1092  return dest;
1093 
1094  /* If we have a source audio format, get its format index */
1095  if (src_audio) {
1096  src_audio = powerof(src_audio);
1097  }
1098 
1099  /* If we have a source video format, get its format index */
1100  if (src_video) {
1101  src_video = powerof(src_video);
1102  }
1103 
1104  /* Note that src_audio and src_video are guaranteed to not be
1105  * negative at this point, as we ensured they were non-zero. It is
1106  * safe to use the return value of powerof as an index into tr_matrix.
1107  */
1108 
1110 
1111  /* For a given source audio format, traverse the list of
1112  known audio formats to determine whether there exists
1113  a translation path from the source format to the
1114  destination format. */
1115  for (x = 1LL; src_audio && x > 0; x <<= 1) {
1116  if (!(x & AST_FORMAT_AUDIO_MASK)) {
1117  continue;
1118  }
1119 
1120  /* if this is not a desired format, nothing to do */
1121  if (!(dest & x))
1122  continue;
1123 
1124  /* if the source is supplying this format, then
1125  we can leave it in the result */
1126  if (src & x)
1127  continue;
1128 
1129  /* if we don't have a translation path from the src
1130  to this format, remove it from the result. Note that x_bits
1131  cannot be less than 0 as x will always have one bit set to 1 */
1132  x_bits = powerof(x);
1133  if (!tr_matrix[src_audio][x_bits].step) {
1134  res &= ~x;
1135  continue;
1136  }
1137 
1138  /* now check the opposite direction */
1139  if (!tr_matrix[x_bits][src_audio].step)
1140  res &= ~x;
1141  }
1142 
1143  /* For a given source video format, traverse the list of
1144  known video formats to determine whether there exists
1145  a translation path from the source format to the
1146  destination format. */
1147  for (x = 1LL; src_video && x > 0; x <<= 1) {
1148  if (!(x & AST_FORMAT_VIDEO_MASK)) {
1149  continue;
1150  }
1151 
1152  /* if this is not a desired format, nothing to do */
1153  if (!(dest & x))
1154  continue;
1155 
1156  /* if the source is supplying this format, then
1157  we can leave it in the result */
1158  if (src & x)
1159  continue;
1160 
1161  /* if we don't have a translation path from the src
1162  to this format, remove it from the result. Note that x_bits
1163  cannot be less than 0 as x will always have one bit set to 1 */
1164  x_bits = powerof(x);
1165  if (!tr_matrix[src_video][x_bits].step) {
1166  res &= ~x;
1167  continue;
1168  }
1169 
1170  /* now check the opposite direction */
1171  if (!tr_matrix[x_bits][src_video].step)
1172  res &= ~x;
1173  }
1174 
1176 
1177  return res;
1178 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:121
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
the list of translators
Definition: codec_dahdi.c:84
int64_t format_t
Definition: frame_defs.h:32
#define AST_FORMAT_VIDEO_MASK
Definition: frame.h:290
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
static force_inline int powerof(format_t d)
returns the index of the lowest bit set
Definition: translate.c:130
unsigned int ast_translate_path_steps ( format_t  dest,
format_t  src 
)

Returns the number of steps required to convert from 'src' to 'dest'.

Parameters
destdestination format
srcsource format
Returns
the number of translation steps required, or -1 if no path is available

Definition at line 1059 of file translate.c.

References ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, LOG_WARNING, translator_path::multistep, powerof(), and tr_matrix.

Referenced by ast_channel_make_compatible_helper().

1060 {
1061  unsigned int res = -1;
1062 
1063  /* convert bitwise format numbers into array indices */
1064  src = powerof(src);
1065  dest = powerof(dest);
1066 
1067  if (src == -1 || dest == -1) {
1068  ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src == -1 ? "starting" : "ending");
1069  return -1;
1070  }
1072 
1073  if (tr_matrix[src][dest].step)
1074  res = tr_matrix[src][dest].multistep + 1;
1075 
1077 
1078  return res;
1079 }
unsigned int multistep
Definition: translate.c:107
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:121
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
the list of translators
Definition: codec_dahdi.c:84
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static force_inline int powerof(format_t d)
returns the index of the lowest bit set
Definition: translate.c:130
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
translatorstructure containing the translation path
ast_stroutput buffer
Return values
onsuccess pointer to beginning of outbuf. on failure "".

Definition at line 630 of file translate.c.

References ast_getformatname(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_translator::dstfmt, ast_trans_pvt::next, ast_translator::srcfmt, and ast_trans_pvt::t.

Referenced by handle_showchan(), and serialize_showchan().

631 {
632  struct ast_trans_pvt *pn = p;
633 
634  if (!p || !p->t) {
635  return "";
636  }
637 
638  ast_str_set(str, 0, "%s", ast_getformatname(1LL << p->t->srcfmt));
639 
640  while ( (p = pn) ) {
641  pn = p->next;
642  ast_str_append(str, 0, "->%s", ast_getformatname(1LL << p->t->dstfmt));
643  }
644 
645  return ast_str_buffer(*str);
646 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_trans_pvt * next
Definition: translate.h:149
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
format_t dstfmt
Definition: translate.h:75
format_t srcfmt
Definition: translate.h:73
struct ast_translator * t
Definition: translate.h:136
void ast_translator_activate ( struct ast_translator t)

Activate a previously deactivated translator.

Parameters
ttranslator to activate
Returns
nothing

Enables the specified translator for use.

Definition at line 967 of file translate.c.

References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and rebuild_matrix().

968 {
970  t->active = 1;
971  rebuild_matrix(0);
973 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
the list of translators
Definition: codec_dahdi.c:84
static void rebuild_matrix(int samples)
rebuild a translation matrix.
Definition: translate.c:515
format_t ast_translator_best_choice ( format_t dst,
format_t srcs 
)

Calculate our best translator source format, given costs, and a desired destination.

Chooses the best translation path.

Definition at line 984 of file translate.c.

References AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, translator_path::cost, ast_translator::cost, MAX_AUDIO_FORMAT, translator_path::multistep, translator_path::rate_change, and tr_matrix.

Referenced by ast_channel_make_compatible_helper(), ast_request(), iax2_request(), and set_format().

985 {
986  int x,y;
987  int better = 0;
988  int besttime = INT_MAX;
989  int beststeps = INT_MAX;
990  unsigned int best_rate_change = INT_MAX;
991  format_t best = -1;
992  format_t bestdst = 0;
993  format_t cur, cursrc;
994  format_t common = ((*dst) & (*srcs)) & AST_FORMAT_AUDIO_MASK; /* are there common formats ? */
995 
996  if (common) { /* yes, pick one and return */
997  for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) {
998  if (!(cur & common)) {
999  continue;
1000  }
1001 
1002  /* We are guaranteed to find one common format. */
1003  if (best == -1) {
1004  best = cur;
1005  continue;
1006  }
1007  /* If there are multiple common formats, pick the one with the highest sample rate */
1008  if (ast_format_rate(best) < ast_format_rate(cur)) {
1009  best = cur;
1010  continue;
1011  }
1012  }
1013  /* We are done, this is a common format to both. */
1014  *srcs = *dst = best;
1015  return 0;
1016  } else { /* No, we will need to translate */
1018  for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) {
1019  if (! (cur & *dst)) {
1020  continue;
1021  }
1022  for (cursrc = 1, x = 0; x <= MAX_AUDIO_FORMAT; cursrc <<= 1, x++) {
1023  if (!(*srcs & cursrc) || !tr_matrix[x][y].step) {
1024  continue;
1025  }
1026 
1027  /* This is a better choice if any of the following are true.
1028  * 1. The sample rate conversion is better than the current pick.
1029  * 2. the sample rate conversion is no worse than the current pick and the cost or multistep is better
1030  */
1031  better = 0;
1032  if (tr_matrix[x][y].rate_change < best_rate_change) {
1033  better = 1; /* this match has a better rate conversion */
1034  }
1035  if ((tr_matrix[x][y].rate_change <= best_rate_change) &&
1036  (tr_matrix[x][y].cost < besttime || tr_matrix[x][y].multistep < beststeps)) {
1037  better = 1; /* this match has no worse rate conversion and the conversion cost is less */
1038  }
1039  if (better) {
1040  /* better than what we have so far */
1041  best = cursrc;
1042  bestdst = cur;
1043  besttime = tr_matrix[x][y].cost;
1044  beststeps = tr_matrix[x][y].multistep;
1045  best_rate_change = tr_matrix[x][y].rate_change;
1046  }
1047  }
1048  }
1050  if (best > -1) {
1051  *srcs = best;
1052  *dst = bestdst;
1053  best = 0;
1054  }
1055  return best;
1056  }
1057 }
unsigned int cost
Definition: translate.c:106
#define MAX_AUDIO_FORMAT
Definition: translate.h:27
enum path_samp_change rate_change
Definition: translate.c:108
unsigned int multistep
Definition: translate.c:107
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:121
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
the list of translators
Definition: codec_dahdi.c:84
int64_t format_t
Definition: frame_defs.h:32
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
struct ast_trans_pvt* ast_translator_build_path ( format_t  dest,
format_t  source 
)

Build a chain of translators based upon the given source and dest formats.

Builds a translator path Build a path (possibly NULL) from source to dest.

Definition at line 282 of file translate.c.

References ast_getformatname(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_free_path(), ast_tv(), ast_translator::dstfmt, LOG_WARNING, newpvt(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, powerof(), translator_path::step, ast_trans_pvt::t, and tr_matrix.

Referenced by ast_audiohook_read_frame(), ast_slinfactory_feed(), ast_writestream(), audio_audiohook_write_list(), conf_run(), and set_format().

283 {
284  struct ast_trans_pvt *head = NULL, *tail = NULL;
285 
286  source = powerof(source);
287  dest = powerof(dest);
288 
289  if (source == -1 || dest == -1) {
290  ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", source == -1 ? "starting" : "ending");
291  return NULL;
292  }
293 
295 
296  while (source != dest) {
297  struct ast_trans_pvt *cur;
298  struct ast_translator *t = tr_matrix[source][dest].step;
299  if (!t) {
300  ast_log(LOG_WARNING, "No translator path from %s to %s\n",
301  ast_getformatname(source), ast_getformatname(dest));
303  return NULL;
304  }
305  if (!(cur = newpvt(t))) {
306  ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
307  ast_getformatname(source), ast_getformatname(dest));
308  if (head)
311  return NULL;
312  }
313  if (!head)
314  head = cur;
315  else
316  tail->next = cur;
317  tail = cur;
318  cur->nextin = cur->nextout = ast_tv(0, 0);
319  /* Keep going if this isn't the final destination */
320  source = cur->t->dstfmt;
321  }
322 
324  return head;
325 }
static void * newpvt(struct ast_translator *t)
Allocate the descriptor, required outbuf space, and possibly desc.
Definition: translate.c:150
Descriptor of a translator.
Definition: translate.h:71
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct ast_trans_pvt * next
Definition: translate.h:149
struct ast_translator * step
Definition: translate.c:105
struct timeval nextin
Definition: translate.h:150
static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:121
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
the list of translators
Definition: codec_dahdi.c:84
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
struct timeval nextout
Definition: translate.h:151
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
format_t dstfmt
Definition: translate.h:75
static force_inline int powerof(format_t d)
returns the index of the lowest bit set
Definition: translate.c:130
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
struct ast_translator * t
Definition: translate.h:136
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
void ast_translator_deactivate ( struct ast_translator t)

Deactivate a translator.

Parameters
ttranslator to deactivate
Returns
nothing

Disables the specified translator from being used.

Definition at line 975 of file translate.c.

References ast_translator::active, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and rebuild_matrix().

976 {
978  t->active = 0;
979  rebuild_matrix(0);
981 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
the list of translators
Definition: codec_dahdi.c:84
static void rebuild_matrix(int samples)
rebuild a translation matrix.
Definition: translate.c:515
void ast_translator_free_path ( struct ast_trans_pvt tr)

Frees a translator path Frees the given translator path structure.

Parameters
trtranslator path to get rid of

Definition at line 272 of file translate.c.

References destroy(), and ast_trans_pvt::next.

Referenced by ast_audiohook_destroy(), ast_audiohook_detach_list(), ast_audiohook_read_frame(), ast_channel_destructor(), ast_slinfactory_destroy(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_translator_build_path(), ast_writestream(), audio_audiohook_write_list(), conf_free(), filestream_destructor(), free_translation(), and set_format().

273 {
274  struct ast_trans_pvt *pn = p;
275  while ( (p = pn) ) {
276  pn = p->next;
277  destroy(p);
278  }
279 }
struct ast_trans_pvt * next
Definition: translate.h:149
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
static void destroy(struct ast_trans_pvt *pvt)
Definition: translate.c:183
int ast_unregister_translator ( struct ast_translator t)

unregister codec translator

Unregister a translator Unregisters the given tranlator.

Definition at line 942 of file translate.c.

References ast_getformatname(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, COLOR_BLACK, COLOR_MAGENTA, ast_translator::dstfmt, ast_translator::list, ast_translator::name, rebuild_matrix(), ast_translator::srcfmt, and term_color().

Referenced by drop_translator(), load_module(), unload_module(), and unregister_translators().

943 {
944  char tmp[80];
945  struct ast_translator *u;
946  int found = 0;
947 
950  if (u == t) {
952  ast_verb(2, "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1LL << t->srcfmt), ast_getformatname(1LL << t->dstfmt));
953  found = 1;
954  break;
955  }
956  }
958 
959  if (found)
960  rebuild_matrix(0);
961 
963 
964  return (u ? 0 : -1);
965 }
Descriptor of a translator.
Definition: translate.h:71
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char name[80]
Definition: translate.h:72
#define ast_verb(level,...)
Definition: logger.h:243
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
#define COLOR_BLACK
Definition: term.h:47
the list of translators
Definition: codec_dahdi.c:84
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
format_t dstfmt
Definition: translate.h:75
format_t srcfmt
Definition: translate.h:73
struct ast_translator::@212 list
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
#define COLOR_MAGENTA
Definition: term.h:57
static void rebuild_matrix(int samples)
rebuild a translation matrix.
Definition: translate.c:515
static void calc_cost ( struct ast_translator t,
int  seconds 
)
static

compute the cost of a single translation step

Definition at line 411 of file translate.c.

References ast_format_rate(), ast_frfree, ast_log(), ast_translator::cost, destroy(), ast_translator::dstfmt, f, framein(), ast_translator::frameout, LOG_WARNING, ast_translator::name, newpvt(), ast_trans_pvt::pvt, ast_translator::sample, and ast_frame::samples.

Referenced by __ast_register_translator(), and rebuild_matrix().

412 {
413  int num_samples = 0;
414  struct ast_trans_pvt *pvt;
415  struct rusage start;
416  struct rusage end;
417  int cost;
418  int out_rate = ast_format_rate(t->dstfmt);
419 
420  if (!seconds)
421  seconds = 1;
422 
423  /* If they don't make samples, give them a terrible score */
424  if (!t->sample) {
425  ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
426  t->cost = 999999;
427  return;
428  }
429 
430  pvt = newpvt(t);
431  if (!pvt) {
432  ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
433  t->cost = 999999;
434  return;
435  }
436 
437  getrusage(RUSAGE_SELF, &start);
438 
439  /* Call the encoder until we've processed the required number of samples */
440  while (num_samples < seconds * out_rate) {
441  struct ast_frame *f = t->sample();
442  if (!f) {
443  ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
444  destroy(pvt);
445  t->cost = 999999;
446  return;
447  }
448  framein(pvt, f);
449  ast_frfree(f);
450  while ((f = t->frameout(pvt))) {
451  num_samples += f->samples;
452  ast_frfree(f);
453  }
454  }
455 
456  getrusage(RUSAGE_SELF, &end);
457 
458  cost = ((end.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000) + end.ru_utime.tv_usec - start.ru_utime.tv_usec;
459  cost += ((end.ru_stime.tv_sec - start.ru_stime.tv_sec) * 1000000) + end.ru_stime.tv_usec - start.ru_stime.tv_usec;
460 
461  destroy(pvt);
462 
463  t->cost = cost / seconds;
464 
465  if (!t->cost)
466  t->cost = 1;
467 }
struct ast_frame *(* sample)(void)
Definition: translate.h:93
static void * newpvt(struct ast_translator *t)
Allocate the descriptor, required outbuf space, and possibly desc.
Definition: translate.c:150
#define LOG_WARNING
Definition: logger.h:144
const char name[80]
Definition: translate.h:72
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
void * pvt
Definition: translate.h:141
static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
Definition: translate.c:194
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
Definition: translate.h:85
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
format_t dstfmt
Definition: translate.h:75
static void destroy(struct ast_trans_pvt *pvt)
Definition: translate.c:183
static struct ast_format f[]
Definition: format_g726.c:181
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
int samples
Definition: frame.h:150
static char* complete_trans_path_choice ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 648 of file translate.c.

References AST_FORMAT_AUDIO_MASK, ast_get_format_list(), ast_strdup, ast_format_list::bits, len(), and name.

Referenced by handle_cli_core_show_translation().

649 {
650  int which = 0;
651  int wordlen = strlen(word);
652  int i;
653  char *ret = NULL;
654  size_t len = 0;
655  const struct ast_format_list *format_list = ast_get_format_list(&len);
656 
657  for (i = 0; i < len; i++) {
658  if (!(format_list[i].bits & AST_FORMAT_AUDIO_MASK)) {
659  continue;
660  }
661  if (!strncasecmp(word, format_list[i].name, wordlen) && ++which > state) {
662  ret = ast_strdup(format_list[i].name);
663  break;
664  }
665  }
666  return ret;
667 }
#define ast_strdup(a)
Definition: astmm.h:109
struct ast_format_list * ast_get_format_list(size_t *size)
Definition: frame.c:572
Definition: ael.tab.c:203
Definition of supported media formats (codecs)
Definition: frame.h:550
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static const char name[]
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
format_t bits
Definition: frame.h:551
static struct ast_frame* default_frameout ( struct ast_trans_pvt pvt)
static

Definition at line 265 of file translate.c.

References ast_trans_frameout().

Referenced by __ast_register_translator().

266 {
267  return ast_trans_frameout(pvt, 0, 0);
268 }
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:235
static void destroy ( struct ast_trans_pvt pvt)
static

Definition at line 183 of file translate.c.

References ast_free, ast_module_unref(), ast_translator::destroy, ast_translator::module, and ast_trans_pvt::t.

Referenced by ast_translator_free_path(), and calc_cost().

184 {
185  struct ast_translator *t = pvt->t;
186 
187  if (t->destroy)
188  t->destroy(pvt);
189  ast_free(pvt);
191 }
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
Descriptor of a translator.
Definition: translate.h:71
struct ast_module * module
Definition: translate.h:110
#define ast_free(a)
Definition: astmm.h:97
struct ast_translator * t
Definition: translate.h:136
void(* destroy)(struct ast_trans_pvt *pvt)
Definition: translate.h:89
static int framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
)
static

framein wrapper, deals with bound checks.

Definition at line 194 of file translate.c.

References ast_copy_flags, AST_FRFLAG_HAS_TIMING_INFO, ast_log(), ast_translator::buffer_samples, ast_frame::datalen, ast_trans_pvt::f, ast_translator::framein, ast_frame::len, LOG_WARNING, ast_translator::name, ast_translator::native_plc, ast_trans_pvt::samples, ast_frame::samples, ast_frame::seqno, ast_trans_pvt::t, and ast_frame::ts.

Referenced by ast_translate(), and calc_cost().

195 {
196  int ret;
197  int samples = pvt->samples; /* initial value */
198 
199  /* Copy the last in jb timing info to the pvt */
201  pvt->f.ts = f->ts;
202  pvt->f.len = f->len;
203  pvt->f.seqno = f->seqno;
204 
205  if (f->samples == 0) {
206  ast_log(LOG_WARNING, "no samples for %s\n", pvt->t->name);
207  }
208  if (pvt->t->buffer_samples) { /* do not pass empty frames to callback */
209  if (f->datalen == 0) { /* perform native PLC if available */
210  /* If the codec has native PLC, then do that */
211  if (!pvt->t->native_plc)
212  return 0;
213  }
214  if (pvt->samples + f->samples > pvt->t->buffer_samples) {
215  ast_log(LOG_WARNING, "Out of buffer space\n");
216  return -1;
217  }
218  }
219  /* we require a framein routine, wouldn't know how to do
220  * it otherwise.
221  */
222  ret = pvt->t->framein(pvt, f);
223  /* diagnostic ... */
224  if (pvt->samples == samples)
225  ast_log(LOG_WARNING, "%s did not update samples %d\n",
226  pvt->t->name, pvt->samples);
227  return ret;
228 }
int seqno
Definition: frame.h:172
struct ast_frame f
Definition: translate.h:137
#define LOG_WARNING
Definition: logger.h:144
long ts
Definition: frame.h:168
const char name[80]
Definition: translate.h:72
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
int datalen
Definition: frame.h:148
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int(* framein)(struct ast_trans_pvt *pvt, struct ast_frame *in)
Definition: translate.h:81
struct ast_translator * t
Definition: translate.h:136
long len
Definition: frame.h:170
int samples
Definition: frame.h:150
int buffer_samples
size of outbuf, in samples. Leave it 0 if you want the framein callback deal with the frame...
Definition: translate.h:100
static enum path_samp_change get_rate_change_result ( format_t  src,
format_t  dst 
)
static

Definition at line 469 of file translate.c.

References ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_TRANS_COST_LL_LL_DOWNSAMP, AST_TRANS_COST_LL_LL_ORIGSAMP, AST_TRANS_COST_LL_LL_UPSAMP, AST_TRANS_COST_LL_LY_DOWNSAMP, AST_TRANS_COST_LL_LY_ORIGSAMP, AST_TRANS_COST_LL_LY_UPSAMP, AST_TRANS_COST_LL_UNKNOWN, AST_TRANS_COST_LY_LL_DOWNSAMP, AST_TRANS_COST_LY_LL_ORIGSAMP, AST_TRANS_COST_LY_LL_UPSAMP, AST_TRANS_COST_LY_LY_DOWNSAMP, AST_TRANS_COST_LY_LY_ORIGSAMP, AST_TRANS_COST_LY_LY_UPSAMP, and AST_TRANS_COST_LY_UNKNOWN.

Referenced by rebuild_matrix().

470 {
471  int src_ll = src == AST_FORMAT_SLINEAR || src == AST_FORMAT_SLINEAR16;
472  int dst_ll = dst == AST_FORMAT_SLINEAR || src == AST_FORMAT_SLINEAR16;
473  int src_rate = ast_format_rate(src);
474  int dst_rate = ast_format_rate(dst);
475 
476  if (src_ll) {
477  if (dst_ll && (src_rate == dst_rate)) {
479  } else if (!dst_ll && (src_rate == dst_rate)) {
481  } else if (dst_ll && (src_rate < dst_rate)) {
483  } else if (!dst_ll && (src_rate < dst_rate)) {
485  } else if (dst_ll && (src_rate > dst_rate)) {
487  } else if (!dst_ll && (src_rate > dst_rate)) {
489  } else {
491  }
492  } else {
493  if (dst_ll && (src_rate == dst_rate)) {
495  } else if (!dst_ll && (src_rate == dst_rate)) {
497  } else if (dst_ll && (src_rate < dst_rate)) {
499  } else if (!dst_ll && (src_rate < dst_rate)) {
501  } else if (dst_ll && (src_rate > dst_rate)) {
503  } else if (!dst_ll && (src_rate > dst_rate)) {
505  } else {
507  }
508  }
509 }
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
#define AST_FORMAT_SLINEAR16
Definition: frame.h:272
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
static char* handle_cli_core_show_translation ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 669 of file translate.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), AST_FORMAT_AUDIO_MASK, ast_format_rate(), ast_get_format_list(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_strlen_zero(), ast_format_list::bits, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_trans_path_choice(), ast_translator::cost, ast_cli_args::fd, len(), ast_cli_args::line, MAX_RECALC, ast_cli_args::n, name, ast_format_list::name, ast_cli_args::pos, powerof(), rebuild_matrix(), SHOW_TRANS, translator_path::step, str, tr_matrix, ast_cli_entry::usage, and ast_cli_args::word.

670 {
671 #define SHOW_TRANS 64
672  static const char * const option1[] = { "recalc", "paths", NULL };
673  int x, y, z;
674  int curlen = 0, longest = 0, magnitude[SHOW_TRANS] = { 0, };
675 
676  switch (cmd) {
677  case CLI_INIT:
678  e->command = "core show translation";
679  e->usage =
680  "Usage: 'core show translation' can be used in two ways.\n"
681  " 1. 'core show translation [recalc [<recalc seconds>]]\n"
682  " Displays known codec translators and the cost associated\n"
683  " with each conversion. If the argument 'recalc' is supplied along\n"
684  " with optional number of seconds to test a new test will be performed\n"
685  " as the chart is being displayed.\n"
686  " 2. 'core show translation paths [codec]'\n"
687  " This will display all the translation paths associated with a codec\n";
688  return NULL;
689  case CLI_GENERATE:
690  if (a->pos == 3) {
691  return ast_cli_complete(a->word, option1, a->n);
692  }
693  if (a->pos == 4 && !strcasecmp(a->argv[3], option1[1])) {
694  return complete_trans_path_choice(a->line, a->word, a->pos, a->n);
695  }
696  return NULL;
697  }
698 
699  if (a->argc > 5)
700  return CLI_SHOWUSAGE;
701 
702  if (a->argv[3] && !strcasecmp(a->argv[3], option1[1]) && a->argc == 5) {
703  format_t input_src = 0;
704  format_t src = 0;
705  size_t len = 0;
706  int dst;
707  int i;
708  const struct ast_format_list *format_list = ast_get_format_list(&len);
709  struct ast_str *str = ast_str_alloca(256);
710  struct ast_translator *step;
711 
712  for (i = 0; i < len; i++) {
713  if (!(format_list[i].bits & AST_FORMAT_AUDIO_MASK)) {
714  continue;
715  }
716  if (!strncasecmp(format_list[i].name, a->argv[4], strlen(format_list[i].name))) {
717  input_src = format_list[i].bits;
718  }
719  }
720 
721  if (!input_src) {
722  ast_cli(a->fd, "Source codec \"%s\" is not found.\n", a->argv[4]);
723  return CLI_FAILURE;
724  }
725 
727  ast_cli(a->fd, "--- Translation paths SRC Codec \"%s\" sample rate %d ---\n", a->argv[4], ast_format_rate(input_src));
728  for (i = 0; i < len; i++) {
729  if (!(format_list[i].bits & AST_FORMAT_AUDIO_MASK) || (format_list[i].bits == input_src)) {
730  continue;
731  }
732  /* Note that dst can never be -1, as an element of format_list will have
733  * at least one bit set. src cannot be -1 as well, as it is previously
734  * sanitized - hence it is safe to directly index tr_matrix with the results
735  * of powerof.
736  */
737  dst = powerof(format_list[i].bits);
738  src = powerof(input_src);
739  ast_str_reset(str);
740  if (tr_matrix[src][dst].step) {
741  ast_str_append(&str, 0, "%s", ast_getformatname(1LL << tr_matrix[src][dst].step->srcfmt));
742  while (src != dst) {
743  step = tr_matrix[src][dst].step;
744  if (!step) {
745  ast_str_reset(str);
746  break;
747  }
748  ast_str_append(&str, 0, "->%s", ast_getformatname(1LL << step->dstfmt));
749  src = step->dstfmt;
750  }
751  }
752 
753  if (ast_strlen_zero(ast_str_buffer(str))) {
754  ast_str_set(&str, 0, "No Translation Path");
755  }
756 
757  ast_cli(a->fd, "\t%-10.10s To %-10.10s: %-60.60s\n", a->argv[4], format_list[i].name, ast_str_buffer(str));
758  }
760 
761  return CLI_SUCCESS;
762  } else if (a->argv[3] && !strcasecmp(a->argv[3], "recalc")) {
763  z = a->argv[4] ? atoi(a->argv[4]) : 1;
764 
765  if (z <= 0) {
766  ast_cli(a->fd, " Recalc must be greater than 0. Defaulting to 1.\n");
767  z = 1;
768  }
769 
770  if (z > MAX_RECALC) {
771  ast_cli(a->fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
772  z = MAX_RECALC;
773  }
774  ast_cli(a->fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
776  rebuild_matrix(z);
778  } else if (a->argc > 3)
779  return CLI_SHOWUSAGE;
780 
782 
783  ast_cli(a->fd, " Translation times between formats (in microseconds) for one second of data\n");
784  ast_cli(a->fd, " Source Format (Rows) Destination Format (Columns)\n\n");
785  /* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
786  for (x = 0; x < SHOW_TRANS; x++) {
787  /* translation only applies to audio right now. */
788  if (!(AST_FORMAT_AUDIO_MASK & (1LL << (x))))
789  continue;
790  curlen = strlen(ast_getformatname(1LL << (x)));
791  if (curlen > longest)
792  longest = curlen;
793  for (y = 0; y < SHOW_TRANS; y++) {
794  if (!(AST_FORMAT_AUDIO_MASK & (1LL << (y))))
795  continue;
796  if (tr_matrix[x][y].cost > pow(10, magnitude[x])) {
797  magnitude[y] = floor(log10(tr_matrix[x][y].cost));
798  }
799  }
800  }
801  for (x = -1; x < SHOW_TRANS; x++) {
802  struct ast_str *out = ast_str_alloca(256);
803  /* translation only applies to audio right now. */
804  if (x >= 0 && !(AST_FORMAT_AUDIO_MASK & (1LL << (x))))
805  continue;
806  /*Go ahead and move to next iteration if dealing with an unknown codec*/
807  if(x >= 0 && !strcmp(ast_getformatname(1LL << (x)), "unknown"))
808  continue;
809  ast_str_set(&out, -1, " ");
810  for (y = -1; y < SHOW_TRANS; y++) {
811  /* translation only applies to audio right now. */
812  if (y >= 0 && !(AST_FORMAT_AUDIO_MASK & (1LL << (y))))
813  continue;
814  /*Go ahead and move to next iteration if dealing with an unknown codec*/
815  if (y >= 0 && !strcmp(ast_getformatname(1LL << (y)), "unknown"))
816  continue;
817  if (y >= 0)
818  curlen = strlen(ast_getformatname(1LL << (y)));
819  if (y >= 0 && magnitude[y] + 1 > curlen) {
820  curlen = magnitude[y] + 1;
821  }
822  if (curlen < 5)
823  curlen = 5;
824  if (x >= 0 && y >= 0 && tr_matrix[x][y].step) {
825  /* Actual codec output */
826  ast_str_append(&out, -1, "%*u", curlen + 1, tr_matrix[x][y].cost);
827  } else if (x == -1 && y >= 0) {
828  /* Top row - use a dynamic size */
829  ast_str_append(&out, -1, "%*s", curlen + 1, ast_getformatname(1LL << (y)) );
830  } else if (y == -1 && x >= 0) {
831  /* Left column - use a static size. */
832  ast_str_append(&out, -1, "%*s", longest, ast_getformatname(1LL << (x)) );
833  } else if (x >= 0 && y >= 0) {
834  /* Codec not supported */
835  ast_str_append(&out, -1, "%*s", curlen + 1, "-");
836  } else {
837  /* Upper left hand corner */
838  ast_str_append(&out, -1, "%*s", longest, "");
839  }
840  }
841  ast_str_append(&out, -1, "\n");
842  ast_cli(a->fd, "%s", ast_str_buffer(out));
843  }
845  return CLI_SUCCESS;
846 }
static char * complete_trans_path_choice(const char *line, const char *word, int pos, int state)
Definition: translate.c:648
Descriptor of a translator.
Definition: translate.h:71
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
const int argc
Definition: cli.h:154
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
#define ast_str_alloca(init_len)
Definition: strings.h:608
const char * str
Definition: app_jack.c:144
struct ast_translator * step
Definition: translate.c:105
struct ast_format_list * ast_get_format_list(size_t *size)
Definition: frame.c:572
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: cli.c:1535
Definition of supported media formats (codecs)
Definition: frame.h:550
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:121
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
char * name
Definition: frame.h:552
const char *const * argv
Definition: cli.h:155
the list of translators
Definition: codec_dahdi.c:84
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
int64_t format_t
Definition: frame_defs.h:32
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
const char * word
Definition: cli.h:157
format_t bits
Definition: frame.h:551
const char * usage
Definition: cli.h:171
#define MAX_RECALC
Definition: translate.c:47
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
#define CLI_SUCCESS
Definition: cli.h:43
static force_inline int powerof(format_t d)
returns the index of the lowest bit set
Definition: translate.c:130
const int pos
Definition: cli.h:158
#define SHOW_TRANS
static void rebuild_matrix(int samples)
rebuild a translation matrix.
Definition: translate.c:515
static void* newpvt ( struct ast_translator t)
static

Allocate the descriptor, required outbuf space, and possibly desc.

Definition at line 150 of file translate.c.

References ast_calloc, ast_free, AST_FRIENDLY_OFFSET, ast_module_ref(), ast_translator::buf_size, ast_trans_pvt::c, ast_translator::desc_size, len(), ast_translator::module, ast_translator::newpvt, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, and ast_trans_pvt::t.

Referenced by ast_translator_build_path(), and calc_cost().

151 {
152  struct ast_trans_pvt *pvt;
153  int len;
154  char *ofs;
155 
156  /*
157  * compute the required size adding private descriptor,
158  * buffer, AST_FRIENDLY_OFFSET.
159  */
160  len = sizeof(*pvt) + t->desc_size;
161  if (t->buf_size)
162  len += AST_FRIENDLY_OFFSET + t->buf_size;
163  pvt = ast_calloc(1, len);
164  if (!pvt)
165  return NULL;
166  pvt->t = t;
167  ofs = (char *)(pvt + 1); /* pointer to data space */
168  if (t->desc_size) { /* first comes the descriptor */
169  pvt->pvt = ofs;
170  ofs += t->desc_size;
171  }
172  if (t->buf_size) /* finally buffer and header */
173  pvt->outbuf.c = ofs + AST_FRIENDLY_OFFSET;
174  /* call local init routine, if present */
175  if (t->newpvt && t->newpvt(pvt)) {
176  ast_free(pvt);
177  return NULL;
178  }
180  return pvt;
181 }
union ast_trans_pvt::@213 outbuf
void * pvt
Definition: translate.h:141
struct ast_module * module
Definition: translate.h:110
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
Definition: translate.h:105
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
int(* newpvt)(struct ast_trans_pvt *)
Definition: translate.h:78
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_translator * t
Definition: translate.h:136
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
static force_inline int powerof ( format_t  d)
static

returns the index of the lowest bit set

Todo:
TODO: sample frames for each supported input format. We build this on the fly, by taking an SLIN frame and using the existing converter to play with it.

Definition at line 130 of file translate.c.

References ast_log(), ffsll(), and LOG_WARNING.

Referenced by __ast_register_translator(), ast_translate_available_formats(), ast_translate_path_steps(), ast_translator_build_path(), and handle_cli_core_show_translation().

131 {
132  int x = ffsll(d);
133 
134  if (x)
135  return x - 1;
136 
137  ast_log(LOG_WARNING, "No bits set? %llu\n", (unsigned long long) d);
138 
139  return -1;
140 }
#define LOG_WARNING
Definition: logger.h:144
int ffsll(long long n)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void rebuild_matrix ( int  samples)
static

rebuild a translation matrix.

Note
This function expects the list of translators to be locked

Definition at line 515 of file translate.c.

References ast_translator::active, ast_debug, ast_getformatname(), AST_RWLIST_TRAVERSE, calc_cost(), translator_path::cost, ast_translator::cost, ast_translator::dstfmt, get_rate_change_result(), ast_translator::list, MAX_FORMAT, translator_path::multistep, translator_path::rate_change, ast_translator::srcfmt, translator_path::step, and tr_matrix.

Referenced by __ast_register_translator(), ast_translator_activate(), ast_translator_deactivate(), ast_unregister_translator(), and handle_cli_core_show_translation().

516 {
517  struct ast_translator *t;
518  int new_rate_change;
519  int newcost;
520  int x; /* source format index */
521  int y; /* intermediate format index */
522  int z; /* destination format index */
523 
524  ast_debug(1, "Resetting translation matrix\n");
525 
526  memset(tr_matrix, '\0', sizeof(tr_matrix));
527 
528  /* first, compute all direct costs */
530  if (!t->active)
531  continue;
532 
533  x = t->srcfmt;
534  z = t->dstfmt;
535 
536  if (samples)
537  calc_cost(t, samples);
538 
539  new_rate_change = get_rate_change_result(1LL << t->srcfmt, 1LL << t->dstfmt);
540 
541  /* this translator is the best choice if any of the below are true.
542  * 1. no translation path is set between x and z yet.
543  * 2. the new translation costs less and sample rate is no worse than old one.
544  * 3. the new translation has a better sample rate conversion than the old one.
545  */
546  if (!tr_matrix[x][z].step ||
547  ((t->cost < tr_matrix[x][z].cost) && (new_rate_change <= tr_matrix[x][z].rate_change)) ||
548  (new_rate_change < tr_matrix[x][z].rate_change)) {
549 
550  tr_matrix[x][z].step = t;
551  tr_matrix[x][z].cost = t->cost;
552  tr_matrix[x][z].rate_change = new_rate_change;
553  }
554  }
555 
556  /*
557  * For each triple x, y, z of distinct formats, check if there is
558  * a path from x to z through y which is cheaper than what is
559  * currently known, and in case, update the matrix.
560  * Repeat until the matrix is stable.
561  */
562  for (;;) {
563  int changed = 0;
564  int better_choice = 0;
565  for (x = 0; x < MAX_FORMAT; x++) { /* source format */
566  for (y = 0; y < MAX_FORMAT; y++) { /* intermediate format */
567  if (x == y) /* skip ourselves */
568  continue;
569  for (z = 0; z < MAX_FORMAT; z++) { /* dst format */
570  if (z == x || z == y) /* skip null conversions */
571  continue;
572  if (!tr_matrix[x][y].step) /* no path from x to y */
573  continue;
574  if (!tr_matrix[y][z].step) /* no path from y to z */
575  continue;
576 
577  /* Does x->y->z result in a less optimal sample rate change?
578  * Never downgrade the sample rate conversion quality regardless
579  * of any cost improvements */
580  if (tr_matrix[x][z].step &&
581  ((tr_matrix[x][z].rate_change < tr_matrix[x][y].rate_change) ||
582  (tr_matrix[x][z].rate_change < tr_matrix[y][z].rate_change))) {
583  continue;
584  }
585 
586  /* is x->y->z a better sample rate confersion that the current x->z? */
587  new_rate_change = tr_matrix[x][y].rate_change + tr_matrix[y][z].rate_change;
588 
589  /* calculate cost from x->y->z */
590  newcost = tr_matrix[x][y].cost + tr_matrix[y][z].cost;
591 
592  /* Is x->y->z a better choice than x->z?
593  * There are three conditions for x->y->z to be a better choice than x->z
594  * 1. if there is no step directly between x->z then x->y->z is the best and only current option.
595  * 2. if x->y->z results in a more optimal sample rate conversion. */
596  if (!tr_matrix[x][z].step) {
597  better_choice = 1;
598  } else if (new_rate_change < tr_matrix[x][z].rate_change) {
599  better_choice = 1;
600  } else {
601  better_choice = 0;
602  }
603 
604  if (!better_choice) {
605  continue;
606  }
607  /* ok, we can get from x to z via y with a cost that
608  is the sum of the transition from x to y and from y to z */
609  tr_matrix[x][z].step = tr_matrix[x][y].step;
610  tr_matrix[x][z].cost = newcost;
611  tr_matrix[x][z].multistep = 1;
612 
613  /* now calculate what kind of sample rate change is required for this multi-step path
614  *
615  * if both paths require a change in rate, and they are not in the same direction
616  * then this is a up sample down sample conversion scenario. */
618 
619  ast_debug(10, "Discovered %u cost path from %s to %s, via %s\n", tr_matrix[x][z].cost,
620  ast_getformatname(1LL << x), ast_getformatname(1LL << z), ast_getformatname(1LL << y));
621  changed++;
622  }
623  }
624  }
625  if (!changed)
626  break;
627  }
628 }
unsigned int cost
Definition: translate.c:106
enum path_samp_change rate_change
Definition: translate.c:108
Descriptor of a translator.
Definition: translate.h:71
static enum path_samp_change get_rate_change_result(format_t src, format_t dst)
Definition: translate.c:469
unsigned int multistep
Definition: translate.c:107
static void calc_cost(struct ast_translator *t, int seconds)
compute the cost of a single translation step
Definition: translate.c:411
struct ast_translator * step
Definition: translate.c:105
static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:121
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
the list of translators
Definition: codec_dahdi.c:84
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
format_t dstfmt
Definition: translate.h:75
#define MAX_FORMAT
Definition: translate.h:28
format_t srcfmt
Definition: translate.h:73
struct ast_translator::@212 list

Variable Documentation

struct ast_cli_entry cli_translate[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_cli_core_show_translation, "Display translation matrix")
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: translate.c:669

Definition at line 848 of file translate.c.

struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]
static

a matrix that, for any pair of supported formats, indicates the total cost of translation and the first step. The full path can be reconstricted iterating on the matrix until step->dstfmt == desired_format.

Array indexes are 'src' and 'dest', in that order.

Note: the lock in the 'translators' list is also used to protect this structure.

Definition at line 121 of file translate.c.

Referenced by ast_translate_available_formats(), ast_translate_path_steps(), ast_translator_best_choice(), ast_translator_build_path(), handle_cli_core_show_translation(), and rebuild_matrix().

struct translators translators = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static