33#include <sys/resource.h> 
   54#define MAX_RECALC 1000 
  198    unsigned int *tmp_table = 
NULL;
 
  230        for (x = 0; x < old_index; x++) {
 
  235        memcpy(tmp_table, 
__indextable, 
sizeof(
unsigned int) * old_index);
 
 
  330    ofs = (
char *)(
pvt + 1);    
 
  358    pvt->f.src = 
pvt->t->name;
 
  359    pvt->f.data.ptr = 
pvt->outbuf.c;
 
  367    if (!
pvt->f.subclass.format) {
 
  374        if (!
pvt->f.subclass.format) {
 
 
  407        if (!f->
src || strcasecmp(f->
src, 
"ast_prod")) {
 
 
  489    int src_index, dst_index;
 
  494    if (src_index < 0 || dst_index < 0) {
 
  495        ast_log(
LOG_WARNING, 
"No translator path: (%s codec is not valid)\n", src_index < 0 ? 
"starting" : 
"ending");
 
  501    while (src_index != dst_index) {
 
  515        if (!(cur = 
newpvt(t, explicit_dst))) {
 
 
  570    struct timeval delivery;
 
  580        for (tp = p; tp; tp = tp->
next) {
 
  665            if (has_timing_info) {
 
 
  706        ast_debug(3, 
"Translator '%s' does not produce sample frames.\n", t->
name);
 
  718    getrusage(RUSAGE_SELF, &start);
 
  721    while (num_samples < seconds * out_rate) {
 
  737    getrusage(RUSAGE_SELF, &
end);
 
  739    cost = ((
end.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000) + 
end.ru_utime.tv_usec - start.ru_utime.tv_usec;
 
  740    cost += ((
end.ru_stime.tv_sec - start.ru_stime.tv_sec) * 1000000) + 
end.ru_stime.tv_usec - start.ru_stime.tv_usec;
 
 
  771    int src_rate = 
src->sample_rate;
 
  784    src_ll = !strcmp(
src->name, 
"slin");
 
  785    dst_ll = !strcmp(dst->
name, 
"slin");
 
  787        if (dst_ll && (src_rate == dst_rate)) {
 
  789        } 
else if (!dst_ll && (src_rate == dst_rate)) {
 
  791        } 
else if (dst_ll && (src_rate < dst_rate)) {
 
  793        } 
else if (!dst_ll && (src_rate < dst_rate)) {
 
  795        } 
else if (dst_ll && (src_rate > dst_rate)) {
 
  797        } 
else if (!dst_ll && (src_rate > dst_rate)) {
 
  803        if (dst_ll && (src_rate == dst_rate)) {
 
  805        } 
else if (!dst_ll && (src_rate == dst_rate)) {
 
  807        } 
else if (dst_ll && (src_rate < dst_rate)) {
 
  809        } 
else if (!dst_ll && (src_rate < dst_rate)) {
 
  811        } 
else if (dst_ll && (src_rate > dst_rate)) {
 
  813        } 
else if (!dst_ll && (src_rate > dst_rate)) {
 
 
  833    ast_debug(1, 
"Resetting translation matrix\n");
 
  880                    if ((z == x || z == y) ||        
 
  903                                "Discovered %u cost path from %s to %s, via %s\n",
 
 
  950    int wordlen = strlen(
word);
 
  959        if (!strncasecmp(
word, codec->
name, wordlen)) {
 
 
  973    int time = 
a->argv[4] ? atoi(
a->argv[4]) : 1;
 
  976        ast_cli(
a->fd, 
"         Recalc must be greater than 0.  Defaulting to 1.\n");
 
  984    ast_cli(
a->fd, 
"         Recalculating Codec Translation (number of sample seconds: %d)\n\n", time);
 
 
  992    int x, y, i, k, compCost;
 
  994    int max_codec_index = 0, curlen = 0;
 
 1005        curlen = strlen(codec->
name);
 
 1006        if (curlen > longest) {
 
 1012    ast_cli(
a->fd, 
"         Translation times between formats (in microseconds) for one second of data\n");
 
 1013    ast_cli(
a->fd, 
"          Source Format (Rows) Destination Format (Columns)\n\n");
 
 1015    for (i = 0; i <= max_codec_index; i++) {
 
 1030        for (k = 0; k <= max_codec_index; k++) {
 
 1046                curlen = strlen(col->
name);
 
 1047                if (!strcmp(col->
name, 
"slin") ||
 
 1048                    !strcmp(col->
name, 
"speex") ||
 
 1049                    !strcmp(col->
name, 
"silk")) {
 
 1051                    curlen = curlen + adjust;
 
 1059            if (x >= 0 && y >= 0 && 
matrix_get(x, y)->step) {
 
 1061                if (
a->argv[3] && !strcasecmp(
a->argv[3], 
"comp")) {
 
 1063                    if (compCost == 0 || compCost == 999999) {
 
 1071            } 
else if (i == 0 && k > 0) {
 
 1073                if (!strcmp(col->
name, 
"slin") ||
 
 1074                    !strcmp(col->
name, 
"speex") ||
 
 1075                    !strcmp(col->
name, 
"silk")) {
 
 1081            } 
else if (k == 0 && i > 0) {
 
 1083                if (!strcmp(row->
name, 
"slin") ||
 
 1084                    !strcmp(row->
name, 
"speex") ||
 
 1085                    !strcmp(row->
name, 
"silk")) {
 
 1086                    int adjust_row = log10(row->
sample_rate / 1000) + 1;
 
 1092            } 
else if (x >= 0 && y >= 0) {
 
 
 1119        ast_cli(
a->fd, 
"Source codec \"%s\" is not found.\n", codec_name);
 
 1124    ast_cli(
a->fd, 
"--- Translation paths SRC Codec \"%s\" sample rate %u ---\n",
 
 1129        char src_buffer[64];
 
 1130        char dst_buffer[64];
 
 1133        if (src_codec == dst_codec ||
 
 1142        if (src < 0 || dst < 0) {
 
 1149                while (src != dst) {
 
 1163        snprintf(src_buffer, 
sizeof(src_buffer), 
"%s:%u", src_codec->
name, src_codec->
sample_rate);
 
 1164        snprintf(dst_buffer, 
sizeof(dst_buffer), 
"%s:%u", dst_codec->
name, dst_codec->
sample_rate);
 
 1165        ast_cli(
a->fd, 
"\t%-16.16s To %-16.16s: %-60.60s\n",
 
 
 1177    static const char * 
const option[] = { 
"recalc", 
"paths", 
"comp", 
NULL };
 
 1181        e->
command = 
"core show translation";
 
 1183            "Usage: 'core show translation' can be used in three ways.\n" 
 1184            "       1. 'core show translation [recalc [<recalc seconds>]\n" 
 1185            "          Displays known codec translators and the cost associated\n" 
 1186            "          with each conversion.  If the argument 'recalc' is supplied along\n" 
 1187            "          with optional number of seconds to test a new test will be performed\n" 
 1188            "          as the chart is being displayed.\n" 
 1189            "       2. 'core show translation paths [codec [sample_rate]]'\n" 
 1190            "           This will display all the translation paths associated with a codec.\n" 
 1191            "           If a codec has multiple sample rates, the sample rate must be\n" 
 1192            "           provided as well.\n" 
 1193            "       3. 'core show translation comp [<recalc seconds>]'\n" 
 1194            "          Displays known codec translators and the cost associated\n" 
 1195            "          with each conversion.  If the argument 'recalc' is supplied along\n" 
 1196            "          with optional number of seconds to test a new test will be performed\n" 
 1197            "          as the chart is being displayed. The resulting numbers in the table\n" 
 1198            "          give the actual computational costs in microseconds.\n";
 
 1204        if (
a->pos == 4 && !strcasecmp(
a->argv[3], option[1])) {
 
 1214    if (
a->argv[3] && !strcasecmp(
a->argv[3], option[1]) && 
a->argc == 5) { 
 
 1216    } 
else if (
a->argv[3] && !strcasecmp(
a->argv[3], option[1]) && 
a->argc == 6) {
 
 1219            ast_cli(
a->fd, 
"Invalid sample rate: %s.\n", 
a->argv[5]);
 
 1223    } 
else if (
a->argv[3] && (!strcasecmp(
a->argv[3], option[0]) || !strcasecmp(
a->argv[3], option[2]))) { 
 
 1225    } 
else if (
a->argc > 3) { 
 
 
 1259            ast_log(
LOG_WARNING, 
"Translator matrix can not represent any more translators.  Out of resources.\n");
 
 1277            "Please set table_cost variable on translator.\n", t->
name);
 
 1305        struct _test_align { 
void *
a, *
b; } p;
 
 1306        int align = (
char *)&p.b - (
char *)&p.a;
 
 1317    ast_verb(5, 
"Registered translator '%s' from codec %s to %s, table cost, %d, computational cost %d\n",
 
 
 1360            ast_verb(5, 
"Unregistered translator '%s' from codec %s to %s\n",
 
 1375    return (u ? 0 : -1);
 
 
 1395#define format_sample_rate_absdiff(fmt1, fmt2) ({ \ 
 1396    unsigned int rate1 = ast_format_get_sample_rate(fmt1); \ 
 1397    unsigned int rate2 = ast_format_get_sample_rate(fmt2); \ 
 1398    (rate1 > rate2 ? rate1 - rate2 : rate2 - rate1); \ 
 
 1407    unsigned int besttablecost = INT_MAX;
 
 1408    unsigned int beststeps = INT_MAX;
 
 1419        ast_log(
LOG_ERROR, 
"Cannot determine best translation path since one capability supports no formats\n");
 
 1470            if (x < 0 || y < 0) {
 
 1476            if (
matrix_get(x, y)->table_cost < besttablecost
 
 1477                || 
matrix_get(x, y)->multistep < beststeps) {
 
 1483            } 
else if (
matrix_get(x, y)->table_cost == besttablecost
 
 1484                    && 
matrix_get(x, y)->multistep == beststeps) {
 
 1489                if (gap_current < gap_selected) {
 
 1492                } 
else if (gap_current == gap_selected) {
 
 1493                    int src_quality, best_quality;
 
 1494                    struct ast_codec *src_codec, *best_codec;
 
 1498                    src_quality = src_codec->
quality;
 
 1499                    best_quality = best_codec->
quality;
 
 1505                    if (src_quality > best_quality) {
 
 1513                        ast_debug(1, 
"Completely ambiguous tie between formats %s and %s (quality %d): sticking with %s, but this is arbitrary\n",
 
 
 1538    unsigned int res = -1;
 
 1543    if (src < 0 || dest < 0) {
 
 1544        ast_log(
LOG_WARNING, 
"No translator path: (%s codec is not valid)\n", src < 0 ? 
"starting" : 
"ending");
 
 
 1574        int index, src_index;
 
 1596        if (src_index < 0 || index < 0) {
 
 
void ast_cli_unregister_multiple(void)
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
int ast_shutting_down(void)
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
General Asterisk PBX channel definitions.
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
void ast_cli(int fd, const char *fmt,...)
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
ast_media_type
Types of media.
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.
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Asterisk internal frame definitions.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
@ AST_FRFLAG_HAS_TIMING_INFO
#define ast_frdup(fr)
Copies a frame.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
struct ast_frame ast_null_frame
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
A set of macros to manage forward-linked lists.
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
#define AST_RWLIST_TRAVERSE_SAFE_END
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_HEAD
#define AST_RWLIST_INSERT_BEFORE_CURRENT
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Asterisk locking-related definitions:
#define ast_rwlock_wrlock(a)
#define ast_rwlock_rdlock(a)
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
#define ast_rwlock_destroy(rwlock)
#define ast_rwlock_unlock(a)
Asterisk module definitions.
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_module_ref(mod)
Hold a reference to the module.
#define ast_opt_generic_plc
Scheduler Routines (derived from cheops)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_alloca(init_len)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
descriptor for a cli entry.
Represents a media codec within Asterisk.
unsigned int sample_rate
Sample rate (number of samples carried in a second)
enum ast_media_type type
Type of media this codec contains.
unsigned int quality
Format quality, on scale from 0 to 150 (100 is ulaw, the reference). This allows better format to be ...
const char * name
Name for this codec.
unsigned int id
Internal unique identifier for this codec, set at registration time (starts at 1)
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@239 data
Structure for rwlock and tracking information.
Support for dynamic strings.
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
union ast_trans_pvt::@308 outbuf
struct ast_trans_pvt * next
struct ast_translator * t
struct ast_format * explicit_dst
int datalen
actual space used in outbuf
Descriptor of a translator.
struct ast_module *int active
void(* destroy)(struct ast_trans_pvt *pvt)
struct ast_frame *(* sample)(void)
struct ast_translator::@307 list
void(* feedback)(struct ast_trans_pvt *pvt, struct ast_frame *feedback)
int buffer_samples
size of outbuf, in samples. Leave it 0 if you want the framein callback deal with the frame....
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
int(* framein)(struct ast_trans_pvt *pvt, struct ast_frame *in)
struct ast_codec src_codec
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
int(* newpvt)(struct ast_trans_pvt *)
struct ast_codec dst_codec
struct ast_translator * step
Handy terminal functions for vt* terms.
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
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 ...
int ast_tveq(struct timeval _a, struct timeval _b)
Returns true if the two struct timeval arguments are equal.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
static char * handle_show_translation_table(struct ast_cli_args *a)
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'.
#define format_sample_rate_absdiff(fmt1, fmt2)
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)
void ast_translator_activate(struct ast_translator *t)
Activate a previously deactivated translator.
static void handle_cli_recalc(struct ast_cli_args *a)
static int add_codec2index(struct ast_codec *codec)
static int codec_to_index(unsigned int id)
static struct ast_frame * default_frameout(struct ast_trans_pvt *pvt)
void ast_translator_free_path(struct ast_trans_pvt *p)
Frees a translator path Frees the given translator path structure.
static ast_rwlock_t tablelock
static void matrix_rebuild(int samples)
rebuild a translation matrix.
int ast_unregister_translator(struct ast_translator *t)
unregister codec translator
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,...
static void matrix_clear(void)
void ast_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result)
Find available formats.
static int matrix_resize(int init)
void ast_translator_deactivate(struct ast_translator *t)
Deactivate a translator.
static unsigned int * __indextable
table for converting index to format values.
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.
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.
static struct ast_trans_pvt * newpvt(struct ast_translator *t, struct ast_format *explicit_dst)
Allocate the descriptor, required outbuf space, and possibly desc.
struct ast_frame * ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
do the actual translation
static struct translator_path ** __matrix
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
static int codec2index(struct ast_codec *codec)
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
static void translate_shutdown(void)
static void generate_computational_cost(struct ast_translator *t, int seconds)
int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
register codec translator
static void codec_append_name(const struct ast_codec *codec, struct ast_str **buf)
static char * handle_show_translation_path(struct ast_cli_args *a, const char *codec_name, unsigned int sample_rate)
static struct ast_cli_entry cli_translate[]
static void destroy(struct ast_trans_pvt *pvt)
static struct ast_frame * generate_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 struct ast_codec * index2codec(int index)
static char * complete_trans_path_choice(const char *word)
static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
static int format2index(struct ast_format *format)
static char * handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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.
int ast_translate_init(void)
Initialize the translation matrix and index to format conversion table.
Support for translation of data formats. translate.c.
@ AST_TRANS_COST_LY_LY_DOWNSAMP
@ AST_TRANS_COST_LL_LL_DOWNSAMP
@ AST_TRANS_COST_LY_LY_ORIGSAMP
@ AST_TRANS_COST_LL_LL_UPSAMP
@ AST_TRANS_COST_LY_LL_ORIGSAMP
@ AST_TRANS_COST_LL_UNKNOWN
@ AST_TRANS_COST_LY_LL_DOWNSAMP
@ AST_TRANS_COST_LL_LY_DOWNSAMP
@ AST_TRANS_COST_LL_LY_ORIGSAMP
@ AST_TRANS_COST_LY_UNKNOWN
@ AST_TRANS_COST_LL_LY_UPSAMP
@ AST_TRANS_COST_LY_LY_UPSAMP
@ AST_TRANS_COST_LY_LL_UPSAMP
@ AST_TRANS_COST_LL_LL_ORIGSAMP
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_set2_flag(p, value, flag)
#define ast_clear_flag(p, flag)
#define ast_copy_flags(dest, src, flagz)