33 #include <sys/resource.h>
54 #define MAX_RECALC 1000
197 unsigned int *tmp_table =
NULL;
229 for (x = 0; x < old_index; x++) {
234 memcpy(tmp_table,
__indextable,
sizeof(
unsigned int) * old_index);
329 ofs = (
char *)(
pvt + 1);
357 pvt->f.src =
pvt->t->name;
358 pvt->f.data.ptr =
pvt->outbuf.c;
366 if (!
pvt->f.subclass.format) {
373 if (!
pvt->f.subclass.format) {
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) {
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;
770 int src_rate =
src->sample_rate;
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;
1057 if (x >= 0 && y >= 0 &&
matrix_get(x, y)->step) {
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) {
1202 ast_cli(
a->fd,
"Invalid sample rate: %s.\n",
a->argv[5]);
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) {
1459 if (
matrix_get(x, y)->table_cost < besttablecost
1460 ||
matrix_get(x, y)->multistep < beststeps) {
1466 }
else if (
matrix_get(x, y)->table_cost == besttablecost
1467 &&
matrix_get(x, y)->multistep == beststeps) {
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) {
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.
static snd_pcm_format_t format
General Asterisk PBX channel definitions.
Standard Command Line Interface.
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#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,...)
#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 len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Asterisk internal frame definitions.
@ AST_FRFLAG_HAS_TIMING_INFO
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#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.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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.
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.
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
union ast_frame::@254 data
enum ast_frame_type frametype
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...
struct ast_trans_pvt * next
union ast_trans_pvt::@317 outbuf
struct ast_translator * t
struct ast_format * explicit_dst
int datalen
actual space used in outbuf
Descriptor of a translator.
void(* destroy)(struct ast_trans_pvt *pvt)
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
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_module * module
struct ast_frame *(* sample)(void)
struct ast_translator::@316 list
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 struct ast_codec * index2codec(int index)
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'.
static char * handle_show_translation_path(struct ast_cli_args *a, const char *codec_name, unsigned int sample_rate)
static char * complete_trans_path_choice(const char *word)
#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 translator_path * matrix_get(unsigned int x, unsigned int y)
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
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 char * handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_frame * default_frameout(struct ast_trans_pvt *pvt)
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.
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 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 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 struct ast_frame * generate_interpolated_slin(struct ast_trans_pvt *p, struct ast_frame *f)
static void codec_append_name(const struct ast_codec *codec, struct ast_str **buf)
static char * handle_show_translation_table(struct ast_cli_args *a)
static struct ast_cli_entry cli_translate[]
static void destroy(struct ast_trans_pvt *pvt)
static int generate_table_cost(struct ast_codec *src, struct ast_codec *dst)
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 int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
static struct ast_trans_pvt * newpvt(struct ast_translator *t, struct ast_format *explicit_dst)
Allocate the descriptor, required outbuf space, and possibly desc.
static int format2index(struct ast_format *format)
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)