Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
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"
#include "asterisk/format.h"
#include "asterisk/linkedlists.h"
Include dependency graph for translate.c:

Go to the source code of this file.

Data Structures

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

Macros

#define format_sample_rate_absdiff(fmt1, fmt2)
 
#define GROW_INDEX   16
 
#define INIT_INDEX   32
 
#define MAX_RECALC   1000
 

Functions

int __ast_register_translator (struct ast_translator *t, struct ast_module *mod)
 register codec translator More...
 
static int add_codec2index (struct ast_codec *codec)
 
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...
 
void ast_translate_available_formats (struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result)
 Find available formats. More...
 
int ast_translate_init (void)
 Initialize the translation matrix and index to format conversion table. More...
 
unsigned int ast_translate_path_steps (struct ast_format *dst_format, struct ast_format *src_format)
 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...
 
int ast_translator_best_choice (struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, struct ast_format **dst_fmt_out, struct ast_format **src_fmt_out)
 Calculate our best translator source format, given costs, and a desired destination. More...
 
struct ast_trans_pvtast_translator_build_path (struct ast_format *dst, struct ast_format *src)
 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 check_translation_path (struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result, struct ast_format *src_fmt, enum ast_media_type type)
 
static int codec2index (struct ast_codec *codec)
 
static void codec_append_name (const struct ast_codec *codec, struct ast_str **buf)
 
static int codec_to_index (unsigned int id)
 
static char * complete_trans_path_choice (const char *word)
 
static struct ast_framedefault_frameout (struct ast_trans_pvt *pvt)
 
static void destroy (struct ast_trans_pvt *pvt)
 
static int format2index (struct ast_format *format)
 
static int framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 framein wrapper, deals with bound checks. More...
 
static void generate_computational_cost (struct ast_translator *t, int seconds)
 
static struct ast_framegenerate_interpolated_slin (struct ast_trans_pvt *p, struct ast_frame *f)
 
static int generate_table_cost (struct ast_codec *src, struct ast_codec *dst)
 
static char * handle_cli_core_show_translation (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_cli_recalc (struct ast_cli_args *a)
 
static char * handle_show_translation_path (struct ast_cli_args *a, const char *codec_name, unsigned int sample_rate)
 
static char * handle_show_translation_table (struct ast_cli_args *a)
 
static struct ast_codecindex2codec (int index)
 
static void matrix_clear (void)
 
static struct translator_pathmatrix_get (unsigned int x, unsigned int y)
 
static void matrix_rebuild (int samples)
 rebuild a translation matrix. More...
 
static int matrix_resize (int init)
 
static struct ast_trans_pvtnewpvt (struct ast_translator *t, struct ast_format *explicit_dst)
 Allocate the descriptor, required outbuf space, and possibly desc. More...
 
static void translate_shutdown (void)
 

Variables

static unsigned int * __indextable
 table for converting index to format values. More...
 
static struct translator_path ** __matrix
 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 ast_cli_entry cli_translate []
 
static int cur_max_index
 
static int index_size
 
static ast_rwlock_t tablelock
 
static struct translators translators = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 

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

◆ format_sample_rate_absdiff

#define format_sample_rate_absdiff (   fmt1,
  fmt2 
)
Value:
({ \
unsigned int rate1 = ast_format_get_sample_rate(fmt1); \
unsigned int rate2 = ast_format_get_sample_rate(fmt2); \
(rate1 > rate2 ? rate1 - rate2 : rate2 - rate1); \
})
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379

Calculate the absolute difference between sample rate of two formats.

Definition at line 1378 of file translate.c.

Referenced by ast_translator_best_choice().

◆ GROW_INDEX

#define GROW_INDEX   16

Definition at line 91 of file translate.c.

Referenced by matrix_resize().

◆ INIT_INDEX

#define INIT_INDEX   32

Definition at line 89 of file translate.c.

Referenced by matrix_resize().

◆ MAX_RECALC

#define MAX_RECALC   1000
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.

max sample recalc

Definition at line 54 of file translate.c.

Referenced by handle_cli_recalc().

Function Documentation

◆ __ast_register_translator()

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

References a, ast_translator::active, add_codec2index(), ao2_cleanup, ast_assert, ast_codec_get(), 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, b, ast_translator::buf_size, codec2index(), COLOR_BLACK, COLOR_MAGENTA, ast_translator::comp_cost, cur_max_index, default_frameout(), ast_translator::dst_codec, ast_translator::dst_fmt_index, ast_translator::frameout, generate_computational_cost(), generate_table_cost(), LOG_WARNING, matrix_rebuild(), matrix_resize(), ast_translator::module, ast_codec::name, ast_translator::name, NULL, RAII_VAR, ast_codec::sample_rate, ast_translator::src_codec, ast_translator::src_fmt_index, ast_translator::table_cost, term_color(), tmp(), and ast_codec::type.

1221 {
1222  struct ast_translator *u;
1223  char tmp[80];
1226 
1228  if (!src_codec) {
1229  ast_assert(0);
1230  ast_log(LOG_WARNING, "Failed to register translator: unknown source codec %s\n", t->src_codec.name);
1231  return -1;
1232  }
1233 
1235  if (!dst_codec) {
1236  ast_log(LOG_WARNING, "Failed to register translator: unknown destination codec %s\n", t->dst_codec.name);
1237  return -1;
1238  }
1239 
1241  if (matrix_resize(0)) {
1242  ast_log(LOG_WARNING, "Translator matrix can not represent any more translators. Out of resources.\n");
1243  return -1;
1244  }
1247  }
1248 
1249  if (!mod) {
1250  ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
1251  return -1;
1252  }
1253 
1254  if (!t->buf_size) {
1255  ast_log(LOG_WARNING, "empty buf size, you need to supply one\n");
1256  return -1;
1257  }
1259  ast_log(LOG_WARNING, "Table cost could not be generated for %s, "
1260  "Please set table_cost variable on translator.\n", t->name);
1261  return -1;
1262  }
1263 
1264  t->module = mod;
1267  t->active = 1;
1268 
1269  if (t->src_fmt_index < 0 || t->dst_fmt_index < 0) {
1270  ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->src_fmt_index < 0 ? "starting" : "ending");
1271  return -1;
1272  }
1273  if (t->src_fmt_index >= cur_max_index) {
1274  ast_log(LOG_WARNING, "Source codec %s is larger than cur_max_index\n", t->src_codec.name);
1275  return -1;
1276  }
1277 
1278  if (t->dst_fmt_index >= cur_max_index) {
1279  ast_log(LOG_WARNING, "Destination codec %s is larger than cur_max_index\n", t->dst_codec.name);
1280  return -1;
1281  }
1282 
1283  if (t->buf_size) {
1284  /*
1285  * Align buf_size properly, rounding up to the machine-specific
1286  * alignment for pointers.
1287  */
1288  struct _test_align { void *a, *b; } p;
1289  int align = (char *)&p.b - (char *)&p.a;
1290 
1291  t->buf_size = ((t->buf_size + align - 1) / align) * align;
1292  }
1293 
1294  if (t->frameout == NULL) {
1296  }
1297 
1299 
1300  ast_verb(2, "Registered translator '%s' from codec %s to %s, table cost, %d, computational cost %d\n",
1301  term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
1302  t->src_codec.name, t->dst_codec.name, t->table_cost, t->comp_cost);
1303 
1305 
1306  /* find any existing translators that provide this same srcfmt/dstfmt,
1307  and put this one in order based on computational cost */
1309  if ((u->src_fmt_index == t->src_fmt_index) &&
1310  (u->dst_fmt_index == t->dst_fmt_index) &&
1311  (u->comp_cost > t->comp_cost)) {
1313  t = NULL;
1314  break;
1315  }
1316  }
1318 
1319  /* if no existing translator was found for this codec combination,
1320  add it to the beginning of the list */
1321  if (t) {
1323  }
1324 
1325  matrix_rebuild(0);
1326 
1328 
1329  return 0;
1330 }
const char * name
Name for this codec.
Definition: codec.h:46
static int matrix_resize(int init)
Definition: translate.c:194
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Definition: translate.c:824
Descriptor of a translator.
Definition: translate.h:137
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static struct ast_frame * default_frameout(struct ast_trans_pvt *pvt)
Definition: translate.c:468
#define ast_assert(a)
Definition: utils.h:695
static int add_codec2index(struct ast_codec *codec)
Definition: translate.c:147
struct ast_codec * ast_codec_get(const char *name, enum ast_media_type type, unsigned int sample_rate)
Retrieve a codec given a name, type, and sample rate.
Definition: codec.c:326
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_module * module
Definition: translate.h:187
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:717
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:609
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
Definition: translate.h:182
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:184
#define COLOR_BLACK
Definition: term.h:47
the list of translators
Definition: codec_dahdi.c:281
struct ast_codec dst_codec
Definition: translate.h:140
static int codec2index(struct ast_codec *codec)
Definition: translate.c:124
struct ast_codec src_codec
Definition: translate.h:139
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
Definition: translate.h:158
static void generate_computational_cost(struct ast_translator *t, int seconds)
Definition: translate.c:690
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
static struct test_val b
static int cur_max_index
Definition: translate.c:94
static int generate_table_cost(struct ast_codec *src, struct ast_codec *dst)
Definition: translate.c:768
Represents a media codec within Asterisk.
Definition: codec.h:42
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
char name[80]
Definition: translate.h:138
#define COLOR_MAGENTA
Definition: term.h:57
static struct test_val a

◆ add_codec2index()

static int add_codec2index ( struct ast_codec codec)
static

Definition at line 147 of file translate.c.

References __indextable, ast_rwlock_unlock, ast_rwlock_wrlock, codec2index(), cur_max_index, ast_codec::id, and index_size.

Referenced by __ast_register_translator().

