diff options
Diffstat (limited to 'main/frame.c')
-rw-r--r-- | main/frame.c | 153 |
1 files changed, 82 insertions, 71 deletions
diff --git a/main/frame.c b/main/frame.c index f24c7a4dc..a11644577 100644 --- a/main/frame.c +++ b/main/frame.c @@ -80,7 +80,7 @@ enum frame_type { struct ast_smoother { int size; - int format; + format_t format; int flags; float samplesperbyte; unsigned int opt_needs_swap:1; @@ -119,6 +119,7 @@ static const struct ast_format_list AST_FORMAT_LIST[] = { { AST_FORMAT_T140, "t140", 0, "Passthrough T.140 Realtime Text" }, /*!< Passthrough support for T.140 Realtime Text */ { AST_FORMAT_SIREN7, "siren7", 16000, "ITU G.722.1 (Siren7, licensed from Polycom)", 80, 20, 80, 20, 20 }, /*!< Binary commercial distribution */ { AST_FORMAT_SIREN14, "siren14", 32000, "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)", 120, 20, 80, 20, 20 }, /*!< Binary commercial distribution */ + { AST_FORMAT_TESTLAW, "testlaw", 8000, "G.711 test-law", 80, 10, 150, 10, 20 }, /*!< codec_ulaw.c */ }; struct ast_frame ast_null_frame = { AST_FRAME_NULL, }; @@ -205,10 +206,11 @@ int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap) return -1; } if (!s->format) { - s->format = f->subclass; + s->format = f->subclass.codec; s->samplesperbyte = (float)f->samples / (float)f->datalen; - } else if (s->format != f->subclass) { - ast_log(LOG_WARNING, "Smoother was working on %d format frames, now trying to feed %d?\n", s->format, f->subclass); + } else if (s->format != f->subclass.codec) { + ast_log(LOG_WARNING, "Smoother was working on %s format frames, now trying to feed %s?\n", + ast_getformatname(s->format), ast_getformatname(f->subclass.codec)); return -1; } if (s->len + f->datalen > SMOOTHER_SIZE) { @@ -259,7 +261,7 @@ struct ast_frame *ast_smoother_read(struct ast_smoother *s) len = s->len; /* Make frame */ s->f.frametype = AST_FRAME_VOICE; - s->f.subclass = s->format; + s->f.subclass.codec = s->format; s->f.data.ptr = s->framedata + AST_FRIENDLY_OFFSET; s->f.offset = AST_FRIENDLY_OFFSET; s->f.datalen = len; @@ -404,7 +406,7 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) return NULL; } out->frametype = fr->frametype; - out->subclass = fr->subclass; + out->subclass.codec = fr->subclass.codec; out->datalen = fr->datalen; out->samples = fr->samples; out->offset = fr->offset; @@ -506,7 +508,7 @@ struct ast_frame *ast_frdup(const struct ast_frame *f) } out->frametype = f->frametype; - out->subclass = f->subclass; + out->subclass.codec = f->subclass.codec; out->datalen = f->datalen; out->samples = f->samples; out->delivery = f->delivery; @@ -557,7 +559,7 @@ const struct ast_format_list *ast_get_format_list(size_t *size) return AST_FORMAT_LIST; } -char* ast_getformatname(int format) +char* ast_getformatname(format_t format) { int x; char *ret = "unknown"; @@ -570,7 +572,7 @@ char* ast_getformatname(int format) return ret; } -char *ast_getformatname_multiple(char *buf, size_t size, int format) +char *ast_getformatname_multiple(char *buf, size_t size, format_t format) { int x; unsigned len; @@ -578,14 +580,14 @@ char *ast_getformatname_multiple(char *buf, size_t size, int format) if (!size) return buf; - snprintf(end, size, "0x%x (", format); + snprintf(end, size, "0x%llx (", (unsigned long long) format); len = strlen(end); end += len; size -= len; start = end; for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) { if (AST_FORMAT_LIST[x].bits & format) { - snprintf(end, size,"%s|",AST_FORMAT_LIST[x].name); + snprintf(end, size, "%s|", AST_FORMAT_LIST[x].name); len = strlen(end); end += len; size -= len; @@ -594,7 +596,7 @@ char *ast_getformatname_multiple(char *buf, size_t size, int format) if (start == end) ast_copy_string(start, "nothing)", size); else if (size > 1) - *(end -1) = ')'; + *(end - 1) = ')'; return buf; } @@ -620,9 +622,10 @@ static const char *ast_expand_codec_alias(const char *in) return in; } -int ast_getformatbyname(const char *name) +format_t ast_getformatbyname(const char *name) { - int x, all, format = 0; + int x, all; + format_t format = 0; all = strcasecmp(name, "all") ? 0 : 1; for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) { @@ -638,7 +641,7 @@ int ast_getformatbyname(const char *name) return format; } -char *ast_codec2str(int codec) +char *ast_codec2str(format_t codec) { int x; char *ret = "unknown"; @@ -676,27 +679,30 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args * ast_cli(a->fd, "%11s %9s %10s TYPE %8s %s\n","INT","BINARY","HEX","NAME","DESC"); ast_cli(a->fd, "--------------------------------------------------------------------------------\n"); - if ((a->argc == 3) || (!strcasecmp(a->argv[3],"audio"))) { + if ((a->argc == 3) || (!strcasecmp(a->argv[3], "audio"))) { found = 1; - for (i=0;i<13;i++) { - snprintf(hex,25,"(0x%x)",1<<i); - ast_cli(a->fd, "%11u (1 << %2d) %10s audio %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i)); + for (i = 0; i < 48; i++) { + if (!((1LL << i) & AST_FORMAT_AUDIO_MASK)) { + continue; + } + snprintf(hex, sizeof(hex), "(0x%Lx)", 1LL << i); + ast_cli(a->fd, "%11Lu (1 << %2d) %10s audio %8s (%s)\n", 1LL << i, i, hex, ast_getformatname(1LL << i), ast_codec2str(1LL << i)); } } - if ((a->argc == 3) || (!strcasecmp(a->argv[3],"image"))) { + if ((a->argc == 3) || (!strcasecmp(a->argv[3], "image"))) { found = 1; - for (i=16;i<18;i++) { - snprintf(hex,25,"(0x%x)",1<<i); - ast_cli(a->fd, "%11u (1 << %2d) %10s image %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i)); + for (i = 16; i < 18; i++) { + snprintf(hex, sizeof(hex), "(0x%Lx)", 1LL << i); + ast_cli(a->fd, "%11Lu (1 << %2d) %10s image %8s (%s)\n", 1LL << i, i, hex, ast_getformatname(1LL << i), ast_codec2str(1LL << i)); } } - if ((a->argc == 3) || (!strcasecmp(a->argv[3],"video"))) { + if ((a->argc == 3) || (!strcasecmp(a->argv[3], "video"))) { found = 1; - for (i=18;i<22;i++) { - snprintf(hex,25,"(0x%x)",1<<i); - ast_cli(a->fd, "%11u (1 << %2d) %10s video %8s (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i)); + for (i = 18; i < 63; i++) { + snprintf(hex, sizeof(hex), "(0x%Lx)", 1LL << i); + ast_cli(a->fd, "%11Lu (1 << %2d) %10s video %8s (%s)\n", 1LL << i, i, hex, ast_getformatname(1LL << i), ast_codec2str(1LL << i)); } } @@ -708,12 +714,13 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args * static char *show_codec_n(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - int codec, i, found=0; + format_t codec; + int i, found = 0; switch (cmd) { case CLI_INIT: e->command = "core show codec"; - e->usage = + e->usage = "Usage: core show codec <number>\n" " Displays codec mapping\n"; return NULL; @@ -724,17 +731,17 @@ static char *show_codec_n(struct ast_cli_entry *e, int cmd, struct ast_cli_args if (a->argc != 4) return CLI_SHOWUSAGE; - if (sscanf(a->argv[3], "%30d", &codec) != 1) + if (sscanf(a->argv[3], "%30Ld", &codec) != 1) return CLI_SHOWUSAGE; - for (i = 0; i < 32; i++) - if (codec & (1 << i)) { + for (i = 0; i < 63; i++) + if (codec & (1LL << i)) { found = 1; - ast_cli(a->fd, "%11u (1 << %2d) %s\n",1 << i,i,ast_codec2str(1<<i)); + ast_cli(a->fd, "%11Lu (1 << %2d) %s\n", 1LL << i, i, ast_codec2str(1LL << i)); } if (!found) - ast_cli(a->fd, "Codec %d not found\n", codec); + ast_cli(a->fd, "Codec %Ld not found\n", codec); return CLI_SUCCESS; } @@ -772,17 +779,17 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) switch(f->frametype) { case AST_FRAME_DTMF_BEGIN: strcpy(ftype, "DTMF Begin"); - subclass[0] = f->subclass; + subclass[0] = f->subclass.integer; subclass[1] = '\0'; break; case AST_FRAME_DTMF_END: strcpy(ftype, "DTMF End"); - subclass[0] = f->subclass; + subclass[0] = f->subclass.integer; subclass[1] = '\0'; break; case AST_FRAME_CONTROL: strcpy(ftype, "Control"); - switch(f->subclass) { + switch (f->subclass.integer) { case AST_CONTROL_HANGUP: strcpy(subclass, "Hangup"); break; @@ -851,7 +858,7 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) strcpy(subclass, "Stop generators"); break; default: - snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass); + snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass.integer); } break; case AST_FRAME_NULL: @@ -861,7 +868,7 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) case AST_FRAME_IAX: /* Should never happen */ strcpy(ftype, "IAX Specific"); - snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass); + snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass.integer); break; case AST_FRAME_TEXT: strcpy(ftype, "Text"); @@ -870,11 +877,11 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) break; case AST_FRAME_IMAGE: strcpy(ftype, "Image"); - snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass)); + snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass.codec)); break; case AST_FRAME_HTML: strcpy(ftype, "HTML"); - switch(f->subclass) { + switch (f->subclass.integer) { case AST_HTML_URL: strcpy(subclass, "URL"); ast_copy_string(moreinfo, f->data.ptr, sizeof(moreinfo)); @@ -905,13 +912,13 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) strcpy(subclass, "Link Reject"); break; default: - snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass); + snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass.integer); break; } break; case AST_FRAME_MODEM: strcpy(ftype, "Modem"); - switch (f->subclass) { + switch (f->subclass.integer) { case AST_MODEM_T38: strcpy(subclass, "T.38"); break; @@ -919,7 +926,7 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) strcpy(subclass, "V.150"); break; default: - snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass); + snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass.integer); break; } break; @@ -932,7 +939,7 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)), f->frametype, term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)), - f->subclass, + f->subclass.integer, term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)), term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn))); else @@ -941,7 +948,7 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)), f->frametype, term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)), - f->subclass, + f->subclass.integer, term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn))); } @@ -970,11 +977,11 @@ void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, } else { to = pref->order; from = buf; - mem = 32; + mem = sizeof(format_t) * 8; } memset(to, 0, mem); - for (x = 0; x < 32 ; x++) { + for (x = 0; x < sizeof(format_t) * 8; x++) { if (!from[x]) break; to[x] = right ? (from[x] + differential) : (from[x] - differential); @@ -983,15 +990,16 @@ void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) { - int x, codec; + int x; + format_t codec; size_t total_len, slen; char *formatname; - memset(buf,0,size); + memset(buf, 0, size); total_len = size; buf[0] = '('; total_len--; - for(x = 0; x < 32 ; x++) { + for (x = 0; x < sizeof(format_t) * 8; x++) { if (total_len <= 0) break; if (!(codec = ast_codec_pref_index(pref,x))) @@ -1003,7 +1011,7 @@ int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) strncat(buf, formatname, total_len - 1); /* safe */ total_len -= slen; } - if (total_len && x < 31 && ast_codec_pref_index(pref , x + 1)) { + if (total_len && x < sizeof(format_t) * 8 - 1 && ast_codec_pref_index(pref, x + 1)) { strncat(buf, "|", total_len - 1); /* safe */ total_len--; } @@ -1016,7 +1024,7 @@ int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) return size - total_len; } -int ast_codec_pref_index(struct ast_codec_pref *pref, int idx) +format_t ast_codec_pref_index(struct ast_codec_pref *pref, int idx) { int slot = 0; @@ -1028,7 +1036,7 @@ int ast_codec_pref_index(struct ast_codec_pref *pref, int idx) } /*! \brief Remove codec from pref list */ -void ast_codec_pref_remove(struct ast_codec_pref *pref, int format) +void ast_codec_pref_remove(struct ast_codec_pref *pref, format_t format) { struct ast_codec_pref oldorder; int x, y = 0; @@ -1051,11 +1059,10 @@ void ast_codec_pref_remove(struct ast_codec_pref *pref, int format) pref->framing[y++] = size; } } - } /*! \brief Append codec to list */ -int ast_codec_pref_append(struct ast_codec_pref *pref, int format) +int ast_codec_pref_append(struct ast_codec_pref *pref, format_t format) { int x, newindex = 0; @@ -1081,7 +1088,7 @@ int ast_codec_pref_append(struct ast_codec_pref *pref, int format) } /*! \brief Prepend codec to list */ -void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing) +void ast_codec_pref_prepend(struct ast_codec_pref *pref, format_t format, int only_if_existing) { int x, newindex = 0; @@ -1097,7 +1104,7 @@ void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if return; /* Now find any existing occurrence, or the end */ - for (x = 0; x < 32; x++) { + for (x = 0; x < sizeof(format_t) * 8; x++) { if (!pref->order[x] || pref->order[x] == newindex) break; } @@ -1118,7 +1125,7 @@ void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if } /*! \brief Set packet size for codec */ -int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems) +int ast_codec_pref_setsize(struct ast_codec_pref *pref, format_t format, int framems) { int x, idx = -1; @@ -1156,7 +1163,7 @@ int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems) } /*! \brief Get packet size for codec */ -struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int format) +struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, format_t format) { int x, idx = -1, framems = 0; struct ast_format_list fmt = { 0, }; @@ -1195,9 +1202,10 @@ struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int f } /*! \brief Pick a codec */ -int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best) +format_t ast_codec_choose(struct ast_codec_pref *pref, format_t formats, int find_best) { - int x, ret = 0, slot; + int x, slot; + format_t ret = 0; for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) { slot = pref->order[x]; @@ -1217,11 +1225,11 @@ int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best) return find_best ? ast_best_codec(formats) : 0; } -int ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing) +int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const char *list, int allowing) { - int errors = 0; + int errors = 0, framems = 0; char *parse = NULL, *this = NULL, *psize = NULL; - int format = 0, framems = 0; + format_t format = 0; parse = ast_strdupa(list); while ((this = strsep(&parse, ","))) { @@ -1418,8 +1426,9 @@ static int speex_samples(unsigned char *data, int len) int ast_codec_get_samples(struct ast_frame *f) { int samples = 0; + char tmp[64]; - switch(f->subclass) { + switch (f->subclass.codec) { case AST_FORMAT_SPEEX: samples = speex_samples(f->data.ptr, f->datalen); break; @@ -1446,6 +1455,7 @@ int ast_codec_get_samples(struct ast_frame *f) break; case AST_FORMAT_ULAW: case AST_FORMAT_ALAW: + case AST_FORMAT_TESTLAW: samples = f->datalen; break; case AST_FORMAT_G722: @@ -1463,12 +1473,12 @@ int ast_codec_get_samples(struct ast_frame *f) samples = (int) f->datalen * ((float) 32000 / 6000); break; default: - ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass)); + ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), f->subclass.codec)); } return samples; } -int ast_codec_get_len(int format, int samples) +int ast_codec_get_len(format_t format, int samples) { int len = 0; @@ -1492,6 +1502,7 @@ int ast_codec_get_len(int format, int samples) break; case AST_FORMAT_ULAW: case AST_FORMAT_ALAW: + case AST_FORMAT_TESTLAW: len = samples; break; case AST_FORMAT_G722: @@ -1521,7 +1532,7 @@ int ast_frame_adjust_volume(struct ast_frame *f, int adjustment) short *fdata = f->data.ptr; short adjust_value = abs(adjustment); - if ((f->frametype != AST_FRAME_VOICE) || (f->subclass != AST_FORMAT_SLINEAR)) + if ((f->frametype != AST_FRAME_VOICE) || (f->subclass.codec != AST_FORMAT_SLINEAR)) return -1; if (!adjustment) @@ -1543,10 +1554,10 @@ int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2) int count; short *data1, *data2; - if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass != AST_FORMAT_SLINEAR)) + if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass.codec != AST_FORMAT_SLINEAR)) return -1; - if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass != AST_FORMAT_SLINEAR)) + if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass.codec != AST_FORMAT_SLINEAR)) return -1; if (f1->samples != f2->samples) |