33 #include <sys/resource.h> 54 #define MAX_RECALC 1000 197 unsigned int *tmp_table =
NULL;
223 if (!(tmp_table =
ast_calloc(1,
sizeof(
unsigned int) * index_size))) {
229 for (x = 0; x < old_index; x++) {
234 memcpy(tmp_table,
__indextable,
sizeof(
unsigned int) * old_index);
239 __matrix = tmp_matrix;
272 memset(__matrix[x],
'\0',
sizeof(
struct translator_path) * (index_size));
284 return __matrix[x] + y;
329 ofs = (
char *)(pvt + 1);
406 if (!f->
src || strcasecmp(f->
src,
"ast_prod")) {
488 int src_index, dst_index;
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");
500 while (src_index != dst_index) {
514 if (!(cur =
newpvt(t, explicit_dst))) {
569 struct timeval delivery;
579 for (tp = p; tp; tp = tp->
next) {
614 for (out = f; out && p ; p = p->
next) {
624 out = p->t->frameout(p);
664 if (has_timing_info) {
705 ast_debug(3,
"Translator '%s' does not produce sample frames.\n", t->
name);
717 getrusage(RUSAGE_SELF, &start);
720 while (num_samples < seconds * out_rate) {
736 getrusage(RUSAGE_SELF, &end);
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;
783 src_ll = !strcmp(src->
name,
"slin");
784 dst_ll = !strcmp(dst->
name,
"slin");
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)) {
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)) {
832 ast_debug(1,
"Resetting translation matrix\n");
878 if ((z == x || z == y) ||
901 "Discovered %u cost path from %s to %s, via %s\n",
948 int wordlen = strlen(word);
957 if (!strncasecmp(word, codec->
name, wordlen)) {
971 int time = a->
argv[4] ? atoi(a->
argv[4]) : 1;
974 ast_cli(a->
fd,
" Recalc must be greater than 0. Defaulting to 1.\n");
982 ast_cli(a->
fd,
" Recalculating Codec Translation (number of sample seconds: %d)\n\n", time);
992 int max_codec_index = 0, curlen = 0;
1003 curlen = strlen(codec->
name);
1004 if (curlen > longest) {
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");
1013 for (i = 0; i <= max_codec_index; i++) {
1028 for (k = 0; k <= max_codec_index; k++) {
1044 curlen = strlen(col->
name);
1045 if (!strcmp(col->
name,
"slin") ||
1046 !strcmp(col->
name,
"speex") ||
1047 !strcmp(col->
name,
"silk")) {
1049 curlen = curlen + adjust;
1060 }
else if (i == 0 && k > 0) {
1062 if (!strcmp(col->
name,
"slin") ||
1063 !strcmp(col->
name,
"speex") ||
1064 !strcmp(col->
name,
"silk")) {
1070 }
else if (k == 0 && i > 0) {
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;
1081 }
else if (x >= 0 && y >= 0) {
1108 ast_cli(a->
fd,
"Source codec \"%s\" is not found.\n", codec_name);
1113 ast_cli(a->
fd,
"--- Translation paths SRC Codec \"%s\" sample rate %u ---\n",
1118 char src_buffer[64];
1119 char dst_buffer[64];
1122 if (src_codec == dst_codec ||
1131 if (src < 0 || dst < 0) {
1138 while (src != dst) {
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",
1166 static const char *
const option[] = {
"recalc",
"paths",
NULL };
1170 e->
command =
"core show translation";
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";
1187 if (a->
pos == 4 && !strcasecmp(a->
argv[3], option[1])) {
1197 if (a->
argv[3] && !strcasecmp(a->
argv[3], option[1]) && a->
argc == 5) {
1199 }
else if (a->
argv[3] && !strcasecmp(a->
argv[3], option[1]) && a->
argc == 6) {
1201 if (sscanf(a->
argv[5],
"%30u", &sample_rate) != 1) {
1206 }
else if (a->
argv[3] && !strcasecmp(a->
argv[3], option[0])) {
1208 }
else if (a->
argc > 3) {
1242 ast_log(
LOG_WARNING,
"Translator matrix can not represent any more translators. Out of resources.\n");
1260 "Please set table_cost variable on translator.\n", t->
name);
1288 struct _test_align {
void *
a, *
b; } p;
1289 int align = (
char *)&p.b - (
char *)&p.a;
1300 ast_verb(2,
"Registered translator '%s' from codec %s to %s, table cost, %d, computational cost %d\n",
1343 ast_verb(2,
"Unregistered translator '%s' from codec %s to %s\n",
1358 return (u ? 0 : -1);
1378 #define format_sample_rate_absdiff(fmt1, fmt2) ({ \ 1379 unsigned int rate1 = ast_format_get_sample_rate(fmt1); \ 1380 unsigned int rate2 = ast_format_get_sample_rate(fmt2); \ 1381 (rate1 > rate2 ? rate1 - rate2 : rate2 - rate1); \ 1390 unsigned int besttablecost = INT_MAX;
1391 unsigned int beststeps = INT_MAX;
1402 ast_log(
LOG_ERROR,
"Cannot determine best translation path since one capability supports no formats\n");
1453 if (x < 0 || y < 0) {
1471 if (gap_current < gap_selected) {
1493 unsigned int res = -1;
1498 if (src < 0 || dest < 0) {
1499 ast_log(
LOG_WARNING,
"No translator path: (%s codec is not valid)\n", src < 0 ?
"starting" :
"ending");
1529 int index, src_index;
1551 if (src_index < 0 || index < 0) {
int datalen
actual space used in outbuf
#define ast_rwlock_rdlock(a)
#define AST_CLI_DEFINE(fn, txt,...)
#define ast_frdup(fr)
Copies a frame.
Asterisk locking-related definitions:
const char * name
Name for this codec.
Asterisk main include file. File version handling, generic pbx functions.
int ast_shutting_down(void)
int(* newpvt)(struct ast_trans_pvt *)
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
static int matrix_resize(int init)
static struct ast_cli_entry cli_translate[]
static void matrix_rebuild(int samples)
rebuild a translation matrix.
Descriptor of a translator.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_set2_flag(p, value, flag)
#define ast_test_flag(p, flag)
Support for translation of data formats. translate.c.
#define ast_rwlock_destroy(rwlock)
static ast_rwlock_t tablelock
int ast_tveq(struct timeval _a, struct timeval _b)
Returns true if the two struct timeval arguments are equal.
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
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...
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
unsigned int id
Internal unique identifier for this codec, set at registration time (starts at 1) ...
static char * handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
descriptor for a cli entry.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
static struct ast_frame * default_frameout(struct ast_trans_pvt *pvt)
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'.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ast_copy_flags(dest, src, flagz)
#define ast_str_alloca(init_len)
#define ast_strdup(str)
A wrapper for strdup()
struct ast_trans_pvt * next
void ast_translator_activate(struct ast_translator *t)
Activate a previously deactivated translator.
static int add_codec2index(struct ast_codec *codec)
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_translator * step
void ast_cli(int fd, const char *fmt,...)
void ast_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result)
Find available formats.
#define ast_rwlock_unlock(a)
#define ast_verb(level,...)
struct ast_frame_subclass subclass
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.
static void matrix_clear(void)
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_strlen_zero(foo)
static void handle_cli_recalc(struct ast_cli_args *a)
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
static struct translator_path ** __matrix
a matrix that, for any pair of supported formats, indicates the total cost of translation and the fir...
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
struct ast_module * module
#define AST_RWLIST_INSERT_HEAD
#define ast_debug(level,...)
Log a DEBUG message.
void ast_translator_free_path(struct ast_trans_pvt *p)
Frees a translator path Frees the given translator path structure.
#define format_sample_rate_absdiff(fmt1, fmt2)
General Asterisk PBX channel definitions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
static char * handle_show_translation_path(struct ast_cli_args *a, const char *codec_name, unsigned int sample_rate)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_RWLIST_TRAVERSE
Scheduler Routines (derived from cheops)
Asterisk internal frame definitions.
#define ao2_ref(o, delta)
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)
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 ...
static struct translator_path * matrix_get(unsigned int x, unsigned int y)
#define AST_RWLIST_REMOVE_CURRENT
int ast_translate_init(void)
Initialize the translation matrix and index to format conversion table.
A set of macros to manage forward-linked lists.
#define AST_RWLIST_INSERT_BEFORE_CURRENT
#define ast_opt_generic_plc
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
union ast_trans_pvt::@327 outbuf
void(* destroy)(struct ast_trans_pvt *pvt)
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_codec dst_codec
static int codec2index(struct ast_codec *codec)
void(* feedback)(struct ast_trans_pvt *pvt, struct ast_frame *feedback)
struct ast_translator::@326 list
struct ast_format * explicit_dst
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
static unsigned int * __indextable
table for converting index to format values.
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
static struct ast_codec * index2codec(int index)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
struct ast_codec src_codec
int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
register codec translator
static void translate_shutdown(void)
static void codec_append_name(const struct ast_codec *codec, struct ast_str **buf)
#define ast_calloc(num, len)
A wrapper for calloc()
static void destroy(struct ast_trans_pvt *pvt)
int ast_unregister_translator(struct ast_translator *t)
unregister codec translator
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
struct ast_frame *(* sample)(void)
unsigned int sample_rate
Sample rate (number of samples carried in a second)
#define ast_clear_flag(p, flag)
struct ast_frame * ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
do the actual translation
static int codec_to_index(unsigned int id)
#define ast_rwlock_wrlock(a)
struct ast_frame ast_null_frame
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
static char * complete_trans_path_choice(const char *word)
#define ao2_replace(dst, src)
Structure for rwlock and tracking information.
Standard Command Line Interface.
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.
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
void ast_translator_deactivate(struct ast_translator *t)
Deactivate a translator.
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
Data structure associated with a single frame of data.
static void generate_computational_cost(struct ast_translator *t, int seconds)
enum ast_media_type type
Type of media this codec contains.
struct ast_translator * t
Handy terminal functions for vt* terms.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
union ast_frame::@263 data
ast_media_type
Types of media.
enum ast_frame_type frametype
struct ast_format * format
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
static int generate_table_cost(struct ast_codec *src, struct ast_codec *dst)
#define DEBUG_ATLEAST(level)
Asterisk module definitions.
static snd_pcm_format_t format
static char * handle_show_translation_table(struct ast_cli_args *a)
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.
Represents a media codec within Asterisk.
#define AST_RWLIST_TRAVERSE_SAFE_END
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_frame * generate_interpolated_slin(struct ast_trans_pvt *p, struct ast_frame *f)
int(* framein)(struct ast_trans_pvt *pvt, struct ast_frame *in)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int buffer_samples
size of outbuf, in samples. Leave it 0 if you want the framein callback deal with the frame...
#define ast_module_ref(mod)
Hold a reference to the module.