33 #include <sys/resource.h>
54 #define MAX_RECALC 1000
105 static int codec_to_index(
unsigned int id)
109 ast_rwlock_rdlock(&tablelock);
113 ast_rwlock_unlock(&tablelock);
117 ast_rwlock_unlock(&tablelock);
125 static int codec2index(
struct ast_codec *codec)
127 return codec_to_index(codec->
id);
134 static int format2index(
struct ast_format *format)
148 static int add_codec2index(
struct ast_codec *codec)
150 if (codec2index(codec) != -1) {
155 ast_rwlock_wrlock(&tablelock);
157 ast_rwlock_unlock(&tablelock);
162 ast_rwlock_unlock(&tablelock);
171 static struct ast_codec *index2codec(
int index)
175 if (index >= cur_max_index) {
178 ast_rwlock_rdlock(&tablelock);
180 ast_rwlock_unlock(&tablelock);
195 static int matrix_resize(
int init)
198 unsigned int *tmp_table = NULL;
203 ast_rwlock_wrlock(&tablelock);
224 if (!(tmp_table =
ast_calloc(1,
sizeof(
unsigned int) * index_size))) {
230 for (x = 0; x < old_index; x++) {
231 ast_free(__matrix[x]);
235 memcpy(tmp_table,
__indextable,
sizeof(
unsigned int) * old_index);
240 __matrix = tmp_matrix;
244 ast_rwlock_unlock(&tablelock);
250 ast_rwlock_unlock(&tablelock);
254 ast_free(tmp_matrix[x]);
256 ast_free(tmp_matrix);
269 static void matrix_clear(
void)
273 memset(__matrix[x],
'\0',
sizeof(
struct translator_path) * (index_size));
283 static struct translator_path *matrix_get(
unsigned int x,
unsigned int y)
285 return __matrix[x] + y;
330 ofs = (
char *)(pvt + 1);
359 pvt->
f.
data.ptr = pvt->outbuf.
c;
378 ast_log(LOG_ERROR,
"Unable to get destination codec\n");
387 ast_log(LOG_ERROR,
"Unable to create format\n");
407 if (!f->
src || strcasecmp(f->
src,
"ast_prod")) {
408 ast_log(LOG_WARNING,
"no samples for %s\n", pvt->t->
name);
415 ast_assert(src_srate > 0);
424 ast_log(LOG_WARNING,
"Out of buffer space\n");
431 return pvt->t->
framein(pvt, f);
455 f->
data.ptr = pvt->outbuf.
c;
461 f->
data.ptr = pvt->outbuf.
c;
489 int src_index, dst_index;
491 src_index = format2index(src);
492 dst_index = format2index(dst);
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) {
506 ast_log(LOG_WARNING,
"No translator path from %s to %s\n",
515 if (!(cur =
newpvt(t, explicit_dst))) {
516 ast_log(LOG_WARNING,
"Failed to build translator step from %s to %s\n",
528 cur->nextin = cur->nextout =
ast_tv(0, 0);
551 if (!ast_opt_generic_plc || f->
datalen != 0 ||
570 struct timeval delivery;
580 for (tp = p; tp; tp = tp->
next) {
615 for (out = f; out && p ; p = p->
next) {
625 out = p->t->frameout(p);
629 out = generate_interpolated_slin(path, f);
648 path->nextout =
ast_tv(0, 0);
665 if (has_timing_info) {
672 path->nextout =
ast_tv(0, 0);
691 static void generate_computational_cost(
struct ast_translator *t,
int seconds)
706 ast_debug(3,
"Translator '%s' does not produce sample frames.\n", t->
name);
713 ast_log(LOG_WARNING,
"Translator '%s' appears to be broken and will probably fail.\n", t->
name);
718 getrusage(RUSAGE_SELF, &start);
721 while (num_samples < seconds * out_rate) {
724 ast_log(LOG_WARNING,
"Translator '%s' failed to produce a sample frame.\n", t->
name);
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;
776 if ((src->
type != AST_MEDIA_TYPE_AUDIO) ||
777 (dst->
type != AST_MEDIA_TYPE_AUDIO)) {
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");
847 generate_computational_cost(t, samples);
856 if (!matrix_get(x, z)->step ||
860 matrix_get(x, z)->
step = t;
880 if ((z == x || z == y) ||
881 !matrix_get(x, y)->step ||
882 !matrix_get(y, z)->step) {
891 if (!matrix_get(x, z)->step || (newtablecost < matrix_get(x, z)->
table_cost)) {
892 matrix_get(x, z)->
step = matrix_get(x, y)->
step;
897 if (DEBUG_ATLEAST(10)) {
898 struct ast_codec *x_codec = index2codec(x);
899 struct ast_codec *y_codec = index2codec(y);
900 struct ast_codec *z_codec = index2codec(z);
903 "Discovered %u cost path from %s to %s, via %s\n",
904 matrix_get(x, z)->table_cost, x_codec->
name,
921 static void codec_append_name(
const struct ast_codec *codec,
struct ast_str **buf)
937 codec_append_name(&p->t->
src_codec, str);
940 codec_append_name(&p->t->
dst_codec, str);
947 static char *complete_trans_path_choice(
const char *word)
950 int wordlen = strlen(word);
955 if (codec->
type != AST_MEDIA_TYPE_AUDIO) {
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");
981 ast_cli(a->fd,
" Maximum limit of recalc exceeded by %d, truncating value to %d\n", time -
MAX_RECALC,
MAX_RECALC);
984 ast_cli(a->fd,
" Recalculating Codec Translation (number of sample seconds: %d)\n\n", time);
990 static char *handle_show_translation_table(
struct ast_cli_args *a)
992 int x, y, i, k, compCost;
994 int max_codec_index = 0, curlen = 0;
1002 if (codec->
type != AST_MEDIA_TYPE_AUDIO) {
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++) {
1019 if ((i > 0) && (row->
type != AST_MEDIA_TYPE_AUDIO)) {
1024 if ((i > 0) && (x = codec2index(row)) == -1) {
1030 for (k = 0; k <= max_codec_index; k++) {
1035 if ((k > 0) && (col->
type != AST_MEDIA_TYPE_AUDIO)) {
1040 if ((k > 0) && (y = codec2index(col)) == -1) {
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) {
1069 ast_str_append(&out, 0,
"%*u", curlen + 1, (matrix_get(x, y)->table_cost / 100));
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) {
1110 static char *handle_show_translation_path(
struct ast_cli_args *a,
const char *codec_name,
unsigned int sample_rate)
1113 struct ast_str *str = ast_str_alloca(1024);
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 ||
1134 dst_codec->
type != AST_MEDIA_TYPE_AUDIO) {
1139 dst = codec2index(dst_codec);
1140 src = codec2index(src_codec);
1142 if (src < 0 || dst < 0) {
1145 step = matrix_get(src, dst)->
step;
1148 codec_append_name(&step->
src_codec, &str);
1149 while (src != dst) {
1151 step = matrix_get(src, dst)->
step;
1154 codec_append_name(dst_codec, &str);
1158 codec_append_name(&step->
src_codec, &str);
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])) {
1205 return complete_trans_path_choice(a->word);
1212 return CLI_SHOWUSAGE;
1214 if (a->argv[3] && !strcasecmp(a->argv[3], option[1]) && a->argc == 5) {
1215 return handle_show_translation_path(a, a->argv[4], 0);
1216 }
else if (a->argv[3] && !strcasecmp(a->argv[3], option[1]) && a->argc == 6) {
1218 if (sscanf(a->argv[5],
"%30u", &sample_rate) != 1) {
1219 ast_cli(a->fd,
"Invalid sample rate: %s.\n", a->argv[5]);
1222 return handle_show_translation_path(a, a->argv[4], sample_rate);
1223 }
else if (a->argv[3] && (!strcasecmp(a->argv[3], option[0]) || !strcasecmp(a->argv[3], option[2]))) {
1224 handle_cli_recalc(a);
1225 }
else if (a->argc > 3) {
1226 return CLI_SHOWUSAGE;
1229 return handle_show_translation_table(a);
1233 AST_CLI_DEFINE(handle_cli_core_show_translation,
"Display translation matrix")
1247 ast_log(LOG_WARNING,
"Failed to register translator: unknown source codec %s\n", t->
src_codec.
name);
1253 ast_log(LOG_WARNING,
"Failed to register translator: unknown destination codec %s\n", t->
dst_codec.
name);
1257 if (add_codec2index(src_codec) || add_codec2index(dst_codec)) {
1258 if (matrix_resize(0)) {
1259 ast_log(LOG_WARNING,
"Translator matrix can not represent any more translators. Out of resources.\n");
1262 add_codec2index(src_codec);
1263 add_codec2index(dst_codec);
1267 ast_log(LOG_WARNING,
"Missing module pointer, you need to supply one\n");
1272 ast_log(LOG_WARNING,
"empty buf size, you need to supply one\n");
1276 ast_log(LOG_WARNING,
"Table cost could not be generated for %s, "
1277 "Please set table_cost variable on translator.\n", t->
name);
1287 ast_log(LOG_WARNING,
"Invalid translator path: (%s codec is not valid)\n", t->
src_fmt_index < 0 ?
"starting" :
"ending");
1291 ast_log(LOG_WARNING,
"Source codec %s is larger than cur_max_index\n", t->
src_codec.
name);
1296 ast_log(LOG_WARNING,
"Destination codec %s is larger than cur_max_index\n", t->
dst_codec.
name);
1305 struct _test_align {
void *a, *b; } p;
1306 int align = (
char *)&p.b - (
char *)&p.a;
1315 generate_computational_cost(t, 1);
1317 ast_verb(5,
"Registered translator '%s' from codec %s to %s, table cost, %d, computational cost %d\n",
1318 term_color(tmp, t->
name, COLOR_MAGENTA, COLOR_BLACK,
sizeof(tmp)),
1325 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&
translators, u, list) {
1329 AST_RWLIST_INSERT_BEFORE_CURRENT(t, list);
1334 AST_RWLIST_TRAVERSE_SAFE_END;
1359 AST_RWLIST_REMOVE_CURRENT(
list);
1360 ast_verb(5,
"Unregistered translator '%s' from codec %s to %s\n",
1361 term_color(tmp, t->
name, COLOR_MAGENTA, COLOR_BLACK,
sizeof(tmp)),
1367 AST_RWLIST_TRAVERSE_SAFE_END;
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");
1468 x = format2index(src);
1469 y = format2index(dst);
1470 if (x < 0 || y < 0) {
1473 if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) {
1476 if (matrix_get(x, y)->table_cost < besttablecost
1477 || matrix_get(x, y)->multistep < beststeps) {
1481 besttablecost = matrix_get(x, y)->
table_cost;
1482 beststeps = matrix_get(x, y)->
multistep;
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;
1501 ao2_cleanup(src_codec);
1502 ao2_cleanup(best_codec);
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",
1520 besttablecost = matrix_get(x, y)->
table_cost;
1521 beststeps = matrix_get(x, y)->
multistep;
1538 unsigned int res = -1;
1540 int src = format2index(src_format);
1541 int dest = format2index(dst_format);
1543 if (src < 0 || dest < 0) {
1544 ast_log(LOG_WARNING,
"No translator path: (%s codec is not valid)\n", src < 0 ?
"starting" :
"ending");
1549 if (matrix_get(src, dest)->step) {
1550 res = matrix_get(src, dest)->
multistep + 1;
1558 static void check_translation_path(
1574 int index, src_index;
1594 src_index = format2index(src_fmt);
1595 index = format2index(fmt);
1596 if (src_index < 0 || index < 0) {
1603 if (!matrix_get(src_index, index)->step) {
1609 if (!matrix_get(index, src_index)->step) {
1649 check_translation_path(dest, src, result,
1650 cur_src, AST_MEDIA_TYPE_AUDIO);
1651 check_translation_path(dest, src, result,
1652 cur_src, AST_MEDIA_TYPE_VIDEO);
1658 static void translate_shutdown(
void)
1663 ast_rwlock_wrlock(&tablelock);
1665 ast_free(__matrix[x]);
1671 ast_rwlock_unlock(&tablelock);
1672 ast_rwlock_destroy(&tablelock);
1679 res = matrix_resize(1);
int datalen
actual space used in outbuf
#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 *)
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.
Support for translation of data formats. translate.c.
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...
unsigned int id
Internal unique identifier for this codec, set at registration time (starts at 1) ...
descriptor for a cli entry.
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define AST_RWLIST_RDLOCK(head)
Read locks a 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.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
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_strdup(str)
A wrapper for strdup()
struct ast_trans_pvt * next
void ast_translator_activate(struct ast_translator *t)
Activate a previously deactivated translator.
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_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result)
Find available formats.
struct ast_frame_subclass subclass
static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
framein wrapper, deals with bound checks.
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
#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 ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
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.
struct ast_module * module
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.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Scheduler Routines (derived from cheops)
Asterisk internal frame definitions.
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 ...
unsigned int quality
Format quality, on scale from 0 to 150 (100 is ulaw, the reference). This allows better format to be ...
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_debug(level,...)
Log a DEBUG message.
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
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
void(* feedback)(struct ast_trans_pvt *pvt, struct ast_frame *feedback)
struct ast_format * explicit_dst
Support for dynamic strings.
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.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
struct ast_codec src_codec
#define ast_module_ref(mod)
Hold a reference to the module.
int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
register codec translator
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
struct ast_translator::@290 list
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_module_unref(mod)
Release a reference to the module.
struct ast_frame * ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
do the actual translation
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.
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
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.
enum ast_media_type type
Type of media this codec contains.
Handy terminal functions for vt* terms.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
ast_media_type
Types of media.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
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.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
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.
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.
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...