Merge updates to frame.h and frame.c (codec stuff from bug #2945, part 1)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4370 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
7742cd11fa
commit
b46c98aa49
436
frame.c
436
frame.c
|
@ -15,6 +15,7 @@
|
|||
#include <asterisk/frame.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/cli.h>
|
||||
#include <asterisk/term.h>
|
||||
#include <asterisk/utils.h>
|
||||
|
@ -33,6 +34,13 @@ AST_MUTEX_DEFINE_STATIC(framelock);
|
|||
|
||||
#define SMOOTHER_SIZE 8000
|
||||
|
||||
struct ast_format_list {
|
||||
int visible; /* Can we see this entry */
|
||||
int bits; /* bitmask value */
|
||||
char *name; /* short name */
|
||||
char *desc; /* Description */
|
||||
};
|
||||
|
||||
struct ast_smoother {
|
||||
int size;
|
||||
int format;
|
||||
|
@ -391,140 +399,136 @@ int ast_fr_fdhangup(int fd)
|
|||
return ast_fr_fdwrite(fd, &hangup);
|
||||
}
|
||||
|
||||
char* ast_getformatname(int format)
|
||||
{
|
||||
if (format == AST_FORMAT_G723_1)
|
||||
return "G723";
|
||||
else if (format == AST_FORMAT_GSM)
|
||||
return "GSM";
|
||||
else if (format == AST_FORMAT_ULAW)
|
||||
return "ULAW";
|
||||
else if (format == AST_FORMAT_ALAW)
|
||||
return "ALAW";
|
||||
else if (format == AST_FORMAT_G726)
|
||||
return "G726";
|
||||
else if (format == AST_FORMAT_SLINEAR)
|
||||
return "SLINR";
|
||||
else if (format == AST_FORMAT_LPC10)
|
||||
return "LPC10";
|
||||
else if (format == AST_FORMAT_ADPCM)
|
||||
return "ADPCM";
|
||||
else if (format == AST_FORMAT_G729A)
|
||||
return "G729A";
|
||||
else if (format == AST_FORMAT_SPEEX)
|
||||
return "SPEEX";
|
||||
else if (format == AST_FORMAT_ILBC)
|
||||
return "ILBC";
|
||||
else if (format == AST_FORMAT_JPEG)
|
||||
return "JPEG";
|
||||
else if (format == AST_FORMAT_PNG)
|
||||
return "PNG";
|
||||
else if (format == AST_FORMAT_H261)
|
||||
return "H261";
|
||||
else if (format == AST_FORMAT_H263)
|
||||
return "H263";
|
||||
return "UNKN";
|
||||
static struct ast_format_list AST_FORMAT_LIST[] = {
|
||||
{ 1, AST_FORMAT_G723_1 , "g723" , "G.723.1"},
|
||||
{ 1, AST_FORMAT_GSM, "gsm" , "GSM"},
|
||||
{ 1, AST_FORMAT_ULAW, "ulaw", "G.711 u-law" },
|
||||
{ 1, AST_FORMAT_ALAW, "alaw", "G.711 A-law" },
|
||||
{ 1, AST_FORMAT_G726, "g726", "G.726" },
|
||||
{ 1, AST_FORMAT_ADPCM, "adpcm" , "ADPCM"},
|
||||
{ 1, AST_FORMAT_SLINEAR, "slin", "16 bit Signed Linear PCM"},
|
||||
{ 1, AST_FORMAT_LPC10, "lpc10", "LPC10" },
|
||||
{ 1, AST_FORMAT_G729A, "g729", "G.729A" },
|
||||
{ 1, AST_FORMAT_SPEEX, "speex", "SpeeX" },
|
||||
{ 1, AST_FORMAT_ILBC, "ilbc", "iLBC"},
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, AST_FORMAT_MAX_AUDIO, "maxaudio", "Maximum audio format" },
|
||||
{ 1, AST_FORMAT_JPEG, "jpeg", "JPEG image"},
|
||||
{ 1, AST_FORMAT_PNG, "png", "PNG image"},
|
||||
{ 1, AST_FORMAT_H261, "h261", "H.261 Video" },
|
||||
{ 1, AST_FORMAT_H263, "h263", "H.263 Video" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, 0, "nothing", "undefined" },
|
||||
{ 0, AST_FORMAT_MAX_VIDEO, "maxvideo", "Maximum video format" },
|
||||
};
|
||||
|
||||
struct ast_format_list *ast_get_format_list_index(int index) {
|
||||
return &AST_FORMAT_LIST[index];
|
||||
}
|
||||
|
||||
char* ast_getformatname_multiple(char *buf, unsigned n, int format) {
|
||||
unsigned u=1;
|
||||
struct ast_format_list *ast_get_format_list(size_t *size) {
|
||||
*size = (sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list));
|
||||
return AST_FORMAT_LIST;
|
||||
}
|
||||
|
||||
char* ast_getformatname(int format)
|
||||
{
|
||||
int x = 0;
|
||||
char *ret = "unknown";
|
||||
for (x = 0 ; x < sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list) ; x++) {
|
||||
if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == format) {
|
||||
ret = AST_FORMAT_LIST[x].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ast_getformatname_multiple(char *buf, size_t size, int format) {
|
||||
|
||||
int x = 0;
|
||||
unsigned len;
|
||||
char *b = buf;
|
||||
char *end = buf;
|
||||
char *start = buf;
|
||||
if (!n) return buf;
|
||||
snprintf(b,n,"0x%x(",format);
|
||||
len = strlen(b);
|
||||
b += len;
|
||||
n -= len;
|
||||
start = b;
|
||||
while (u) {
|
||||
if (u&format) {
|
||||
snprintf(b,n,"%s|",ast_getformatname(u));
|
||||
len = strlen(b);
|
||||
b += len;
|
||||
n -= len;
|
||||
if (!size) return buf;
|
||||
snprintf(end, size, "0x%x (", format);
|
||||
len = strlen(end);
|
||||
end += len;
|
||||
size -= len;
|
||||
start = end;
|
||||
for (x = 0 ; x < sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list) ; x++) {
|
||||
if (AST_FORMAT_LIST[x].visible && (AST_FORMAT_LIST[x].bits & format)) {
|
||||
snprintf(end, size,"%s|",AST_FORMAT_LIST[x].name);
|
||||
len = strlen(end);
|
||||
end += len;
|
||||
size -= len;
|
||||
}
|
||||
u *= 2;
|
||||
}
|
||||
if (start==b)
|
||||
snprintf(start,n,"EMPTY)");
|
||||
else if (n>1)
|
||||
b[-1]=')';
|
||||
if (start == end)
|
||||
snprintf(start, size, "nothing)");
|
||||
else if (size > 1)
|
||||
*(end -1) = ')';
|
||||
return buf;
|
||||
}
|
||||
|
||||
static struct ast_codec_alias_table {
|
||||
char *alias;
|
||||
char *realname;
|
||||
|
||||
} ast_codec_alias_table[] = {
|
||||
{"slinear","slin"},
|
||||
{"g723.1","g723"},
|
||||
};
|
||||
|
||||
static char *ast_expand_codec_alias(char *in) {
|
||||
int x = 0;
|
||||
|
||||
for (x = 0; x < sizeof(ast_codec_alias_table) / sizeof(struct ast_codec_alias_table) ; x++) {
|
||||
if(!strcmp(in,ast_codec_alias_table[x].alias))
|
||||
return ast_codec_alias_table[x].realname;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
int ast_getformatbyname(char *name)
|
||||
{
|
||||
if (!strcasecmp(name, "g723.1"))
|
||||
return AST_FORMAT_G723_1;
|
||||
else if (!strcasecmp(name, "gsm"))
|
||||
return AST_FORMAT_GSM;
|
||||
else if (!strcasecmp(name, "ulaw"))
|
||||
return AST_FORMAT_ULAW;
|
||||
else if (!strcasecmp(name, "alaw"))
|
||||
return AST_FORMAT_ALAW;
|
||||
else if (!strcasecmp(name, "g726"))
|
||||
return AST_FORMAT_G726;
|
||||
else if (!strcasecmp(name, "slinear"))
|
||||
return AST_FORMAT_SLINEAR;
|
||||
else if (!strcasecmp(name, "lpc10"))
|
||||
return AST_FORMAT_LPC10;
|
||||
else if (!strcasecmp(name, "adpcm"))
|
||||
return AST_FORMAT_ADPCM;
|
||||
else if (!strcasecmp(name, "g729"))
|
||||
return AST_FORMAT_G729A;
|
||||
else if (!strcasecmp(name, "speex"))
|
||||
return AST_FORMAT_SPEEX;
|
||||
else if (!strcasecmp(name, "ilbc"))
|
||||
return AST_FORMAT_ILBC;
|
||||
else if (!strcasecmp(name, "h261"))
|
||||
return AST_FORMAT_H261;
|
||||
else if (!strcasecmp(name, "h263"))
|
||||
return AST_FORMAT_H263;
|
||||
else if (!strcasecmp(name, "all"))
|
||||
return 0x7FFFFFFF;
|
||||
return 0;
|
||||
int x = 0, all = 0, format = 0;
|
||||
|
||||
all = strcmp(name, "all") ? 0 : 1;
|
||||
for (x = 0 ; x < sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list) ; x++) {
|
||||
if(AST_FORMAT_LIST[x].visible && (all ||
|
||||
!strcmp(AST_FORMAT_LIST[x].name,name) ||
|
||||
!strcmp(AST_FORMAT_LIST[x].name,ast_expand_codec_alias(name)))) {
|
||||
format |= AST_FORMAT_LIST[x].bits;
|
||||
if(!all)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
char *ast_codec2str(int codec) {
|
||||
static char codecs[25][30] = {
|
||||
/* Audio formats */
|
||||
"G.723.1", /* 0 */
|
||||
"GSM", /* 1 */
|
||||
"G.711 u-law", /* 2 */
|
||||
"G.711 A-law", /* 3 */
|
||||
"G.726", /* 4 */
|
||||
"ADPCM", /* 5 */
|
||||
"16 bit Signed Linear PCM", /* 6 */
|
||||
"LPC10", /* 7 */
|
||||
"G.729A audio", /* 8 */
|
||||
"SpeeX", /* 9 */
|
||||
"iLBC", /* 10 */
|
||||
"undefined", /* 11 */
|
||||
"undefined", /* 12 */
|
||||
"undefined", /* 13 */
|
||||
"undefined", /* 14 */
|
||||
"Maximum audio format", /* 15 */
|
||||
/* Image formats */
|
||||
"JPEG image", /* 16 */
|
||||
"PNG image", /* 17 */
|
||||
"H.261 Video", /* 18 */
|
||||
"H.263 Video", /* 19 */
|
||||
"undefined", /* 20 */
|
||||
"undefined", /* 21 */
|
||||
"undefined", /* 22 */
|
||||
"undefined", /* 23 */
|
||||
"Maximum video format", /* 24 */
|
||||
};
|
||||
if ((codec >= 0) && (codec <= 24))
|
||||
return codecs[codec];
|
||||
else
|
||||
return "unknown";
|
||||
int x = 0;
|
||||
char *ret = "unknown";
|
||||
for (x = 0 ; x < sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list) ; x++) {
|
||||
if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == codec) {
|
||||
ret = AST_FORMAT_LIST[x].desc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int show_codecs(int fd, int argc, char *argv[])
|
||||
{
|
||||
int i, found=0;
|
||||
char hex[25];
|
||||
|
||||
if ((argc < 2) || (argc > 3))
|
||||
return RESULT_SHOWUSAGE;
|
||||
|
@ -533,22 +537,30 @@ static int show_codecs(int fd, int argc, char *argv[])
|
|||
ast_cli(fd, "Disclaimer: this command is for informational purposes only.\n"
|
||||
"\tIt does not indicate anything about your configuration.\n");
|
||||
|
||||
ast_cli(fd, "%11s %9s %10s TYPE %5s %s\n","INT","BINARY","HEX","NAME","DESC");
|
||||
ast_cli(fd, "--------------------------------------------------------------------------------\n");
|
||||
if ((argc == 2) || (!strcasecmp(argv[1],"audio"))) {
|
||||
found = 1;
|
||||
for (i=0;i<11;i++)
|
||||
ast_cli(fd, "%11u (1 << %2d) %s\n",1 << i,i,ast_codec2str(i));
|
||||
for (i=0;i<11;i++) {
|
||||
snprintf(hex,25,"(0x%x)",1<<i);
|
||||
ast_cli(fd, "%11u (1 << %2d) %10s audio %5s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc == 2) || (!strcasecmp(argv[1],"image"))) {
|
||||
found = 1;
|
||||
for (i=16;i<18;i++)
|
||||
ast_cli(fd, "%11u (1 << %2d) %s\n",1 << i,i,ast_codec2str(i));
|
||||
for (i=16;i<18;i++) {
|
||||
snprintf(hex,25,"(0x%x)",1<<i);
|
||||
ast_cli(fd, "%11u (1 << %2d) %10s image %5s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc == 2) || (!strcasecmp(argv[1],"video"))) {
|
||||
found = 1;
|
||||
for (i=18;i<20;i++)
|
||||
ast_cli(fd, "%11u (1 << %2d) %s\n",1 << i,i,ast_codec2str(i));
|
||||
for (i=18;i<20;i++) {
|
||||
snprintf(hex,25,"(0x%x)",1<<i);
|
||||
ast_cli(fd, "%11u (1 << %2d) %10s video %5s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
|
@ -797,3 +809,185 @@ int init_framer(void)
|
|||
ast_cli_register(&cli_show_codec_n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ast_codec_pref_shift(struct ast_codec_pref *pref, char *buf, size_t size, int right)
|
||||
{
|
||||
int x = 0, differential = 65, mem = 0;
|
||||
char *from = NULL, *to = NULL;
|
||||
|
||||
if(right) {
|
||||
from = pref->order;
|
||||
to = buf;
|
||||
mem = size;
|
||||
} else {
|
||||
to = pref->order;
|
||||
from = buf;
|
||||
mem = 32;
|
||||
}
|
||||
|
||||
memset(to, 0, mem);
|
||||
for (x = 0; x < 32 ; x++) {
|
||||
if(!from[x])
|
||||
break;
|
||||
to[x] = right ? (from[x] + differential) : (from[x] - differential);
|
||||
}
|
||||
}
|
||||
|
||||
int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size)
|
||||
{
|
||||
int x = 0, codec = 0;
|
||||
size_t total_len = 0, slen = 0;
|
||||
char *formatname = 0;
|
||||
|
||||
memset(buf,0,size);
|
||||
total_len = size;
|
||||
buf[0] = '(';
|
||||
total_len--;
|
||||
for(x = 0; x < 32 ; x++) {
|
||||
if(total_len <= 0)
|
||||
break;
|
||||
if(!(codec = ast_codec_pref_index(pref,x)))
|
||||
break;
|
||||
if((formatname = ast_getformatname(codec))) {
|
||||
slen = strlen(formatname);
|
||||
if(slen > total_len)
|
||||
break;
|
||||
strncat(buf,formatname,total_len);
|
||||
total_len -= slen;
|
||||
}
|
||||
if(total_len && x < 31 && ast_codec_pref_index(pref , x + 1)) {
|
||||
strncat(buf,"|",total_len);
|
||||
total_len--;
|
||||
}
|
||||
}
|
||||
if(total_len) {
|
||||
strncat(buf,")",total_len);
|
||||
total_len--;
|
||||
}
|
||||
|
||||
return size - total_len;
|
||||
}
|
||||
|
||||
int ast_codec_pref_index(struct ast_codec_pref *pref, int index)
|
||||
{
|
||||
int slot = 0;
|
||||
|
||||
|
||||
if((index >= 0) && (index < sizeof(pref->order))) {
|
||||
slot = pref->order[index];
|
||||
}
|
||||
|
||||
return slot ? AST_FORMAT_LIST[slot-1].bits : 0;
|
||||
}
|
||||
|
||||
/*--- ast_codec_pref_remove: Remove codec from pref list ---*/
|
||||
void ast_codec_pref_remove(struct ast_codec_pref *pref, int format)
|
||||
{
|
||||
struct ast_codec_pref oldorder;
|
||||
int x=0, y=0;
|
||||
size_t size = 0;
|
||||
int slot = 0;
|
||||
|
||||
if(!pref->order[0])
|
||||
return;
|
||||
|
||||
size = sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list);
|
||||
|
||||
memcpy(&oldorder,pref,sizeof(struct ast_codec_pref));
|
||||
memset(pref,0,sizeof(struct ast_codec_pref));
|
||||
|
||||
for (x = 0; x < size; x++) {
|
||||
slot = oldorder.order[x];
|
||||
if(! slot)
|
||||
break;
|
||||
if(AST_FORMAT_LIST[slot-1].bits != format)
|
||||
pref->order[y++] = slot;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--- ast_codec_pref_append: Append codec to list ---*/
|
||||
int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
|
||||
{
|
||||
size_t size = 0;
|
||||
int x = 0, newindex = -1;
|
||||
|
||||
ast_codec_pref_remove(pref, format);
|
||||
size = sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list);
|
||||
|
||||
for (x = 0; x < size; x++) {
|
||||
if(AST_FORMAT_LIST[x].bits == format) {
|
||||
newindex = x + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(newindex) {
|
||||
for (x = 0; x < size; x++) {
|
||||
if(!pref->order[x]) {
|
||||
pref->order[x] = newindex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/*--- sip_codec_choose: Pick a codec ---*/
|
||||
int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best)
|
||||
{
|
||||
size_t size = 0;
|
||||
int x = 0, ret = 0, slot = 0;
|
||||
|
||||
size = sizeof(AST_FORMAT_LIST) / sizeof(struct ast_format_list);
|
||||
for (x = 0; x < size; x++) {
|
||||
slot = pref->order[x];
|
||||
|
||||
if(!slot)
|
||||
break;
|
||||
if ( formats & AST_FORMAT_LIST[slot-1].bits ) {
|
||||
ret = AST_FORMAT_LIST[slot-1].bits;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
return find_best ? ast_best_codec(formats) : 0;
|
||||
}
|
||||
|
||||
void ast_parse_allow_deny(struct ast_codec_pref *pref, int *mask, char *list, int allowing)
|
||||
{
|
||||
int format_i = 0;
|
||||
char *next_format = NULL, *last_format = NULL;
|
||||
|
||||
last_format = ast_strdupa(list);
|
||||
while(last_format) {
|
||||
if((next_format = strchr(last_format, ','))) {
|
||||
*next_format = '\0';
|
||||
next_format++;
|
||||
}
|
||||
if ((format_i = ast_getformatbyname(last_format)) > 0) {
|
||||
if (mask) {
|
||||
if (allowing)
|
||||
(*mask) |= format_i;
|
||||
else
|
||||
(*mask) &= format_i;
|
||||
}
|
||||
/* can't consider 'all' a prefered codec*/
|
||||
if(pref && strcasecmp(last_format, "all")) {
|
||||
if(allowing)
|
||||
ast_codec_pref_append(pref, format_i);
|
||||
else
|
||||
ast_codec_pref_remove(pref, format_i);
|
||||
}
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", allowing ? "allow" : "disallow", last_format);
|
||||
|
||||
last_format = next_format;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,11 @@ extern "C" {
|
|||
#error Need to know endianess
|
||||
#endif /* __BYTE_ORDER */
|
||||
|
||||
struct ast_codec_pref {
|
||||
char order[32];
|
||||
};
|
||||
|
||||
|
||||
//! Data structure associated with a single frame of data
|
||||
/* A frame of data read used to communicate between
|
||||
between channels and applications */
|
||||
|
@ -340,8 +345,7 @@ extern char* ast_getformatname(int format);
|
|||
* ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)"
|
||||
* \return The return value is buf.
|
||||
*/
|
||||
extern char* ast_getformatname_multiple(char *buf, unsigned n, int format);
|
||||
|
||||
extern char* ast_getformatname_multiple(char *buf, size_t size, int format);
|
||||
|
||||
/*!
|
||||
* \param name string of format
|
||||
|
@ -364,6 +368,8 @@ extern int ast_best_codec(int fmts);
|
|||
|
||||
struct ast_smoother;
|
||||
|
||||
extern struct ast_format_list *ast_get_format_list_index(int index);
|
||||
extern struct ast_format_list *ast_get_format_list(size_t *size);
|
||||
extern struct ast_smoother *ast_smoother_new(int bytes);
|
||||
extern void ast_smoother_set_flags(struct ast_smoother *smoother, int flags);
|
||||
extern int ast_smoother_get_flags(struct ast_smoother *smoother);
|
||||
|
@ -374,6 +380,32 @@ extern struct ast_frame *ast_smoother_read(struct ast_smoother *s);
|
|||
|
||||
extern void ast_frame_dump(char *name, struct ast_frame *f, char *prefix);
|
||||
|
||||
/* Initialize a codec preference to "no preference" */
|
||||
extern void ast_codec_pref_init(struct ast_codec_pref *pref);
|
||||
|
||||
/* Codec located at a particular place in the preference index */
|
||||
extern int ast_codec_pref_index(struct ast_codec_pref *pref, int index);
|
||||
|
||||
/* Remove a codec from a preference list */
|
||||
extern void ast_codec_pref_remove(struct ast_codec_pref *pref, int format);
|
||||
|
||||
/* Append a codec to a preference list, removing it first if it was already there */
|
||||
extern int ast_codec_pref_append(struct ast_codec_pref *pref, int format);
|
||||
|
||||
/* Select the best format according to preference list from supplied options.
|
||||
If "find_best" is non-zero then if nothing is found, the "Best" format of
|
||||
the format list is selected, otherwise 0 is returned. */
|
||||
extern int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best);
|
||||
|
||||
/* Parse an "allow" or "deny" line and update the mask and pref if provided */
|
||||
extern void ast_parse_allow_deny(struct ast_codec_pref *pref, int *mask, char *list, int allowing);
|
||||
|
||||
/* Dump codec preference list into a string */
|
||||
extern int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
|
||||
|
||||
/* Shift a codec preference list up or down 65 bytes so that it becomes an ASCII string */
|
||||
extern void ast_codec_pref_shift(struct ast_codec_pref *pref, char *buf, size_t size, int right);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
Reference in New Issue