148 {
149  if (codec2index(codec) != -1) {
150  /* format is already already indexed */
151  return 0;
152  }
153 
155  if (cur_max_index == (index_size)) {
157  return -1; /* hit max length */
158  }
159  __indextable[cur_max_index] = codec->id;
160  cur_max_index++;
162 
163  return 0;
164 }
static int index_size
Definition: translate.c:96
static ast_rwlock_t tablelock
Definition: translate.c:86
unsigned int id
Internal unique identifier for this codec, set at registration time (starts at 1) ...
Definition: codec.h:44
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static int codec2index(struct ast_codec *codec)
Definition: translate.c:124
static unsigned int * __indextable
table for converting index to format values.
Definition: translate.c:83
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
static int cur_max_index
Definition: translate.c:94

◆ ast_trans_frameout()

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

References ast_frisolate, ast_trans_pvt::c, ast_frame::data, ast_frame::datalen, ast_trans_pvt::datalen, ast_trans_pvt::f, NULL, ast_trans_pvt::outbuf, ast_frame::ptr, ast_frame::samples, and ast_trans_pvt::samples.

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

440 {
441  struct ast_frame *f = &pvt->f;
442 
443  if (samples) {
444  f->samples = samples;
445  } else {
446  if (pvt->samples == 0) {
447  return NULL;
448  }
449  f->samples = pvt->samples;
450  pvt->samples = 0;
451  }
452  if (datalen) {
453  f->datalen = datalen;
454  f->data.ptr = pvt->outbuf.c;
455  } else {
456  f->datalen = pvt->datalen;
457  if (!f->datalen) {
458  f->data.ptr = NULL;
459  } else {
460  f->data.ptr = pvt->outbuf.c;
461  }
462  pvt->datalen = 0;
463  }
464 
465  return ast_frisolate(f);
466 }
int datalen
actual space used in outbuf
Definition: translate.h:218
struct ast_frame f
Definition: translate.h:215
#define NULL
Definition: resample.c:96
union ast_trans_pvt::@327 outbuf
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
Data structure associated with a single frame of data.
union ast_frame::@263 data

◆ ast_translate()

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. In case the frame type is AST_FRAME_RTCP, the frame is not translated but passed to the translator codecs via the feedback callback, and a pointer to ast_null_frame is returned after that.

Definition at line 565 of file translate.c.

References ast_clear_flag, ast_debug, ast_format_get_sample_rate(), AST_FRAME_CNG, AST_FRAME_RTCP, AST_FRFLAG_HAS_TIMING_INFO, ast_frfree, AST_LIST_NEXT, ast_null_frame, ast_samp2tv(), ast_set2_flag, ast_test_flag, ast_tv(), ast_tvadd(), ast_tveq(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_frame::delivery, ast_translator::feedback, ast_frame_subclass::format, framein(), ast_frame::frametype, generate_interpolated_slin(), ast_frame::len, len(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, out, ast_frame::samples, ast_frame::seqno, ast_frame::subclass, ast_trans_pvt::t, and ast_frame::ts.

Referenced by __ast_read(), ast_slinfactory_feed(), ast_write_stream(), ast_writestream(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), audiohook_read_frame_helper(), conf_run(), fax_gateway_framehook(), and softmix_process_write_audio().

566 {
567  struct ast_trans_pvt *p = path;
568  struct ast_frame *out;
569  struct timeval delivery;
570  int has_timing_info;
571  long ts;
572  long len;
573  int seqno;
574 
575  if (f->frametype == AST_FRAME_RTCP) {
576  /* Just pass the feedback to the right callback, if it exists.
577  * This "translation" does nothing so return a null frame. */
578  struct ast_trans_pvt *tp;
579  for (tp = p; tp; tp = tp->next) {
580  if (tp->t->feedback)
581  tp->t->feedback(tp, f);
582  }
583  return &ast_null_frame;
584  }
585 
586  has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
587  ts = f->ts;
588  len = f->len;
589  seqno = f->seqno;
590 
591  if (!ast_tvzero(f->delivery)) {
592  if (!ast_tvzero(path->nextin)) {
593  /* Make sure this is in line with what we were expecting */
594  if (!ast_tveq(path->nextin, f->delivery)) {
595  /* The time has changed between what we expected and this
596  most recent time on the new packet. If we have a
597  valid prediction adjust our output time appropriately */
598  if (!ast_tvzero(path->nextout)) {
599  path->nextout = ast_tvadd(path->nextout,
600  ast_tvsub(f->delivery, path->nextin));
601  }
602  path->nextin = f->delivery;
603  }
604  } else {
605  /* This is our first pass. Make sure the timing looks good */
606  path->nextin = f->delivery;
607  path->nextout = f->delivery;
608  }
609  /* Predict next incoming sample */
610  path->nextin = ast_tvadd(path->nextin, ast_samp2tv(
612  }
613  delivery = f->delivery;
614  for (out = f; out && p ; p = p->next) {
615  struct ast_frame *current = out;
616 
617  do {
618  framein(p, current);
619  current = AST_LIST_NEXT(current, frame_list);
620  } while (current);
621  if (out != f) {
622  ast_frfree(out);
623  }
624  out = p->t->frameout(p);
625  }
626 
627  if (!out) {
628  out = generate_interpolated_slin(path, f);
629  }
630 
631  if (out) {
632  /* we have a frame, play with times */
633  if (!ast_tvzero(delivery)) {
634  struct ast_frame *current = out;
635 
636  do {
637  /* Regenerate prediction after a discontinuity */
638  if (ast_tvzero(path->nextout)) {
639  path->nextout = ast_tvnow();
640  }
641 
642  /* Use next predicted outgoing timestamp */
643  current->delivery = path->nextout;
644 
645  /* Invalidate prediction if we're entering a silence period */
646  if (current->frametype == AST_FRAME_CNG) {
647  path->nextout = ast_tv(0, 0);
648  /* Predict next outgoing timestamp from samples in this
649  frame. */
650  } else {
651  path->nextout = ast_tvadd(path->nextout, ast_samp2tv(
652  current->samples, ast_format_get_sample_rate(current->subclass.format)));
653  }
654 
655  if (f->samples != current->samples && ast_test_flag(current, AST_FRFLAG_HAS_TIMING_INFO)) {
656  ast_debug(4, "Sample size different %d vs %d\n", f->samples, current->samples);
658  }
659  current = AST_LIST_NEXT(current, frame_list);
660  } while (current);
661  } else {
662  out->delivery = ast_tv(0, 0);
663  ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
664  if (has_timing_info) {
665  out->ts = ts;
666  out->len = len;
667  out->seqno = seqno;
668  }
669  /* Invalidate prediction if we're entering a silence period */
670  if (out->frametype == AST_FRAME_CNG) {
671  path->nextout = ast_tv(0, 0);
672  }
673  }
674  }
675  if (consume) {
676  ast_frfree(f);
677  }
678  return out;
679 }
#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:138
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
struct ast_trans_pvt * next
Definition: translate.h:227
struct timeval nextin
Definition: translate.h:228
struct ast_frame_subclass subclass
static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
Definition: translate.c:396
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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:238
void(* feedback)(struct ast_trans_pvt *pvt, struct ast_frame *feedback)
Definition: translate.h:162
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct timeval nextout
Definition: translate.h:229
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct timeval delivery
struct ast_frame ast_null_frame
Definition: main/frame.c:79
FILE * out
Definition: utils/frame.c:33
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
#define ast_frfree(fr)
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
Data structure associated with a single frame of data.
struct ast_translator * t
Definition: translate.h:214
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2298
enum ast_frame_type frametype
struct ast_format * format
static struct ast_frame * generate_interpolated_slin(struct ast_trans_pvt *p, struct ast_frame *f)
Definition: translate.c:536

◆ ast_translate_available_formats()

void ast_translate_available_formats ( struct ast_format_cap dest,
struct ast_format_cap src,
struct ast_format_cap result 
)

Find available formats.

Parameters
destpossible destination formats
srcsource formats
resultcapabilities structure to store available formats in
Returns
the destination formats that are available in the source or translatable

The result will include all formats from 'dest' that are either present in 'src' or translatable from a format present in 'src'.

Note
Only a single audio format and a single video format can be present in 'src', or the function will produce unexpected results.

Definition at line 1571 of file translate.c.

References ao2_ref, ast_format_cap_append, ast_format_cap_count(), ast_format_cap_get_compatible_format(), ast_format_cap_get_format(), AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and check_translation_path().

Referenced by ast_rtp_instance_available_formats().

1572 {
1573  struct ast_format *cur_dest, *cur_src;
1574  int index;
1575 
1576  for (index = 0; index < ast_format_cap_count(dest); ++index) {
1577  if (!(cur_dest = ast_format_cap_get_format(dest, index))) {
1578  continue;
1579  }
1580 
1581  /* We give preference to a joint format structure if possible */
1582  if ((cur_src = ast_format_cap_get_compatible_format(src, cur_dest))) {
1583  ast_format_cap_append(result, cur_src, 0);
1584  ao2_ref(cur_src, -1);
1585  } else {
1586  /* Otherwise we just use the destination format */
1587  ast_format_cap_append(result, cur_dest, 0);
1588  }
1589  ao2_ref(cur_dest, -1);
1590  }
1591 
1592  /* if we don't have a source format, we just have to try all
1593  possible destination formats */
1594  if (!src) {
1595  return;
1596  }
1597 
1598  for (index = 0; index < ast_format_cap_count(src); ++index) {
1599  if (!(cur_src = ast_format_cap_get_format(src, index))) {
1600  continue;
1601  }
1602 
1604  check_translation_path(dest, src, result,
1605  cur_src, AST_MEDIA_TYPE_AUDIO);
1606  check_translation_path(dest, src, result,
1607  cur_src, AST_MEDIA_TYPE_VIDEO);
1609  ao2_ref(cur_src, -1);
1610  }
1611 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition of a media format.
Definition: format.c:43
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_format * ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if input ast_format is within the capabilities of the ast_format_cap object then return the comp...
Definition: format_cap.c:548
static void check_translation_path(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result, struct ast_format *src_fmt, enum ast_media_type type)
Definition: translate.c:1513
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
the list of translators
Definition: codec_dahdi.c:281
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400

◆ ast_translate_init()

int ast_translate_init ( void  )

Initialize the translation matrix and index to format conversion table.

Return values
0on success
-1on failure

Definition at line 1630 of file translate.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_register_cleanup(), ast_rwlock_init, matrix_resize(), and translate_shutdown().

Referenced by asterisk_daemon().

1631 {
1632  int res = 0;
1634  res = matrix_resize(1);
1637  return res;
1638 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int matrix_resize(int init)
Definition: translate.c:194
static struct ast_cli_entry cli_translate[]
Definition: translate.c:1215
static ast_rwlock_t tablelock
Definition: translate.c:86
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
Definition: lock.h:222
static void translate_shutdown(void)
Definition: translate.c:1613

◆ ast_translate_path_steps()

unsigned int ast_translate_path_steps ( struct ast_format dest,
struct ast_format src 
)

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

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

Definition at line 1491 of file translate.c.

References ast_log, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, format2index(), LOG_WARNING, matrix_get(), translator_path::multistep, and translator_path::step.

Referenced by ast_channel_make_compatible_helper().

1492 {
1493  unsigned int res = -1;
1494  /* convert bitwise format numbers into array indices */
1495  int src = format2index(src_format);
1496  int dest = format2index(dst_format);
1497 
1498  if (src < 0 || dest < 0) {
1499  ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src < 0 ? "starting" : "ending");
1500  return -1;
1501  }
1503 
1504  if (matrix_get(src, dest)->step) {
1505  res = matrix_get(src, dest)->multistep + 1;
1506  }
1507 
1509 
1510  return res;
1511 }
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int format2index(struct ast_format *format)
Definition: translate.c:133
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_log
Definition: astobj2.c:42
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
the list of translators
Definition: codec_dahdi.c:281
uint8_t multistep
Definition: translate.c:62

◆ ast_translate_path_to_str()

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
ttranslator structure containing the translation path
strast_str output buffer
Return values
onsuccess pointer to beginning of outbuf. on failure "".

Definition at line 928 of file translate.c.

References ast_str_append(), ast_str_buffer(), ast_str_reset(), codec_append_name(), ast_translator::dst_codec, ast_trans_pvt::next, ast_translator::src_codec, and ast_trans_pvt::t.

Referenced by chan_pjsip_write_stream(), generate_status(), handle_showchan(), and serialize_showchan().

929 {
930  if (!p || !p->t) {
931  return "";
932  }
933 
934  ast_str_reset(*str);
935  codec_append_name(&p->t->src_codec, str);
936  while (p) {
937  ast_str_append(str, 0, "->");
938  codec_append_name(&p->t->dst_codec, str);
939  p = p->next;
940  }
941 
942  return ast_str_buffer(*str);
943 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
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:1091
struct ast_trans_pvt * next
Definition: translate.h:227
struct ast_codec dst_codec
Definition: translate.h:140
struct ast_codec src_codec
Definition: translate.h:139
static void codec_append_name(const struct ast_codec *codec, struct ast_str **buf)
Definition: translate.c:919
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:653
struct ast_translator * t
Definition: translate.h:214

◆ ast_translator_activate()

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

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

1362 {
1364  t->active = 1;
1365  matrix_rebuild(0);
1367 }
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Definition: translate.c:824
#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:281

◆ ast_translator_best_choice()

int ast_translator_best_choice ( struct ast_format_cap dst_cap,
struct ast_format_cap src_cap,
struct ast_format **  dst_fmt_out,
struct ast_format **  src_fmt_out 
)

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

Chooses the best translation path.

Definition at line 1385 of file translate.c.

References ao2_cleanup, ao2_ref, ao2_replace, ast_format_cap_alloc, ast_format_cap_count(), ast_format_cap_empty(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_compatible(), ast_format_cap_get_format(), ast_format_get_sample_rate(), ast_format_get_type(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, format2index(), format_sample_rate_absdiff, LOG_ERROR, matrix_get(), translator_path::multistep, NULL, RAII_VAR, translator_path::step, and translator_path::table_cost.

Referenced by ast_channel_make_compatible_helper(), iax2_request(), local_request_with_stream_topology(), request_channel(), and set_format().

1389 {
1390  unsigned int besttablecost = INT_MAX;
1391  unsigned int beststeps = INT_MAX;
1392  struct ast_format *fmt;
1393  struct ast_format *dst;
1394  struct ast_format *src;
1395  RAII_VAR(struct ast_format *, best, NULL, ao2_cleanup);
1396  RAII_VAR(struct ast_format *, bestdst, NULL, ao2_cleanup);
1397  struct ast_format_cap *joint_cap;
1398  int i;
1399  int j;
1400 
1401  if (ast_format_cap_empty(dst_cap) || ast_format_cap_empty(src_cap)) {
1402  ast_log(LOG_ERROR, "Cannot determine best translation path since one capability supports no formats\n");
1403  return -1;
1404  }
1405 
1407  if (!joint_cap) {
1408  return -1;
1409  }
1410  ast_format_cap_get_compatible(dst_cap, src_cap, joint_cap);
1411 
1412  for (i = 0; i < ast_format_cap_count(joint_cap); ++i, ao2_cleanup(fmt)) {
1413  fmt = ast_format_cap_get_format(joint_cap, i);
1414  if (!fmt
1416  continue;
1417  }
1418 
1419  if (!best
1421  ao2_replace(best, fmt);
1422  }
1423  }
1424  ao2_ref(joint_cap, -1);
1425 
1426  if (best) {
1427  ao2_replace(*dst_fmt_out, best);
1428  ao2_replace(*src_fmt_out, best);
1429  return 0;
1430  }
1431 
1432  /* need to translate */
1434  for (i = 0; i < ast_format_cap_count(dst_cap); ++i, ao2_cleanup(dst)) {
1435  dst = ast_format_cap_get_format(dst_cap, i);
1436  if (!dst
1438  continue;
1439  }
1440 
1441  for (j = 0; j < ast_format_cap_count(src_cap); ++j, ao2_cleanup(src)) {
1442  int x;
1443  int y;
1444 
1445  src = ast_format_cap_get_format(src_cap, j);
1446  if (!src
1448  continue;
1449  }
1450 
1451  x = format2index(src);
1452  y = format2index(dst);
1453  if (x < 0 || y < 0) {
1454  continue;
1455  }
1456  if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) {
1457  continue;
1458  }
1459  if (matrix_get(x, y)->table_cost < besttablecost
1460  || matrix_get(x, y)->multistep < beststeps) {
1461  /* better than what we have so far */
1462  ao2_replace(best, src);
1463  ao2_replace(bestdst, dst);
1464  besttablecost = matrix_get(x, y)->table_cost;
1465  beststeps = matrix_get(x, y)->multistep;
1466  } else if (matrix_get(x, y)->table_cost == besttablecost
1467  && matrix_get(x, y)->multistep == beststeps) {
1468  unsigned int gap_selected = format_sample_rate_absdiff(best, bestdst);
1469  unsigned int gap_current = format_sample_rate_absdiff(src, dst);
1470 
1471  if (gap_current < gap_selected) {
1472  /* better than what we have so far */
1473  ao2_replace(best, src);
1474  ao2_replace(bestdst, dst);
1475  besttablecost = matrix_get(x, y)->table_cost;
1476  beststeps = matrix_get(x, y)->multistep;
1477  }
1478  }
1479  }
1480  }
1482 
1483  if (!best) {
1484  return -1;
1485  }
1486  ao2_replace(*dst_fmt_out, bestdst);
1487  ao2_replace(*src_fmt_out, best);
1488  return 0;
1489 }
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition of a media format.
Definition: format.c:43
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
#define NULL
Definition: resample.c:96
static int format2index(struct ast_format *format)
Definition: translate.c:133
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_log
Definition: astobj2.c:42
#define format_sample_rate_absdiff(fmt1, fmt2)
Definition: translate.c:1378
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
the list of translators
Definition: codec_dahdi.c:281
#define LOG_ERROR
Definition: logger.h:285
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
uint32_t table_cost
Definition: translate.c:61
uint8_t multistep
Definition: translate.c:62
#define ao2_replace(dst, src)
Definition: astobj2.h:517
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition: format_cap.c:746
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630

◆ ast_translator_build_path()

struct ast_trans_pvt* ast_translator_build_path ( struct ast_format dst,
struct ast_format src 
)

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

References ast_format_get_name(), ast_format_get_sample_rate(), ast_format_get_type(), ast_log, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_free_path(), ast_tv(), ast_translator::dst_codec, ast_translator::dst_fmt_index, format2index(), LOG_WARNING, matrix_get(), newpvt(), ast_trans_pvt::next, ast_trans_pvt::nextin, ast_trans_pvt::nextout, NULL, ast_codec::sample_rate, translator_path::step, ast_trans_pvt::t, and ast_codec::type.

Referenced by ast_set_read_format_path(), ast_set_write_format_path(), ast_slinfactory_feed(), ast_writestream(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), audiohook_read_frame_helper(), conf_run(), set_format(), softmix_process_write_audio(), and softmix_translate_helper_change_rate().

486 {
487  struct ast_trans_pvt *head = NULL, *tail = NULL;
488  int src_index, dst_index;
489 
490  src_index = format2index(src);
491  dst_index = format2index(dst);
492 
493  if (src_index < 0 || dst_index < 0) {
494  ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src_index < 0 ? "starting" : "ending");
495  return NULL;
496  }
497 
499 
500  while (src_index != dst_index) {
501  struct ast_trans_pvt *cur;
502  struct ast_format *explicit_dst = NULL;
503  struct ast_translator *t = matrix_get(src_index, dst_index)->step;
504  if (!t) {
505  ast_log(LOG_WARNING, "No translator path from %s to %s\n",
509  return NULL;
510  }
512  explicit_dst = dst;
513  }
514  if (!(cur = newpvt(t, explicit_dst))) {
515  ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
519  return NULL;
520  }
521  if (!head) {
522  head = cur;
523  } else {
524  tail->next = cur;
525  }
526  tail = cur;
527  cur->nextin = cur->nextout = ast_tv(0, 0);
528  /* Keep going if this isn't the final destination */
529  src_index = cur->t->dst_fmt_index;
530  }
531 
533  return head;
534 }
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
Descriptor of a translator.
Definition: translate.h:137
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition of a media format.
Definition: format.c:43
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct ast_trans_pvt * next
Definition: translate.h:227
#define NULL
Definition: resample.c:96
struct ast_translator * step
Definition: translate.c:60
struct timeval nextin
Definition: translate.h:228
static int format2index(struct ast_format *format)
Definition: translate.c:133
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_log
Definition: astobj2.c:42
void ast_translator_free_path(struct ast_trans_pvt *p)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
static struct ast_trans_pvt * newpvt(struct ast_translator *t, struct ast_format *explicit_dst)
Allocate the descriptor, required outbuf space, and possibly desc.
Definition: translate.c:311
the list of translators
Definition: codec_dahdi.c:281
struct ast_codec dst_codec
Definition: translate.h:140
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
struct timeval nextout
Definition: translate.h:229
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
struct ast_translator * t
Definition: translate.h:214

◆ ast_translator_deactivate()

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

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

1370 {
1372  t->active = 0;
1373  matrix_rebuild(0);
1375 }
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Definition: translate.c:824
#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:281

◆ ast_translator_free_path()

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

References destroy(), and ast_trans_pvt::next.

Referenced by ast_audiohook_destroy(), ast_audiohook_detach_list(), ast_channel_destructor(), ast_set_read_format_path(), ast_set_write_format_path(), ast_slinfactory_destroy(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_translator_build_path(), ast_writestream(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), audiohook_read_frame_helper(), conf_free(), filestream_destructor(), free_translation(), set_format(), softmix_translate_helper_change_rate(), softmix_translate_helper_cleanup(), and softmix_translate_helper_free_entry().

476 {
477  struct ast_trans_pvt *pn = p;
478  while ( (p = pn) ) {
479  pn = p->next;
480  destroy(p);
481  }
482 }
struct ast_trans_pvt * next
Definition: translate.h:227
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
static void destroy(struct ast_trans_pvt *pvt)
Definition: translate.c:291

◆ ast_unregister_translator()

int ast_unregister_translator ( struct ast_translator t)

unregister codec translator

Unregister a translator Unregisters the given tranlator.

Definition at line 1333 of file translate.c.

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_shutting_down(), ast_verb, COLOR_BLACK, COLOR_MAGENTA, ast_translator::dst_codec, ast_translator::list, matrix_rebuild(), ast_codec::name, ast_translator::name, ast_translator::src_codec, term_color(), and tmp().

Referenced by unload_module(), and unregister_translators().

1334 {
1335  char tmp[80];
1336  struct ast_translator *u;
1337  int found = 0;
1338 
1341  if (u == t) {
1343  ast_verb(2, "Unregistered translator '%s' from codec %s to %s\n",
1344  term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
1345  t->src_codec.name, t->dst_codec.name);
1346  found = 1;
1347  break;
1348  }
1349  }
1351 
1352  if (found && !ast_shutting_down()) {
1353  matrix_rebuild(0);
1354  }
1355 
1357 
1358  return (u ? 0 : -1);
1359 }
const char * name
Name for this codec.
Definition: codec.h:46
int ast_shutting_down(void)
Definition: asterisk.c:1834
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Definition: translate.c:824
Descriptor of a translator.
Definition: translate.h:137
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static int tmp()
Definition: bt_open.c:389
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_verb(level,...)
Definition: logger.h:463
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:184
#define COLOR_BLACK
Definition: term.h:47
the list of translators
Definition: codec_dahdi.c:281
struct ast_codec dst_codec
Definition: translate.h:140
struct ast_translator::@326 list
struct ast_codec src_codec
Definition: translate.h:139
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
char name[80]
Definition: translate.h:138
#define COLOR_MAGENTA
Definition: term.h:57

◆ check_translation_path()

static void check_translation_path ( struct ast_format_cap dest,
struct ast_format_cap src,
struct ast_format_cap result,
struct ast_format src_fmt,
enum ast_media_type  type 
)
static

Definition at line 1513 of file translate.c.

References ao2_cleanup, ast_format_cap_count(), ast_format_cap_get_format(), ast_format_cap_iscompatible_format(), ast_format_cap_remove(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_type(), format2index(), matrix_get(), RAII_VAR, and translator_path::step.

Referenced by ast_translate_available_formats().

1517 {
1518  int i;
1519 
1520  if (ast_format_get_type(src_fmt) != type) {
1521  return;
1522  }
1523 
1524  /* For a given source format, traverse the list of
1525  known formats to determine whether there exists
1526  a translation path from the source format to the
1527  destination format. */
1528  for (i = ast_format_cap_count(result) - 1; 0 <= i; i--) {
1529  int index, src_index;
1530  RAII_VAR(struct ast_format *, fmt, ast_format_cap_get_format(result, i), ao2_cleanup);
1531 
1532  if (ast_format_get_type(fmt) != type) {
1533  continue;
1534  }
1535 
1536  /* if this is not a desired format, nothing to do */
1538  continue;
1539  }
1540 
1541  /* if the source is supplying this format, then
1542  we can leave it in the result */
1544  continue;
1545  }
1546 
1547  /* if this is a pass-through format, not in the source,
1548  we cannot transcode. Therefore, remove it from the result */
1549  src_index = format2index(src_fmt);
1550  index = format2index(fmt);
1551  if (src_index < 0 || index < 0) {
1552  ast_format_cap_remove(result, fmt);
1553  continue;
1554  }
1555 
1556  /* if we don't have a translation path from the src
1557  to this format, remove it from the result */
1558  if (!matrix_get(src_index, index)->step) {
1559  ast_format_cap_remove(result, fmt);
1560  continue;
1561  }
1562 
1563  /* now check the opposite direction */
1564  if (!matrix_get(index, src_index)->step) {
1565  ast_format_cap_remove(result, fmt);
1566  }
1567  }
1568 
1569 }
static const char type[]
Definition: chan_ooh323.c:109
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
Definition of a media format.
Definition: format.c:43
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
static int format2index(struct ast_format *format)
Definition: translate.c:133
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:583
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format)
Remove format capability from capability structure.
Definition: format_cap.c:497
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400

◆ codec2index()

static int codec2index ( struct ast_codec codec)
static

Definition at line 124 of file translate.c.

References codec_to_index(), and ast_codec::id.

Referenced by __ast_register_translator(), add_codec2index(), handle_show_translation_path(), and handle_show_translation_table().

125 {
126  return codec_to_index(codec->id);
127 }
unsigned int id
Internal unique identifier for this codec, set at registration time (starts at 1) ...
Definition: codec.h:44
static int codec_to_index(unsigned int id)
Definition: translate.c:104

◆ codec_append_name()

static void codec_append_name ( const struct ast_codec codec,
struct ast_str **  buf 
)
static

Definition at line 919 of file translate.c.

References ast_str_append(), ast_codec::name, and ast_codec::sample_rate.

Referenced by ast_translate_path_to_str(), and handle_show_translation_path().

920 {
921  if (codec) {
922  ast_str_append(buf, 0, "(%s@%u)", codec->name, codec->sample_rate);
923  } else {
924  ast_str_append(buf, 0, "(nothing)");
925  }
926 }
const char * name
Name for this codec.
Definition: codec.h:46
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:1091
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52

◆ codec_to_index()

static int codec_to_index ( unsigned int  id)
static

Definition at line 104 of file translate.c.

References __indextable, ast_rwlock_rdlock, ast_rwlock_unlock, and cur_max_index.

Referenced by codec2index(), and format2index().

105 {
106  int x;
107 
109  for (x = 0; x < cur_max_index; x++) {
110  if (__indextable[x] == id) {
111  /* format already exists in index2format table */
113  return x;
114  }
115  }
117  return -1; /* not found */
118 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
static ast_rwlock_t tablelock
Definition: translate.c:86
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static unsigned int * __indextable
table for converting index to format values.
Definition: translate.c:83
static int cur_max_index
Definition: translate.c:94

◆ complete_trans_path_choice()

static char* complete_trans_path_choice ( const char *  word)
static

Definition at line 945 of file translate.c.

References ao2_ref, ast_cli_completion_add(), ast_codec_get_by_id(), AST_MEDIA_TYPE_AUDIO, ast_strdup, ast_codec::name, NULL, and ast_codec::type.

Referenced by handle_cli_core_show_translation().

946 {
947  int i = 1;
948  int wordlen = strlen(word);
949  struct ast_codec *codec;
950 
951  while ((codec = ast_codec_get_by_id(i))) {
952  ++i;
953  if (codec->type != AST_MEDIA_TYPE_AUDIO) {
954  ao2_ref(codec, -1);
955  continue;
956  }
957  if (!strncasecmp(word, codec->name, wordlen)) {
958  if (ast_cli_completion_add(ast_strdup(codec->name))) {
959  ao2_ref(codec, -1);
960  break;
961  }
962  }
963  ao2_ref(codec, -1);
964  }
965 
966  return NULL;
967 }
const char * name
Name for this codec.
Definition: codec.h:46
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
Definition: codec.c:337
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726
Represents a media codec within Asterisk.
Definition: codec.h:42
short word

◆ default_frameout()

static struct ast_frame* default_frameout ( struct ast_trans_pvt pvt)
static

Definition at line 468 of file translate.c.

References ast_trans_frameout().

Referenced by __ast_register_translator().

469 {
470  return ast_trans_frameout(pvt, 0, 0);
471 }
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...
Definition: translate.c:438

◆ destroy()

static void destroy ( struct ast_trans_pvt pvt)
static

Definition at line 291 of file translate.c.

References ao2_cleanup, ao2_ref, ast_free, ast_module_unref, ast_translator::destroy, ast_trans_pvt::explicit_dst, ast_trans_pvt::f, ast_frame_subclass::format, ast_translator::module, NULL, ast_frame::subclass, and ast_trans_pvt::t.

Referenced by ast_translator_free_path(), generate_computational_cost(), newpvt(), and rtp_ioqueue_thread_remove().

292 {
293  struct ast_translator *t = pvt->t;
294 
295  if (t->destroy) {
296  t->destroy(pvt);
297  }
299  if (pvt->explicit_dst) {
300  ao2_ref(pvt->explicit_dst, -1);
301  pvt->explicit_dst = NULL;
302  }
303  ast_free(pvt);
305 }
Descriptor of a translator.
Definition: translate.h:137
struct ast_frame f
Definition: translate.h:215
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct ast_module * module
Definition: translate.h:187
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void(* destroy)(struct ast_trans_pvt *pvt)
Definition: translate.h:166
struct ast_format * explicit_dst
Definition: translate.h:237
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_translator * t
Definition: translate.h:214
struct ast_format * format

◆ format2index()

static int format2index ( struct ast_format format)
static

Definition at line 133 of file translate.c.

References ast_format_get_codec_id(), and codec_to_index().

Referenced by ast_translate_path_steps(), ast_translator_best_choice(), ast_translator_build_path(), and check_translation_path().

134 {
135  return codec_to_index(ast_format_get_codec_id(format));
136 }
static int codec_to_index(unsigned int id)
Definition: translate.c:104
unsigned int ast_format_get_codec_id(const struct ast_format *format)
Get the codec identifier associated with a format.
Definition: format.c:329

◆ framein()

static int framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
)
static

framein wrapper, deals with bound checks.

Definition at line 396 of file translate.c.

References ast_assert, ast_copy_flags, AST_FRFLAG_HAS_TIMING_INFO, ast_log, ast_translator::buffer_samples, ast_frame::datalen, ast_translator::dst_codec, ast_trans_pvt::f, ast_translator::framein, ast_frame::len, LOG_WARNING, ast_translator::name, ast_translator::native_plc, ast_codec::sample_rate, ast_frame::samples, ast_trans_pvt::samples, ast_frame::seqno, ast_frame::src, ast_translator::src_codec, ast_trans_pvt::t, and ast_frame::ts.

Referenced by ast_translate(), and generate_computational_cost().

397 {
398  /* Copy the last in jb timing info to the pvt */
400  pvt->f.ts = f->ts;
401  pvt->f.len = f->len;
402  pvt->f.seqno = f->seqno;
403 
404  if (f->samples == 0) {
405  /* Do not log empty audio frame */
406  if (!f->src || strcasecmp(f->src, "ast_prod")) {
407  ast_log(LOG_WARNING, "no samples for %s\n", pvt->t->name);
408  }
409  }
410  if (pvt->t->buffer_samples) { /* do not pass empty frames to callback */
411  int src_srate = pvt->t->src_codec.sample_rate;
412  int dst_srate = pvt->t->dst_codec.sample_rate;
413 
414  ast_assert(src_srate > 0);
415 
416  if (f->datalen == 0) { /* perform native PLC if available */
417  /* If the codec has native PLC, then do that */
418  if (!pvt->t->native_plc)
419  return 0;
420  }
421 
422  if (pvt->samples + (f->samples * dst_srate / src_srate) > pvt->t->buffer_samples) {
423  ast_log(LOG_WARNING, "Out of buffer space\n");
424  return -1;
425  }
426  }
427  /* we require a framein routine, wouldn't know how to do
428  * it otherwise.
429  */
430  return pvt->t->framein(pvt, f);
431 }
struct ast_frame f
Definition: translate.h:215
#define LOG_WARNING
Definition: logger.h:274
#define ast_assert(a)
Definition: utils.h:695
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define ast_log
Definition: astobj2.c:42
const char * src
struct ast_codec dst_codec
Definition: translate.h:140
struct ast_codec src_codec
Definition: translate.h:139
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
struct ast_translator * t
Definition: translate.h:214
char name[80]
Definition: translate.h:138
int(* framein)(struct ast_trans_pvt *pvt, struct ast_frame *in)
Definition: translate.h:154
int buffer_samples
size of outbuf, in samples. Leave it 0 if you want the framein callback deal with the frame...
Definition: translate.h:177

◆ generate_computational_cost()

static void generate_computational_cost ( struct ast_translator t,
int  seconds 
)
static

Definition at line 690 of file translate.c.

References ast_debug, ast_frfree, ast_log, ast_translator::comp_cost, destroy(), ast_translator::dst_codec, framein(), ast_translator::frameout, LOG_WARNING, ast_translator::name, newpvt(), NULL, ast_trans_pvt::pvt, ast_translator::sample, ast_codec::sample_rate, and ast_frame::samples.

Referenced by __ast_register_translator(), and matrix_rebuild().

691 {
692  int num_samples = 0;
693  struct ast_trans_pvt *pvt;
694  struct rusage start;
695  struct rusage end;
696  int cost;
697  int out_rate = t->dst_codec.sample_rate;
698 
699  if (!seconds) {
700  seconds = 1;
701  }
702 
703  /* If they don't make samples, give them a terrible score */
704  if (!t->sample) {
705  ast_debug(3, "Translator '%s' does not produce sample frames.\n", t->name);
706  t->comp_cost = 999999;
707  return;
708  }
709 
710  pvt = newpvt(t, NULL);
711  if (!pvt) {
712  ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
713  t->comp_cost = 999999;
714  return;
715  }
716 
717  getrusage(RUSAGE_SELF, &start);
718 
719  /* Call the encoder until we've processed the required number of samples */
720  while (num_samples < seconds * out_rate) {
721  struct ast_frame *f = t->sample();
722  if (!f) {
723  ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
724  destroy(pvt);
725  t->comp_cost = 999999;
726  return;
727  }
728  framein(pvt, f);
729  ast_frfree(f);
730  while ((f = t->frameout(pvt))) {
731  num_samples += f->samples;
732  ast_frfree(f);
733  }
734  }
735 
736  getrusage(RUSAGE_SELF, &end);
737 
738  cost = ((end.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000) + end.ru_utime.tv_usec - start.ru_utime.tv_usec;
739  cost += ((end.ru_stime.tv_sec - start.ru_stime.tv_sec) * 1000000) + end.ru_stime.tv_usec - start.ru_stime.tv_usec;
740 
741  destroy(pvt);
742 
743  t->comp_cost = cost / seconds;
744 
745  if (!t->comp_cost) {
746  t->comp_cost = 1;
747  }
748 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
void * pvt
Definition: translate.h:219
char * end
Definition: eagi_proxy.c:73
static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
Definition: translate.c:396
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct ast_trans_pvt * newpvt(struct ast_translator *t, struct ast_format *explicit_dst)
Allocate the descriptor, required outbuf space, and possibly desc.
Definition: translate.c:311
struct ast_codec dst_codec
Definition: translate.h:140
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
static void destroy(struct ast_trans_pvt *pvt)
Definition: translate.c:291
struct ast_frame *(* sample)(void)
Definition: translate.h:170
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
Definition: translate.h:158
#define ast_frfree(fr)
Data structure associated with a single frame of data.
char name[80]
Definition: translate.h:138

◆ generate_interpolated_slin()

static struct ast_frame* generate_interpolated_slin ( struct ast_trans_pvt p,
struct ast_frame f 
)
static

Definition at line 536 of file translate.c.

References ast_format_cache_get_slin_by_rate(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_slin, AST_FRAME_VOICE, ast_frdup, AST_FRIENDLY_OFFSET, ast_opt_generic_plc, ast_frame::data, ast_frame::datalen, ast_trans_pvt::explicit_dst, ast_frame_subclass::format, NULL, ast_frame::offset, ast_frame::ptr, ast_frame::samples, and ast_frame::subclass.

Referenced by ast_translate().

537 {
538  struct ast_frame res = { AST_FRAME_VOICE };
539 
540  /*
541  * If we've gotten here then we should have an interpolated frame that was not handled
542  * by the translation codec. So create an interpolated frame in the appropriate format
543  * that was going to be written. This frame might be handled later by other resources.
544  * For instance, generic plc.
545  *
546  * Note, generic plc is currently only available for the format type 'slin' (8KHz only -
547  * The generic plc code appears to have been based around that). Generic plc is filled
548  * in later on frame write.
549  */
550  if (!ast_opt_generic_plc || f->datalen != 0 ||
552  return NULL;
553  }
554 
555  res.subclass.format = ast_format_cache_get_slin_by_rate(8000); /* ref bumped on dup */
556  res.samples = f->samples;
557  res.datalen = 0;
558  res.data.ptr = NULL;
560 
561  return ast_frdup(&res);
562 }
#define ast_frdup(fr)
Copies a frame.
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
#define ast_opt_generic_plc
Definition: options.h:134
struct ast_format * explicit_dst
Definition: translate.h:237
Data structure associated with a single frame of data.
union ast_frame::@263 data
struct ast_format * format
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520

◆ generate_table_cost()

static int generate_table_cost ( struct ast_codec src,
struct ast_codec dst 
)
static

Definition at line 768 of file translate.c.

References AST_MEDIA_TYPE_AUDIO, 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, AST_TRANS_COST_LY_UNKNOWN, ast_codec::name, ast_codec::sample_rate, and ast_codec::type.

Referenced by __ast_register_translator().

769 {
770  int src_rate = src->sample_rate;
771  int src_ll = 0;
772  int dst_rate = dst->sample_rate;
773  int dst_ll = 0;
774 
775  if ((src->type != AST_MEDIA_TYPE_AUDIO) ||
776  (dst->type != AST_MEDIA_TYPE_AUDIO)) {
777  /* This method of generating table cost is limited to audio.
778  * Translators for media other than audio must manually set their
779  * table cost. */
780  return 0;
781  }
782 
783  src_ll = !strcmp(src->name, "slin");
784  dst_ll = !strcmp(dst->name, "slin");
785  if (src_ll) {
786  if (dst_ll && (src_rate == dst_rate)) {
788  } else if (!dst_ll && (src_rate == dst_rate)) {
790  } else if (dst_ll && (src_rate < dst_rate)) {
792  } else if (!dst_ll && (src_rate < dst_rate)) {
794  } else if (dst_ll && (src_rate > dst_rate)) {
796  } else if (!dst_ll && (src_rate > dst_rate)) {
798  } else {
800  }
801  } else {
802  if (dst_ll && (src_rate == dst_rate)) {
804  } else if (!dst_ll && (src_rate == dst_rate)) {
806  } else if (dst_ll && (src_rate < dst_rate)) {
808  } else if (!dst_ll && (src_rate < dst_rate)) {
810  } else if (dst_ll && (src_rate > dst_rate)) {
812  } else if (!dst_ll && (src_rate > dst_rate)) {
814  } else {
816  }
817  }
818 }
const char * name
Name for this codec.
Definition: codec.h:46
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50

◆ handle_cli_core_show_translation()

static char* handle_cli_core_show_translation ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1164 of file translate.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_trans_path_choice(), ast_cli_args::fd, handle_cli_recalc(), handle_show_translation_path(), handle_show_translation_table(), NULL, ast_cli_args::pos, ast_codec::sample_rate, ast_cli_entry::usage, and ast_cli_args::word.

1165 {
1166  static const char * const option[] = { "recalc", "paths", NULL };
1167 
1168  switch (cmd) {
1169  case CLI_INIT:
1170  e->command = "core show translation";
1171  e->usage =
1172  "Usage: 'core show translation' can be used in two ways.\n"
1173  " 1. 'core show translation [recalc [<recalc seconds>]]\n"
1174  " Displays known codec translators and the cost associated\n"
1175  " with each conversion. If the argument 'recalc' is supplied along\n"
1176  " with optional number of seconds to test a new test will be performed\n"
1177  " as the chart is being displayed.\n"
1178  " 2. 'core show translation paths [codec [sample_rate]]'\n"
1179  " This will display all the translation paths associated with a codec.\n"
1180  " If a codec has multiple sample rates, the sample rate must be\n"
1181  " provided as well.\n";
1182  return NULL;
1183  case CLI_GENERATE:
1184  if (a->pos == 3) {
1185  return ast_cli_complete(a->word, option, -1);
1186  }
1187  if (a->pos == 4 && !strcasecmp(a->argv[3], option[1])) {
1188  return complete_trans_path_choice(a->word);
1189  }
1190  /* BUGBUG - add tab completion for sample rates */
1191  return NULL;
1192  }
1193 
1194  if (a->argc > 6)
1195  return CLI_SHOWUSAGE;
1196 
1197  if (a->argv[3] && !strcasecmp(a->argv[3], option[1]) && a->argc == 5) { /* show paths */
1198  return handle_show_translation_path(a, a->argv[4], 0);
1199  } else if (a->argv[3] && !strcasecmp(a->argv[3], option[1]) && a->argc == 6) {
1200  unsigned int sample_rate;
1201  if (sscanf(a->argv[5], "%30u", &sample_rate) != 1) {
1202  ast_cli(a->fd, "Invalid sample rate: %s.\n", a->argv[5]);
1203  return CLI_FAILURE;
1204  }
1205  return handle_show_translation_path(a, a->argv[4], sample_rate);
1206  } else if (a->argv[3] && !strcasecmp(a->argv[3], option[0])) { /* recalc and then fall through to show table */
1207  handle_cli_recalc(a);
1208  } else if (a->argc > 3) { /* wrong input */
1209  return CLI_SHOWUSAGE;
1210  }
1211 
1213 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static void handle_cli_recalc(struct ast_cli_args *a)
Definition: translate.c:969
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
static char * handle_show_translation_path(struct ast_cli_args *a, const char *codec_name, unsigned int sample_rate)
Definition: translate.c:1099
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
static char * complete_trans_path_choice(const char *word)
Definition: translate.c:945
const int pos
Definition: cli.h:164
static char * handle_show_translation_table(struct ast_cli_args *a)
Definition: translate.c:988

◆ handle_cli_recalc()

static void handle_cli_recalc ( struct ast_cli_args a)
static

Definition at line 969 of file translate.c.

References ast_cli_args::argv, ast_cli(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cli_args::fd, matrix_rebuild(), and MAX_RECALC.

Referenced by handle_cli_core_show_translation().

970 {
971  int time = a->argv[4] ? atoi(a->argv[4]) : 1;
972 
973  if (time <= 0) {
974  ast_cli(a->fd, " Recalc must be greater than 0. Defaulting to 1.\n");
975  time = 1;
976  }
977 
978  if (time > MAX_RECALC) {
979  ast_cli(a->fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", time - MAX_RECALC, MAX_RECALC);
980  time = MAX_RECALC;
981  }
982  ast_cli(a->fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", time);
984  matrix_rebuild(time);
986 }
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Definition: translate.c:824
#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
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
the list of translators
Definition: codec_dahdi.c:281
#define MAX_RECALC
Definition: translate.c:54

◆ handle_show_translation_path()

static char* handle_show_translation_path ( struct ast_cli_args a,
const char *  codec_name,
unsigned int  sample_rate 
)
static

Definition at line 1099 of file translate.c.

References ao2_ref, ast_cli(), ast_codec_get(), ast_codec_get_by_id(), AST_MEDIA_TYPE_AUDIO, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), CLI_FAILURE, CLI_SUCCESS, codec2index(), codec_append_name(), ast_translator::dst_fmt_index, ast_cli_args::fd, matrix_get(), ast_codec::name, ast_codec::sample_rate, ast_translator::src_codec, translator_path::step, str, and ast_codec::type.

Referenced by handle_cli_core_show_translation().

1100 {
1101  int i = 1;
1102  struct ast_str *str = ast_str_alloca(1024);
1103  struct ast_translator *step;
1104  struct ast_codec *dst_codec;
1105  struct ast_codec *src_codec = ast_codec_get(codec_name, AST_MEDIA_TYPE_AUDIO, sample_rate);
1106 
1107  if (!src_codec) {
1108  ast_cli(a->fd, "Source codec \"%s\" is not found.\n", codec_name);
1109  return CLI_FAILURE;
1110  }
1111 
1113  ast_cli(a->fd, "--- Translation paths SRC Codec \"%s\" sample rate %u ---\n",
1114  codec_name, src_codec->sample_rate);
1115 
1116  while ((dst_codec = ast_codec_get_by_id(i))) {
1117  int src, dst;
1118  char src_buffer[64];
1119  char dst_buffer[64];
1120 
1121  ++i;
1122  if (src_codec == dst_codec ||
1123  dst_codec->type != AST_MEDIA_TYPE_AUDIO) {
1124  ao2_ref(dst_codec, -1);
1125  continue;
1126  }
1127 
1128  dst = codec2index(dst_codec);
1129  src = codec2index(src_codec);
1130 
1131  if (src < 0 || dst < 0) {
1132  ast_str_set(&str, 0, "No Translation Path");
1133  } else {
1134  step = matrix_get(src, dst)->step;
1135 
1136  if (step) {
1137  codec_append_name(&step->src_codec, &str);
1138  while (src != dst) {
1139  src = step->dst_fmt_index;
1140  step = matrix_get(src, dst)->step;
1141  if (!step) {
1142  ast_str_append(&str, 0, "->");
1143  codec_append_name(dst_codec, &str);
1144  break;
1145  }
1146  ast_str_append(&str, 0, "->");
1147  codec_append_name(&step->src_codec, &str);
1148  }
1149  }
1150  }
1151 
1152  snprintf(src_buffer, sizeof(src_buffer), "%s:%u", src_codec->name, src_codec->sample_rate);
1153  snprintf(dst_buffer, sizeof(dst_buffer), "%s:%u", dst_codec->name, dst_codec->sample_rate);
1154  ast_cli(a->fd, "\t%-16.16s To %-16.16s: %-60.60s\n",
1155  src_buffer, dst_buffer, ast_str_buffer(str));
1156  ast_str_reset(str);
1157  ao2_ref(dst_codec, -1);
1158  }
1160  ao2_ref(src_codec, -1);
1161  return CLI_SUCCESS;
1162 }
const char * name
Name for this codec.
Definition: codec.h:46
Descriptor of a translator.
Definition: translate.h:137
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
Definition: codec.c:337
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
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:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * str
Definition: app_jack.c:147
struct ast_codec * ast_codec_get(const char *name, enum ast_media_type type, unsigned int sample_rate)
Retrieve a codec given a name, type, and sample rate.
Definition: codec.c:326
struct ast_translator * step
Definition: translate.c:60
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
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:1065
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
the list of translators
Definition: codec_dahdi.c:281
static int codec2index(struct ast_codec *codec)
Definition: translate.c:124
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_codec src_codec
Definition: translate.h:139
static void codec_append_name(const struct ast_codec *codec, struct ast_str **buf)
Definition: translate.c:919
#define CLI_FAILURE
Definition: cli.h:46
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
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:653
#define CLI_SUCCESS
Definition: cli.h:44
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
Represents a media codec within Asterisk.
Definition: codec.h:42

◆ handle_show_translation_table()

static char* handle_show_translation_table ( struct ast_cli_args a)
static

Definition at line 988 of file translate.c.

References ao2_cleanup, ao2_ref, ast_cli(), ast_codec_get_by_id(), ast_free, AST_MEDIA_TYPE_AUDIO, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), CLI_SUCCESS, codec2index(), ast_cli_args::fd, matrix_get(), ast_codec::name, NULL, out, ast_codec::sample_rate, translator_path::step, translator_path::table_cost, and ast_codec::type.

Referenced by handle_cli_core_show_translation().

989 {
990  int x, y, i, k;
991  int longest = 7; /* slin192 */
992  int max_codec_index = 0, curlen = 0;
993  struct ast_str *out = ast_str_create(1024);
994  struct ast_codec *codec;
995 
996  /* Get the length of the longest (usable?) codec name,
997  so we know how wide the left side should be */
998  for (i = 1; (codec = ast_codec_get_by_id(i)); ao2_ref(codec, -1), ++i) {
999  ++max_codec_index;
1000  if (codec->type != AST_MEDIA_TYPE_AUDIO) {
1001  continue;
1002  }
1003  curlen = strlen(codec->name);
1004  if (curlen > longest) {
1005  longest = curlen;
1006  }
1007  }
1008 
1010  ast_cli(a->fd, " Translation times between formats (in microseconds) for one second of data\n");
1011  ast_cli(a->fd, " Source Format (Rows) Destination Format (Columns)\n\n");
1012 
1013  for (i = 0; i <= max_codec_index; i++) {
1014  struct ast_codec *row = i ? ast_codec_get_by_id(i) : NULL;
1015 
1016  x = -1;
1017  if ((i > 0) && (row->type != AST_MEDIA_TYPE_AUDIO)) {
1018  ao2_ref(row, -1);
1019  continue;
1020  }
1021 
1022  if ((i > 0) && (x = codec2index(row)) == -1) {
1023  ao2_ref(row, -1);
1024  continue;
1025  }
1026 
1027  ast_str_set(&out, 0, " ");
1028  for (k = 0; k <= max_codec_index; k++) {
1029  int adjust = 0;
1030  struct ast_codec *col = k ? ast_codec_get_by_id(k) : NULL;
1031 
1032  y = -1;
1033  if ((k > 0) && (col->type != AST_MEDIA_TYPE_AUDIO)) {
1034  ao2_ref(col, -1);
1035  continue;
1036  }
1037 
1038  if ((k > 0) && (y = codec2index(col)) == -1) {
1039  ao2_ref(col, -1);
1040  continue;
1041  }
1042 
1043  if (k > 0) {
1044  curlen = strlen(col->name);
1045  if (!strcmp(col->name, "slin") ||
1046  !strcmp(col->name, "speex") ||
1047  !strcmp(col->name, "silk")) {
1048  adjust = log10(col->sample_rate / 1000) + 1;
1049  curlen = curlen + adjust;
1050  }
1051  }
1052 
1053  if (curlen < 5) {
1054  curlen = 5;
1055  }
1056 
1057  if (x >= 0 && y >= 0 && matrix_get(x, y)->step) {
1058  /* Actual codec output */
1059  ast_str_append(&out, 0, "%*u", curlen + 1, (matrix_get(x, y)->table_cost/100));
1060  } else if (i == 0 && k > 0) {
1061  /* Top row - use a dynamic size */
1062  if (!strcmp(col->name, "slin") ||
1063  !strcmp(col->name, "speex") ||
1064  !strcmp(col->name, "silk")) {
1065  ast_str_append(&out, 0, "%*s%u", curlen - adjust + 1,
1066  col->name, col->sample_rate / 1000);
1067  } else {
1068  ast_str_append(&out, 0, "%*s", curlen + 1, col->name);
1069  }
1070  } else if (k == 0 && i > 0) {
1071  /* Left column - use a static size. */
1072  if (!strcmp(row->name, "slin") ||
1073  !strcmp(row->name, "speex") ||
1074  !strcmp(row->name, "silk")) {
1075  int adjust_row = log10(row->sample_rate / 1000) + 1;
1076  ast_str_append(&out, 0, "%*s%u", longest - adjust_row,
1077  row->name, row->sample_rate / 1000);
1078  } else {
1079  ast_str_append(&out, 0, "%*s", longest, row->name);
1080  }
1081  } else if (x >= 0 && y >= 0) {
1082  /* Codec not supported */
1083  ast_str_append(&out, 0, "%*s", curlen + 1, "-");
1084  } else {
1085  /* Upper left hand corner */
1086  ast_str_append(&out, 0, "%*s", longest, "");
1087  }
1088  ao2_cleanup(col);
1089  }
1090  ast_str_append(&out, 0, "\n");
1091  ast_cli(a->fd, "%s", ast_str_buffer(out));
1092  ao2_cleanup(row);
1093  }
1094  ast_free(out);
1096  return CLI_SUCCESS;
1097 }
const char * name
Name for this codec.
Definition: codec.h:46
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
Definition: codec.c:337
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
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:1091
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
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:1065
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
the list of translators
Definition: codec_dahdi.c:281
static int codec2index(struct ast_codec *codec)
Definition: translate.c:124
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
#define CLI_SUCCESS
Definition: cli.h:44
FILE * out
Definition: utils/frame.c:33
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
Represents a media codec within Asterisk.
Definition: codec.h:42
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ index2codec()

static struct ast_codec* index2codec ( int  index)
static

Definition at line 170 of file translate.c.

References __indextable, ast_codec_get_by_id(), ast_rwlock_rdlock, ast_rwlock_unlock, and cur_max_index.

Referenced by matrix_rebuild().

171 {
172  struct ast_codec *codec;
173 
174  if (index >= cur_max_index) {
175  return 0;
176  }
178  codec = ast_codec_get_by_id(__indextable[index]);
180 
181  return codec;
182 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
static ast_rwlock_t tablelock
Definition: translate.c:86
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
Definition: codec.c:337
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static unsigned int * __indextable
table for converting index to format values.
Definition: translate.c:83
static int cur_max_index
Definition: translate.c:94
Represents a media codec within Asterisk.
Definition: codec.h:42

◆ matrix_clear()

static void matrix_clear ( void  )
static

Definition at line 268 of file translate.c.

References index_size.

Referenced by matrix_rebuild().

269 {
270  int x;
271  for (x = 0; x < index_size; x++) {
272  memset(__matrix[x], '\0', sizeof(struct translator_path) * (index_size));
273  }
274 }
static int index_size
Definition: translate.c:96
static struct translator_path ** __matrix
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:76

◆ matrix_get()

static struct translator_path* matrix_get ( unsigned int  x,
unsigned int  y 
)
static

Definition at line 282 of file translate.c.

Referenced by ast_translate_path_steps(), ast_translator_best_choice(), ast_translator_build_path(), check_translation_path(), handle_show_translation_path(), handle_show_translation_table(), and matrix_rebuild().

283 {
284  return __matrix[x] + y;
285 }
static struct translator_path ** __matrix
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:76

◆ matrix_rebuild()

static void matrix_rebuild ( int  samples)
static

rebuild a translation matrix.

Note
This function expects the list of translators to be locked

Definition at line 824 of file translate.c.

References ast_translator::active, ao2_ref, ast_debug, ast_log, AST_RWLIST_TRAVERSE, ast_translator::comp_cost, cur_max_index, DEBUG_ATLEAST, ast_translator::dst_fmt_index, generate_computational_cost(), index2codec(), ast_translator::list, LOG_DEBUG, matrix_clear(), matrix_get(), translator_path::multistep, ast_codec::name, ast_translator::src_fmt_index, translator_path::step, translator_path::table_cost, and ast_translator::table_cost.

Referenced by __ast_register_translator(), ast_translator_activate(), ast_translator_deactivate(), ast_unregister_translator(), handle_cli_recalc(), and matrix_resize().

825 {
826  struct ast_translator *t;
827  int newtablecost;
828  int x; /* source format index */
829  int y; /* intermediate format index */
830  int z; /* destination format index */
831 
832  ast_debug(1, "Resetting translation matrix\n");
833 
834  matrix_clear();
835 
836  /* first, compute all direct costs */
838  if (!t->active) {
839  continue;
840  }
841 
842  x = t->src_fmt_index;
843  z = t->dst_fmt_index;
844 
845  if (samples) {
846  generate_computational_cost(t, samples);
847  }
848 
849  /* This new translator is the best choice if any of the below are true.
850  * 1. no translation path is set between x and z yet.
851  * 2. the new table cost is less.
852  * 3. the new computational cost is less. Computational cost is only used
853  * to break a tie between two identical translation paths.
854  */
855  if (!matrix_get(x, z)->step ||
856  (t->table_cost < matrix_get(x, z)->step->table_cost) ||
857  (t->comp_cost < matrix_get(x, z)->step->comp_cost)) {
858 
859  matrix_get(x, z)->step = t;
860  matrix_get(x, z)->table_cost = t->table_cost;
861  }
862  }
863 
864  /*
865  * For each triple x, y, z of distinct formats, check if there is
866  * a path from x to z through y which is cheaper than what is
867  * currently known, and in case, update the matrix.
868  * Repeat until the matrix is stable.
869  */
870  for (;;) {
871  int changed = 0;
872  for (x = 0; x < cur_max_index; x++) { /* source format */
873  for (y = 0; y < cur_max_index; y++) { /* intermediate format */
874  if (x == y) { /* skip ourselves */
875  continue;
876  }
877  for (z = 0; z < cur_max_index; z++) { /* dst format */
878  if ((z == x || z == y) || /* skip null conversions */
879  !matrix_get(x, y)->step || /* no path from x to y */
880  !matrix_get(y, z)->step) { /* no path from y to z */
881  continue;
882  }
883 
884  /* calculate table cost from x->y->z */
885  newtablecost = matrix_get(x, y)->table_cost + matrix_get(y, z)->table_cost;
886 
887  /* if no step already exists between x and z OR the new cost of using the intermediate
888  * step is cheaper, use this step. */
889  if (!matrix_get(x, z)->step || (newtablecost < matrix_get(x, z)->table_cost)) {
890  matrix_get(x, z)->step = matrix_get(x, y)->step;
891  matrix_get(x, z)->table_cost = newtablecost;
892  matrix_get(x, z)->multistep = 1;
893  changed++;
894 
895  if (DEBUG_ATLEAST(10)) {
896  struct ast_codec *x_codec = index2codec(x);
897  struct ast_codec *y_codec = index2codec(y);
898  struct ast_codec *z_codec = index2codec(z);
899 
901  "Discovered %u cost path from %s to %s, via %s\n",
902  matrix_get(x, z)->table_cost, x_codec->name,
903  y_codec->name, z_codec->name);
904 
905  ao2_ref(x_codec, -1);
906  ao2_ref(y_codec, -1);
907  ao2_ref(z_codec, -1);
908  }
909  }
910  }
911  }
912  }
913  if (!changed) {
914  break;
915  }
916  }
917 }
const char * name
Name for this codec.
Definition: codec.h:46
Descriptor of a translator.
Definition: translate.h:137
struct ast_translator * step
Definition: translate.c:60
#define LOG_DEBUG
Definition: logger.h:241
static void matrix_clear(void)
Definition: translate.c:268
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
Definition: translate.c:282
the list of translators
Definition: codec_dahdi.c:281
struct ast_translator::@326 list
static struct ast_codec * index2codec(int index)
Definition: translate.c:170
uint32_t table_cost
Definition: translate.c:61
uint8_t multistep
Definition: translate.c:62
static void generate_computational_cost(struct ast_translator *t, int seconds)
Definition: translate.c:690
static int cur_max_index
Definition: translate.c:94
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
Represents a media codec within Asterisk.
Definition: codec.h:42

◆ matrix_resize()

static int matrix_resize ( int  init)
static

Definition at line 194 of file translate.c.

References __indextable, ast_calloc, ast_free, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_rwlock_unlock, ast_rwlock_wrlock, GROW_INDEX, index_size, INIT_INDEX, matrix_rebuild(), and NULL.

Referenced by __ast_register_translator(), and ast_translate_init().

195 {
196  struct translator_path **tmp_matrix = NULL;
197  unsigned int *tmp_table = NULL;
198  int old_index;
199  int x;
200 
203 
204  old_index = index_size;
205  if (init) {
207  } else {
209  }
210 
211  /* make new 2d array of translator_path structures */
212  if (!(tmp_matrix = ast_calloc(1, sizeof(struct translator_path *) * (index_size)))) {
213  goto resize_cleanup;
214  }
215 
216  for (x = 0; x < index_size; x++) {
217  if (!(tmp_matrix[x] = ast_calloc(1, sizeof(struct translator_path) * (index_size)))) {
218  goto resize_cleanup;
219  }
220  }
221 
222  /* make new index table */
223  if (!(tmp_table = ast_calloc(1, sizeof(unsigned int) * index_size))) {
224  goto resize_cleanup;
225  }
226 
227  /* if everything went well this far, free the old and use the new */
228  if (!init) {
229  for (x = 0; x < old_index; x++) {
230  ast_free(__matrix[x]);
231  }
233 
234  memcpy(tmp_table, __indextable, sizeof(unsigned int) * old_index);
236  }
237 
238  /* now copy them over */
239  __matrix = tmp_matrix;
240  __indextable = tmp_table;
241 
242  matrix_rebuild(0);
245 
246  return 0;
247 
248 resize_cleanup:
251  if (tmp_matrix) {
252  for (x = 0; x < index_size; x++) {
253  ast_free(tmp_matrix[x]);
254  }
255  ast_free(tmp_matrix);
256  }
257  ast_free(tmp_table);
258 
259  return -1;
260 }
#define GROW_INDEX
Definition: translate.c:91
static int index_size
Definition: translate.c:96
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Definition: translate.c:824
static ast_rwlock_t tablelock
Definition: translate.c:86
#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
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static struct translator_path ** __matrix
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:76
the list of translators
Definition: codec_dahdi.c:281
static unsigned int * __indextable
table for converting index to format values.
Definition: translate.c:83
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
#define INIT_INDEX
Definition: translate.c:89

◆ newpvt()

static struct ast_trans_pvt* newpvt ( struct ast_translator t,
struct ast_format explicit_dst 
)
static

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

Definition at line 311 of file translate.c.

References ao2_bump, ao2_ref, ast_calloc, ast_codec_get(), ast_format_cache_get, ast_format_create(), AST_FRAME_VOICE, ast_free, AST_FRIENDLY_OFFSET, ast_log, ast_module_ref, ast_module_unref, ast_strlen_zero, ast_translator::buf_size, ast_trans_pvt::c, ast_frame::data, ast_translator::desc_size, destroy(), ast_translator::dst_codec, ast_trans_pvt::explicit_dst, ast_trans_pvt::f, ast_translator::format, ast_frame_subclass::format, ast_frame::frametype, len(), LOG_ERROR, ast_frame::mallocd, ast_translator::module, ast_codec::name, ast_translator::name, ast_translator::newpvt, NULL, ast_frame::offset, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, ast_codec::sample_rate, ast_frame::src, ast_frame::subclass, ast_trans_pvt::t, and ast_codec::type.

Referenced by ast_translator_build_path(), and generate_computational_cost().

312 {
313  struct ast_trans_pvt *pvt;
314  int len;
315  char *ofs;
316 
317  /*
318  * compute the required size adding private descriptor,
319  * buffer, AST_FRIENDLY_OFFSET.
320  */
321  len = sizeof(*pvt) + t->desc_size;
322  if (t->buf_size)
323  len += AST_FRIENDLY_OFFSET + t->buf_size;
324  pvt = ast_calloc(1, len);
325  if (!pvt) {
326  return NULL;
327  }
328  pvt->t = t;
329  ofs = (char *)(pvt + 1); /* pointer to data space */
330  if (t->desc_size) { /* first comes the descriptor */
331  pvt->pvt = ofs;
332  ofs += t->desc_size;
333  }
334  if (t->buf_size) {/* finally buffer and header */
335  pvt->outbuf.c = ofs + AST_FRIENDLY_OFFSET;
336  }
337  /*
338  * If the format has an attribute module, explicit_dst includes the (joined)
339  * result of the SDP negotiation. For example with the Opus Codec, the format
340  * knows whether both parties want to do forward-error correction (FEC).
341  */
342  pvt->explicit_dst = ao2_bump(explicit_dst);
343 
345 
346  /* call local init routine, if present */
347  if (t->newpvt && t->newpvt(pvt)) {
348  ast_free(pvt);
350  return NULL;
351  }
352 
353  /* Setup normal static translation frame. */
354  pvt->f.frametype = AST_FRAME_VOICE;
355  pvt->f.mallocd = 0;
357  pvt->f.src = pvt->t->name;
358  pvt->f.data.ptr = pvt->outbuf.c;
359 
360  /*
361  * If the translator has not provided a format
362  * A) use the joined one,
363  * B) use the cached one, or
364  * C) create one.
365  */
366  if (!pvt->f.subclass.format) {
367  pvt->f.subclass.format = ao2_bump(pvt->explicit_dst);
368 
369  if (!pvt->f.subclass.format && !ast_strlen_zero(pvt->t->format)) {
371  }
372 
373  if (!pvt->f.subclass.format) {
374  struct ast_codec *codec = ast_codec_get(t->dst_codec.name,
376  if (!codec) {
377  ast_log(LOG_ERROR, "Unable to get destination codec\n");
378  destroy(pvt);
379  return NULL;
380  }
381  pvt->f.subclass.format = ast_format_create(codec);
382  ao2_ref(codec, -1);
383  }
384 
385  if (!pvt->f.subclass.format) {
386  ast_log(LOG_ERROR, "Unable to create format\n");
387  destroy(pvt);
388  return NULL;
389  }
390  }
391 
392  return pvt;
393 }
const char * name
Name for this codec.
Definition: codec.h:46
const char * format
Definition: translate.h:143
int(* newpvt)(struct ast_trans_pvt *)
Definition: translate.h:151
struct ast_format * ast_format_create(struct ast_codec *codec)
Create a new media format.
Definition: format.c:196
struct ast_frame f
Definition: translate.h:215
struct ast_codec * ast_codec_get(const char *name, enum ast_media_type type, unsigned int sample_rate)
Retrieve a codec given a name, type, and sample rate.
Definition: codec.c:326
#define NULL
Definition: resample.c:96
void * pvt
Definition: translate.h:219
struct ast_frame_subclass subclass
#define ast_format_cache_get(name)
Definition: format_cache.h:286
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_module * module
Definition: translate.h:187
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
const char * src
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
Definition: translate.h:182
union ast_trans_pvt::@327 outbuf
struct ast_codec dst_codec
Definition: translate.h:140
#define LOG_ERROR
Definition: logger.h:285
struct ast_format * explicit_dst
Definition: translate.h:237
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void destroy(struct ast_trans_pvt *pvt)
Definition: translate.c:291
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
struct ast_translator * t
Definition: translate.h:214
union ast_frame::@263 data
enum ast_frame_type frametype
struct ast_format * format
Represents a media codec within Asterisk.
Definition: codec.h:42
char name[80]
Definition: translate.h:138
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

◆ translate_shutdown()

static void translate_shutdown ( void  )
static

Definition at line 1613 of file translate.c.

References __indextable, ARRAY_LEN, ast_cli_unregister_multiple(), ast_free, ast_rwlock_destroy, ast_rwlock_unlock, ast_rwlock_wrlock, index_size, and NULL.

Referenced by ast_translate_init().

1614 {
1615  int x;
1617 
1619  for (x = 0; x < index_size; x++) {
1620  ast_free(__matrix[x]);
1621  }
1622  ast_free(__matrix);
1623  __matrix = NULL;
1625  __indextable = NULL;
1628 }
static int index_size
Definition: translate.c:96
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry cli_translate[]
Definition: translate.c:1215
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:231
static ast_rwlock_t tablelock
Definition: translate.c:86
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static struct translator_path ** __matrix
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
Definition: translate.c:76
static unsigned int * __indextable
table for converting index to format values.
Definition: translate.c:83
#define ast_free(a)
Definition: astmm.h:182
#define ast_rwlock_wrlock(a)
Definition: lock.h:234

Variable Documentation

◆ __indextable

unsigned int* __indextable
static

table for converting index to format values.

Note
this table is protected by the table_lock.

Definition at line 83 of file translate.c.

Referenced by add_codec2index(), codec_to_index(), index2codec(), matrix_resize(), and translate_shutdown().

◆ __matrix

struct translator_path** __matrix
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 76 of file translate.c.

◆ cli_translate

struct ast_cli_entry cli_translate[]
static
Initial value:
= {
{ .handler = handle_cli_core_show_translation , .summary = "Display translation matrix" ,}
}
static char * handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: translate.c:1164

Definition at line 1215 of file translate.c.

◆ cur_max_index

int cur_max_index
static

the current largest index used by the __matrix and __indextable arrays

Definition at line 94 of file translate.c.

Referenced by __ast_register_translator(), add_codec2index(), codec_to_index(), index2codec(), and matrix_rebuild().

◆ index_size

int index_size
static

the largest index that can be used in either the __indextable or __matrix before resize must occur

Definition at line 96 of file translate.c.

Referenced by add_codec2index(), matrix_clear(), matrix_resize(), and translate_shutdown().

◆ tablelock

ast_rwlock_t tablelock
static

protects the __indextable for resizing

Definition at line 86 of file translate.c.

◆ translators

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