00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "asterisk.h"
00027
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 334574 $")
00029
00030 #include "asterisk/_private.h"
00031 #include "asterisk/lock.h"
00032 #include "asterisk/frame.h"
00033 #include "asterisk/channel.h"
00034 #include "asterisk/cli.h"
00035 #include "asterisk/term.h"
00036 #include "asterisk/utils.h"
00037 #include "asterisk/threadstorage.h"
00038 #include "asterisk/linkedlists.h"
00039 #include "asterisk/translate.h"
00040 #include "asterisk/dsp.h"
00041 #include "asterisk/file.h"
00042
00043 #if !defined(LOW_MEMORY)
00044 static void frame_cache_cleanup(void *data);
00045
00046
00047 AST_THREADSTORAGE_CUSTOM(frame_cache, NULL, frame_cache_cleanup);
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #define FRAME_CACHE_MAX_SIZE 10
00059
00060
00061
00062 AST_LIST_HEAD_NOLOCK(ast_frames, ast_frame);
00063
00064 struct ast_frame_cache {
00065 struct ast_frames list;
00066 size_t size;
00067 };
00068 #endif
00069
00070 #define SMOOTHER_SIZE 8000
00071
00072 enum frame_type {
00073 TYPE_HIGH,
00074 TYPE_LOW,
00075 TYPE_SILENCE,
00076 TYPE_DONTSEND
00077 };
00078
00079 #define TYPE_MASK 0x3
00080
00081 struct ast_smoother {
00082 int size;
00083 struct ast_format format;
00084 int flags;
00085 float samplesperbyte;
00086 unsigned int opt_needs_swap:1;
00087 struct ast_frame f;
00088 struct timeval delivery;
00089 char data[SMOOTHER_SIZE];
00090 char framedata[SMOOTHER_SIZE + AST_FRIENDLY_OFFSET];
00091 struct ast_frame *opt;
00092 int len;
00093 };
00094
00095 struct ast_frame ast_null_frame = { AST_FRAME_NULL, };
00096
00097 static int smoother_frame_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
00098 {
00099 if (s->flags & AST_SMOOTHER_FLAG_G729) {
00100 if (s->len % 10) {
00101 ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
00102 return 0;
00103 }
00104 }
00105 if (swap) {
00106 ast_swapcopy_samples(s->data + s->len, f->data.ptr, f->samples);
00107 } else {
00108 memcpy(s->data + s->len, f->data.ptr, f->datalen);
00109 }
00110
00111 if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery)) {
00112 s->delivery = f->delivery;
00113 }
00114 s->len += f->datalen;
00115
00116 return 0;
00117 }
00118
00119 void ast_smoother_reset(struct ast_smoother *s, int bytes)
00120 {
00121 memset(s, 0, sizeof(*s));
00122 s->size = bytes;
00123 }
00124
00125 void ast_smoother_reconfigure(struct ast_smoother *s, int bytes)
00126 {
00127
00128 if (s->size == bytes) {
00129 return;
00130 }
00131
00132 s->size = bytes;
00133
00134
00135
00136 if (!s->opt) {
00137 return;
00138 }
00139
00140
00141
00142
00143 smoother_frame_feed(s, s->opt, s->opt_needs_swap);
00144 s->opt = NULL;
00145 }
00146
00147 struct ast_smoother *ast_smoother_new(int size)
00148 {
00149 struct ast_smoother *s;
00150 if (size < 1)
00151 return NULL;
00152 if ((s = ast_malloc(sizeof(*s))))
00153 ast_smoother_reset(s, size);
00154 return s;
00155 }
00156
00157 int ast_smoother_get_flags(struct ast_smoother *s)
00158 {
00159 return s->flags;
00160 }
00161
00162 void ast_smoother_set_flags(struct ast_smoother *s, int flags)
00163 {
00164 s->flags = flags;
00165 }
00166
00167 int ast_smoother_test_flag(struct ast_smoother *s, int flag)
00168 {
00169 return (s->flags & flag);
00170 }
00171
00172 int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
00173 {
00174 if (f->frametype != AST_FRAME_VOICE) {
00175 ast_log(LOG_WARNING, "Huh? Can't smooth a non-voice frame!\n");
00176 return -1;
00177 }
00178 if (!s->format.id) {
00179 ast_format_copy(&s->format, &f->subclass.format);
00180 s->samplesperbyte = (float)f->samples / (float)f->datalen;
00181 } else if (ast_format_cmp(&s->format, &f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
00182 ast_log(LOG_WARNING, "Smoother was working on %s format frames, now trying to feed %s?\n",
00183 ast_getformatname(&s->format), ast_getformatname(&f->subclass.format));
00184 return -1;
00185 }
00186 if (s->len + f->datalen > SMOOTHER_SIZE) {
00187 ast_log(LOG_WARNING, "Out of smoother space\n");
00188 return -1;
00189 }
00190 if (((f->datalen == s->size) ||
00191 ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729))) &&
00192 !s->opt &&
00193 !s->len &&
00194 (f->offset >= AST_MIN_OFFSET)) {
00195
00196
00197
00198 if (swap)
00199 ast_swapcopy_samples(f->data.ptr, f->data.ptr, f->samples);
00200 s->opt = f;
00201 s->opt_needs_swap = swap ? 1 : 0;
00202 return 0;
00203 }
00204
00205 return smoother_frame_feed(s, f, swap);
00206 }
00207
00208 struct ast_frame *ast_smoother_read(struct ast_smoother *s)
00209 {
00210 struct ast_frame *opt;
00211 int len;
00212
00213
00214 if (s->opt) {
00215 if (s->opt->offset < AST_FRIENDLY_OFFSET)
00216 ast_log(LOG_WARNING, "Returning a frame of inappropriate offset (%d).\n",
00217 s->opt->offset);
00218 opt = s->opt;
00219 s->opt = NULL;
00220 return opt;
00221 }
00222
00223
00224 if (s->len < s->size) {
00225
00226 if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->len % 10)))
00227 return NULL;
00228 }
00229 len = s->size;
00230 if (len > s->len)
00231 len = s->len;
00232
00233 s->f.frametype = AST_FRAME_VOICE;
00234 ast_format_copy(&s->f.subclass.format, &s->format);
00235 s->f.data.ptr = s->framedata + AST_FRIENDLY_OFFSET;
00236 s->f.offset = AST_FRIENDLY_OFFSET;
00237 s->f.datalen = len;
00238
00239 s->f.samples = len * s->samplesperbyte;
00240 s->f.delivery = s->delivery;
00241
00242 memcpy(s->f.data.ptr, s->data, len);
00243 s->len -= len;
00244
00245 if (s->len) {
00246
00247
00248 memmove(s->data, s->data + len, s->len);
00249 if (!ast_tvzero(s->delivery)) {
00250
00251 s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, ast_format_rate(&s->format)));
00252 }
00253 }
00254
00255 return &s->f;
00256 }
00257
00258 void ast_smoother_free(struct ast_smoother *s)
00259 {
00260 ast_free(s);
00261 }
00262
00263 static struct ast_frame *ast_frame_header_new(void)
00264 {
00265 struct ast_frame *f;
00266
00267 #if !defined(LOW_MEMORY)
00268 struct ast_frame_cache *frames;
00269
00270 if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
00271 if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) {
00272 size_t mallocd_len = f->mallocd_hdr_len;
00273 memset(f, 0, sizeof(*f));
00274 f->mallocd_hdr_len = mallocd_len;
00275 f->mallocd = AST_MALLOCD_HDR;
00276 frames->size--;
00277 return f;
00278 }
00279 }
00280 if (!(f = ast_calloc_cache(1, sizeof(*f))))
00281 return NULL;
00282 #else
00283 if (!(f = ast_calloc(1, sizeof(*f))))
00284 return NULL;
00285 #endif
00286
00287 f->mallocd_hdr_len = sizeof(*f);
00288
00289 return f;
00290 }
00291
00292 #if !defined(LOW_MEMORY)
00293 static void frame_cache_cleanup(void *data)
00294 {
00295 struct ast_frame_cache *frames = data;
00296 struct ast_frame *f;
00297
00298 while ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list)))
00299 ast_free(f);
00300
00301 ast_free(frames);
00302 }
00303 #endif
00304
00305 static void __frame_free(struct ast_frame *fr, int cache)
00306 {
00307 if (!fr->mallocd)
00308 return;
00309
00310 #if !defined(LOW_MEMORY)
00311 if (cache && fr->mallocd == AST_MALLOCD_HDR) {
00312
00313
00314 struct ast_frame_cache *frames;
00315
00316 if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames))) &&
00317 (frames->size < FRAME_CACHE_MAX_SIZE)) {
00318 AST_LIST_INSERT_HEAD(&frames->list, fr, frame_list);
00319 frames->size++;
00320 return;
00321 }
00322 }
00323 #endif
00324
00325 if (fr->mallocd & AST_MALLOCD_DATA) {
00326 if (fr->data.ptr)
00327 ast_free(fr->data.ptr - fr->offset);
00328 }
00329 if (fr->mallocd & AST_MALLOCD_SRC) {
00330 if (fr->src)
00331 ast_free((void *) fr->src);
00332 }
00333 if (fr->mallocd & AST_MALLOCD_HDR) {
00334 ast_free(fr);
00335 }
00336 }
00337
00338
00339 void ast_frame_free(struct ast_frame *frame, int cache)
00340 {
00341 struct ast_frame *next;
00342
00343 for (next = AST_LIST_NEXT(frame, frame_list);
00344 frame;
00345 frame = next, next = frame ? AST_LIST_NEXT(frame, frame_list) : NULL) {
00346 __frame_free(frame, cache);
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355 struct ast_frame *ast_frisolate(struct ast_frame *fr)
00356 {
00357 struct ast_frame *out;
00358 void *newdata;
00359
00360
00361
00362
00363 if (fr->mallocd == 0) {
00364 return ast_frdup(fr);
00365 }
00366
00367
00368 if ((fr->mallocd & (AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA)) ==
00369 (AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA)) {
00370 return fr;
00371 }
00372
00373 if (!(fr->mallocd & AST_MALLOCD_HDR)) {
00374
00375 if (!(out = ast_frame_header_new())) {
00376 return NULL;
00377 }
00378 out->frametype = fr->frametype;
00379 ast_format_copy(&out->subclass.format, &fr->subclass.format);
00380 out->datalen = fr->datalen;
00381 out->samples = fr->samples;
00382 out->offset = fr->offset;
00383
00384 ast_copy_flags(out, fr, AST_FLAGS_ALL);
00385 if (ast_test_flag(fr, AST_FRFLAG_HAS_TIMING_INFO)) {
00386 out->ts = fr->ts;
00387 out->len = fr->len;
00388 out->seqno = fr->seqno;
00389 }
00390 } else {
00391 out = fr;
00392 }
00393
00394 if (!(fr->mallocd & AST_MALLOCD_SRC) && fr->src) {
00395 if (!(out->src = ast_strdup(fr->src))) {
00396 if (out != fr) {
00397 ast_free(out);
00398 }
00399 return NULL;
00400 }
00401 } else {
00402 out->src = fr->src;
00403 fr->src = NULL;
00404 fr->mallocd &= ~AST_MALLOCD_SRC;
00405 }
00406
00407 if (!(fr->mallocd & AST_MALLOCD_DATA)) {
00408 if (!fr->datalen) {
00409 out->data.uint32 = fr->data.uint32;
00410 out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC;
00411 return out;
00412 }
00413 if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) {
00414 if (out->src != fr->src) {
00415 ast_free((void *) out->src);
00416 }
00417 if (out != fr) {
00418 ast_free(out);
00419 }
00420 return NULL;
00421 }
00422 newdata += AST_FRIENDLY_OFFSET;
00423 out->offset = AST_FRIENDLY_OFFSET;
00424 out->datalen = fr->datalen;
00425 memcpy(newdata, fr->data.ptr, fr->datalen);
00426 out->data.ptr = newdata;
00427 } else {
00428 out->data = fr->data;
00429 memset(&fr->data, 0, sizeof(fr->data));
00430 fr->mallocd &= ~AST_MALLOCD_DATA;
00431 }
00432
00433 out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
00434
00435 return out;
00436 }
00437
00438 struct ast_frame *ast_frdup(const struct ast_frame *f)
00439 {
00440 struct ast_frame *out = NULL;
00441 int len, srclen = 0;
00442 void *buf = NULL;
00443
00444 #if !defined(LOW_MEMORY)
00445 struct ast_frame_cache *frames;
00446 #endif
00447
00448
00449 len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
00450
00451
00452
00453
00454
00455 if (f->src)
00456 srclen = strlen(f->src);
00457 if (srclen > 0)
00458 len += srclen + 1;
00459
00460 #if !defined(LOW_MEMORY)
00461 if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
00462 AST_LIST_TRAVERSE_SAFE_BEGIN(&frames->list, out, frame_list) {
00463 if (out->mallocd_hdr_len >= len) {
00464 size_t mallocd_len = out->mallocd_hdr_len;
00465
00466 AST_LIST_REMOVE_CURRENT(frame_list);
00467 memset(out, 0, sizeof(*out));
00468 out->mallocd_hdr_len = mallocd_len;
00469 buf = out;
00470 frames->size--;
00471 break;
00472 }
00473 }
00474 AST_LIST_TRAVERSE_SAFE_END;
00475 }
00476 #endif
00477
00478 if (!buf) {
00479 if (!(buf = ast_calloc_cache(1, len)))
00480 return NULL;
00481 out = buf;
00482 out->mallocd_hdr_len = len;
00483 }
00484
00485 out->frametype = f->frametype;
00486 ast_format_copy(&out->subclass.format, &f->subclass.format);
00487 out->datalen = f->datalen;
00488 out->samples = f->samples;
00489 out->delivery = f->delivery;
00490
00491
00492 out->mallocd = AST_MALLOCD_HDR;
00493 out->offset = AST_FRIENDLY_OFFSET;
00494 if (out->datalen) {
00495 out->data.ptr = buf + sizeof(*out) + AST_FRIENDLY_OFFSET;
00496 memcpy(out->data.ptr, f->data.ptr, out->datalen);
00497 } else {
00498 out->data.uint32 = f->data.uint32;
00499 }
00500 if (srclen > 0) {
00501
00502 char *src;
00503 out->src = buf + sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
00504 src = (char *) out->src;
00505
00506 strcpy(src, f->src);
00507 }
00508 ast_copy_flags(out, f, AST_FLAGS_ALL);
00509 out->ts = f->ts;
00510 out->len = f->len;
00511 out->seqno = f->seqno;
00512 return out;
00513 }
00514
00515 void ast_swapcopy_samples(void *dst, const void *src, int samples)
00516 {
00517 int i;
00518 unsigned short *dst_s = dst;
00519 const unsigned short *src_s = src;
00520
00521 for (i = 0; i < samples; i++)
00522 dst_s[i] = (src_s[i]<<8) | (src_s[i]>>8);
00523 }
00524
00525
00526 void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
00527 {
00528 const char noname[] = "unknown";
00529 char ftype[40] = "Unknown Frametype";
00530 char cft[80];
00531 char subclass[40] = "Unknown Subclass";
00532 char csub[80];
00533 char moreinfo[40] = "";
00534 char cn[60];
00535 char cp[40];
00536 char cmn[40];
00537 const char *message = "Unknown";
00538
00539 if (!name)
00540 name = noname;
00541
00542
00543 if (!f) {
00544 ast_verbose("%s [ %s (NULL) ] [%s]\n",
00545 term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
00546 term_color(cft, "HANGUP", COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
00547 term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
00548 return;
00549 }
00550
00551 if (f->frametype == AST_FRAME_VOICE)
00552 return;
00553 if (f->frametype == AST_FRAME_VIDEO)
00554 return;
00555 switch(f->frametype) {
00556 case AST_FRAME_DTMF_BEGIN:
00557 strcpy(ftype, "DTMF Begin");
00558 subclass[0] = f->subclass.integer;
00559 subclass[1] = '\0';
00560 break;
00561 case AST_FRAME_DTMF_END:
00562 strcpy(ftype, "DTMF End");
00563 subclass[0] = f->subclass.integer;
00564 subclass[1] = '\0';
00565 break;
00566 case AST_FRAME_CONTROL:
00567 strcpy(ftype, "Control");
00568 switch (f->subclass.integer) {
00569 case AST_CONTROL_HANGUP:
00570 strcpy(subclass, "Hangup");
00571 break;
00572 case AST_CONTROL_RING:
00573 strcpy(subclass, "Ring");
00574 break;
00575 case AST_CONTROL_RINGING:
00576 strcpy(subclass, "Ringing");
00577 break;
00578 case AST_CONTROL_ANSWER:
00579 strcpy(subclass, "Answer");
00580 break;
00581 case AST_CONTROL_BUSY:
00582 strcpy(subclass, "Busy");
00583 break;
00584 case AST_CONTROL_TAKEOFFHOOK:
00585 strcpy(subclass, "Take Off Hook");
00586 break;
00587 case AST_CONTROL_OFFHOOK:
00588 strcpy(subclass, "Line Off Hook");
00589 break;
00590 case AST_CONTROL_CONGESTION:
00591 strcpy(subclass, "Congestion");
00592 break;
00593 case AST_CONTROL_FLASH:
00594 strcpy(subclass, "Flash");
00595 break;
00596 case AST_CONTROL_WINK:
00597 strcpy(subclass, "Wink");
00598 break;
00599 case AST_CONTROL_OPTION:
00600 strcpy(subclass, "Option");
00601 break;
00602 case AST_CONTROL_RADIO_KEY:
00603 strcpy(subclass, "Key Radio");
00604 break;
00605 case AST_CONTROL_RADIO_UNKEY:
00606 strcpy(subclass, "Unkey Radio");
00607 break;
00608 case AST_CONTROL_HOLD:
00609 strcpy(subclass, "Hold");
00610 break;
00611 case AST_CONTROL_UNHOLD:
00612 strcpy(subclass, "Unhold");
00613 break;
00614 case AST_CONTROL_T38_PARAMETERS:
00615 if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
00616 message = "Invalid";
00617 } else {
00618 struct ast_control_t38_parameters *parameters = f->data.ptr;
00619 enum ast_control_t38 state = parameters->request_response;
00620 if (state == AST_T38_REQUEST_NEGOTIATE)
00621 message = "Negotiation Requested";
00622 else if (state == AST_T38_REQUEST_TERMINATE)
00623 message = "Negotiation Request Terminated";
00624 else if (state == AST_T38_NEGOTIATED)
00625 message = "Negotiated";
00626 else if (state == AST_T38_TERMINATED)
00627 message = "Terminated";
00628 else if (state == AST_T38_REFUSED)
00629 message = "Refused";
00630 }
00631 snprintf(subclass, sizeof(subclass), "T38_Parameters/%s", message);
00632 break;
00633 case -1:
00634 strcpy(subclass, "Stop generators");
00635 break;
00636 default:
00637 snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass.integer);
00638 }
00639 break;
00640 case AST_FRAME_NULL:
00641 strcpy(ftype, "Null Frame");
00642 strcpy(subclass, "N/A");
00643 break;
00644 case AST_FRAME_IAX:
00645
00646 strcpy(ftype, "IAX Specific");
00647 snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass.integer);
00648 break;
00649 case AST_FRAME_TEXT:
00650 strcpy(ftype, "Text");
00651 strcpy(subclass, "N/A");
00652 ast_copy_string(moreinfo, f->data.ptr, sizeof(moreinfo));
00653 break;
00654 case AST_FRAME_IMAGE:
00655 strcpy(ftype, "Image");
00656 snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(&f->subclass.format));
00657 break;
00658 case AST_FRAME_HTML:
00659 strcpy(ftype, "HTML");
00660 switch (f->subclass.integer) {
00661 case AST_HTML_URL:
00662 strcpy(subclass, "URL");
00663 ast_copy_string(moreinfo, f->data.ptr, sizeof(moreinfo));
00664 break;
00665 case AST_HTML_DATA:
00666 strcpy(subclass, "Data");
00667 break;
00668 case AST_HTML_BEGIN:
00669 strcpy(subclass, "Begin");
00670 break;
00671 case AST_HTML_END:
00672 strcpy(subclass, "End");
00673 break;
00674 case AST_HTML_LDCOMPLETE:
00675 strcpy(subclass, "Load Complete");
00676 break;
00677 case AST_HTML_NOSUPPORT:
00678 strcpy(subclass, "No Support");
00679 break;
00680 case AST_HTML_LINKURL:
00681 strcpy(subclass, "Link URL");
00682 ast_copy_string(moreinfo, f->data.ptr, sizeof(moreinfo));
00683 break;
00684 case AST_HTML_UNLINK:
00685 strcpy(subclass, "Unlink");
00686 break;
00687 case AST_HTML_LINKREJECT:
00688 strcpy(subclass, "Link Reject");
00689 break;
00690 default:
00691 snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass.integer);
00692 break;
00693 }
00694 break;
00695 case AST_FRAME_MODEM:
00696 strcpy(ftype, "Modem");
00697 switch (f->subclass.integer) {
00698 case AST_MODEM_T38:
00699 strcpy(subclass, "T.38");
00700 break;
00701 case AST_MODEM_V150:
00702 strcpy(subclass, "V.150");
00703 break;
00704 default:
00705 snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass.integer);
00706 break;
00707 }
00708 break;
00709 default:
00710 snprintf(ftype, sizeof(ftype), "Unknown Frametype '%d'", f->frametype);
00711 }
00712 if (!ast_strlen_zero(moreinfo))
00713 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) '%s' ] [%s]\n",
00714 term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
00715 term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
00716 f->frametype,
00717 term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
00718 f->subclass.integer,
00719 term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)),
00720 term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
00721 else
00722 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) ] [%s]\n",
00723 term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
00724 term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
00725 f->frametype,
00726 term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
00727 f->subclass.integer,
00728 term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
00729 }
00730
00731 int ast_parse_allow_disallow(struct ast_codec_pref *pref, struct ast_format_cap *cap, const char *list, int allowing)
00732 {
00733 int errors = 0, framems = 0, all = 0, iter_allowing;
00734 char *parse = NULL, *this = NULL, *psize = NULL;
00735 struct ast_format format;
00736
00737 parse = ast_strdupa(list);
00738 while ((this = strsep(&parse, ","))) {
00739 iter_allowing = allowing;
00740 framems = 0;
00741 if (*this == '!') {
00742 this++;
00743 iter_allowing = !allowing;
00744 }
00745 if ((psize = strrchr(this, ':'))) {
00746 *psize++ = '\0';
00747 ast_debug(1, "Packetization for codec: %s is %s\n", this, psize);
00748 framems = atoi(psize);
00749 if (framems < 0) {
00750 framems = 0;
00751 errors++;
00752 ast_log(LOG_WARNING, "Bad packetization value for codec %s\n", this);
00753 }
00754 }
00755 all = strcasecmp(this, "all") ? 0 : 1;
00756
00757 if (!all && !ast_getformatbyname(this, &format)) {
00758 ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", iter_allowing ? "allow" : "disallow", this);
00759 errors++;
00760 continue;
00761 }
00762
00763 if (cap) {
00764 if (iter_allowing) {
00765 if (all) {
00766 ast_format_cap_add_all(cap);
00767 } else {
00768 ast_format_cap_add(cap, &format);
00769 }
00770 } else {
00771 if (all) {
00772 ast_format_cap_remove_all(cap);
00773 } else {
00774 ast_format_cap_remove(cap, &format);
00775 }
00776 }
00777 }
00778
00779 if (pref) {
00780 if (!all) {
00781 if (iter_allowing) {
00782 ast_codec_pref_append(pref, &format);
00783 ast_codec_pref_setsize(pref, &format, framems);
00784 } else {
00785 ast_codec_pref_remove(pref, &format);
00786 }
00787 } else if (!iter_allowing) {
00788 memset(pref, 0, sizeof(*pref));
00789 }
00790 }
00791 }
00792 return errors;
00793 }
00794
00795 static int g723_len(unsigned char buf)
00796 {
00797 enum frame_type type = buf & TYPE_MASK;
00798
00799 switch(type) {
00800 case TYPE_DONTSEND:
00801 return 0;
00802 break;
00803 case TYPE_SILENCE:
00804 return 4;
00805 break;
00806 case TYPE_HIGH:
00807 return 24;
00808 break;
00809 case TYPE_LOW:
00810 return 20;
00811 break;
00812 default:
00813 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", type);
00814 }
00815 return -1;
00816 }
00817
00818 static int g723_samples(unsigned char *buf, int maxlen)
00819 {
00820 int pos = 0;
00821 int samples = 0;
00822 int res;
00823 while(pos < maxlen) {
00824 res = g723_len(buf[pos]);
00825 if (res <= 0)
00826 break;
00827 samples += 240;
00828 pos += res;
00829 }
00830 return samples;
00831 }
00832
00833 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
00834 {
00835 int byte = bit / 8;
00836 int rem = 8 - (bit % 8);
00837 unsigned char ret = 0;
00838
00839 if (n <= 0 || n > 8)
00840 return 0;
00841
00842 if (rem < n) {
00843 ret = (data[byte] << (n - rem));
00844 ret |= (data[byte + 1] >> (8 - n + rem));
00845 } else {
00846 ret = (data[byte] >> (rem - n));
00847 }
00848
00849 return (ret & (0xff >> (8 - n)));
00850 }
00851
00852 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
00853 {
00854 static const int SpeexWBSubModeSz[] = {
00855 4, 36, 112, 192,
00856 352, 0, 0, 0 };
00857 int off = bit;
00858 unsigned char c;
00859
00860
00861 if (((len * 8 - off) >= 5) &&
00862 get_n_bits_at(data, 1, off)) {
00863 c = get_n_bits_at(data, 3, off + 1);
00864 off += SpeexWBSubModeSz[c];
00865
00866 if (((len * 8 - off) >= 5) &&
00867 get_n_bits_at(data, 1, off)) {
00868 c = get_n_bits_at(data, 3, off + 1);
00869 off += SpeexWBSubModeSz[c];
00870
00871 if (((len * 8 - off) >= 5) &&
00872 get_n_bits_at(data, 1, off)) {
00873 ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
00874 return -1;
00875 }
00876 }
00877
00878 }
00879 return off - bit;
00880 }
00881
00882 static int speex_samples(unsigned char *data, int len)
00883 {
00884 static const int SpeexSubModeSz[] = {
00885 5, 43, 119, 160,
00886 220, 300, 364, 492,
00887 79, 0, 0, 0,
00888 0, 0, 0, 0 };
00889 static const int SpeexInBandSz[] = {
00890 1, 1, 4, 4,
00891 4, 4, 4, 4,
00892 8, 8, 16, 16,
00893 32, 32, 64, 64 };
00894 int bit = 0;
00895 int cnt = 0;
00896 int off;
00897 unsigned char c;
00898
00899 while ((len * 8 - bit) >= 5) {
00900
00901 off = speex_get_wb_sz_at(data, len, bit);
00902 if (off < 0) {
00903 ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
00904 break;
00905 }
00906 bit += off;
00907
00908 if ((len * 8 - bit) < 5)
00909 break;
00910
00911
00912 c = get_n_bits_at(data, 5, bit);
00913 bit += 5;
00914
00915 if (c == 15) {
00916
00917 break;
00918 } else if (c == 14) {
00919
00920 c = get_n_bits_at(data, 4, bit);
00921 bit += 4;
00922 bit += SpeexInBandSz[c];
00923 } else if (c == 13) {
00924
00925 c = get_n_bits_at(data, 4, bit);
00926 bit += 4;
00927
00928 bit += 5 + c * 8;
00929 } else if (c > 8) {
00930
00931 ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
00932 break;
00933 } else {
00934
00935 bit += SpeexSubModeSz[c] - 5;
00936 cnt += 160;
00937 }
00938 }
00939 return cnt;
00940 }
00941
00942 int ast_codec_get_samples(struct ast_frame *f)
00943 {
00944 int samples = 0;
00945
00946 switch (f->subclass.format.id) {
00947 case AST_FORMAT_SPEEX:
00948 samples = speex_samples(f->data.ptr, f->datalen);
00949 break;
00950 case AST_FORMAT_SPEEX16:
00951 samples = 2 * speex_samples(f->data.ptr, f->datalen);
00952 break;
00953 case AST_FORMAT_SPEEX32:
00954 samples = 4 * speex_samples(f->data.ptr, f->datalen);
00955 break;
00956 case AST_FORMAT_G723_1:
00957 samples = g723_samples(f->data.ptr, f->datalen);
00958 break;
00959 case AST_FORMAT_ILBC:
00960 samples = 240 * (f->datalen / 50);
00961 break;
00962 case AST_FORMAT_GSM:
00963 samples = 160 * (f->datalen / 33);
00964 break;
00965 case AST_FORMAT_G729A:
00966 samples = f->datalen * 8;
00967 break;
00968 case AST_FORMAT_SLINEAR:
00969 case AST_FORMAT_SLINEAR16:
00970 samples = f->datalen / 2;
00971 break;
00972 case AST_FORMAT_LPC10:
00973
00974 samples = 22 * 8;
00975 samples += (((char *)(f->data.ptr))[7] & 0x1) * 8;
00976 break;
00977 case AST_FORMAT_ULAW:
00978 case AST_FORMAT_ALAW:
00979 case AST_FORMAT_TESTLAW:
00980 samples = f->datalen;
00981 break;
00982 case AST_FORMAT_G722:
00983 case AST_FORMAT_ADPCM:
00984 case AST_FORMAT_G726:
00985 case AST_FORMAT_G726_AAL2:
00986 samples = f->datalen * 2;
00987 break;
00988 case AST_FORMAT_SIREN7:
00989
00990 samples = f->datalen * (16000 / 4000);
00991 break;
00992 case AST_FORMAT_SIREN14:
00993
00994 samples = (int) f->datalen * ((float) 32000 / 6000);
00995 break;
00996 case AST_FORMAT_G719:
00997
00998 samples = (int) f->datalen * ((float) 48000 / 8000);
00999 break;
01000 case AST_FORMAT_SILK:
01001 if (!(ast_format_isset(&f->subclass.format,
01002 SILK_ATTR_KEY_SAMP_RATE,
01003 SILK_ATTR_VAL_SAMP_24KHZ,
01004 AST_FORMAT_ATTR_END))) {
01005 return 480;
01006 } else if (!(ast_format_isset(&f->subclass.format,
01007 SILK_ATTR_KEY_SAMP_RATE,
01008 SILK_ATTR_VAL_SAMP_16KHZ,
01009 AST_FORMAT_ATTR_END))) {
01010 return 320;
01011 } else if (!(ast_format_isset(&f->subclass.format,
01012 SILK_ATTR_KEY_SAMP_RATE,
01013 SILK_ATTR_VAL_SAMP_12KHZ,
01014 AST_FORMAT_ATTR_END))) {
01015 return 240;
01016 } else {
01017 return 160;
01018 }
01019 case AST_FORMAT_CELT:
01020
01021 samples = ast_format_rate(&f->subclass.format) / 50;
01022 break;
01023 default:
01024 ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(&f->subclass.format));
01025 }
01026 return samples;
01027 }
01028
01029 int ast_codec_get_len(struct ast_format *format, int samples)
01030 {
01031 int len = 0;
01032
01033
01034 switch(format->id) {
01035 case AST_FORMAT_G723_1:
01036 len = (samples / 240) * 20;
01037 break;
01038 case AST_FORMAT_ILBC:
01039 len = (samples / 240) * 50;
01040 break;
01041 case AST_FORMAT_GSM:
01042 len = (samples / 160) * 33;
01043 break;
01044 case AST_FORMAT_G729A:
01045 len = samples / 8;
01046 break;
01047 case AST_FORMAT_SLINEAR:
01048 case AST_FORMAT_SLINEAR16:
01049 len = samples * 2;
01050 break;
01051 case AST_FORMAT_ULAW:
01052 case AST_FORMAT_ALAW:
01053 case AST_FORMAT_TESTLAW:
01054 len = samples;
01055 break;
01056 case AST_FORMAT_G722:
01057 case AST_FORMAT_ADPCM:
01058 case AST_FORMAT_G726:
01059 case AST_FORMAT_G726_AAL2:
01060 len = samples / 2;
01061 break;
01062 case AST_FORMAT_SIREN7:
01063
01064 len = samples / (16000 / 4000);
01065 break;
01066 case AST_FORMAT_SIREN14:
01067
01068 len = (int) samples / ((float) 32000 / 6000);
01069 break;
01070 case AST_FORMAT_G719:
01071
01072 len = (int) samples / ((float) 48000 / 8000);
01073 break;
01074 default:
01075 ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
01076 }
01077
01078 return len;
01079 }
01080
01081 int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
01082 {
01083 int count;
01084 short *fdata = f->data.ptr;
01085 short adjust_value = abs(adjustment);
01086
01087 if ((f->frametype != AST_FRAME_VOICE) || !(ast_format_is_slinear(&f->subclass.format))) {
01088 return -1;
01089 }
01090
01091 if (!adjustment) {
01092 return 0;
01093 }
01094
01095 for (count = 0; count < f->samples; count++) {
01096 if (adjustment > 0) {
01097 ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
01098 } else if (adjustment < 0) {
01099 ast_slinear_saturated_divide(&fdata[count], &adjust_value);
01100 }
01101 }
01102
01103 return 0;
01104 }
01105
01106 int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
01107 {
01108 int count;
01109 short *data1, *data2;
01110
01111 if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass.format.id != AST_FORMAT_SLINEAR))
01112 return -1;
01113
01114 if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass.format.id != AST_FORMAT_SLINEAR))
01115 return -1;
01116
01117 if (f1->samples != f2->samples)
01118 return -1;
01119
01120 for (count = 0, data1 = f1->data.ptr, data2 = f2->data.ptr;
01121 count < f1->samples;
01122 count++, data1++, data2++)
01123 ast_slinear_saturated_add(data1, data2);
01124
01125 return 0;
01126 }
01127
01128 int ast_frame_clear(struct ast_frame *frame)
01129 {
01130 struct ast_frame *next;
01131
01132 for (next = AST_LIST_NEXT(frame, frame_list);
01133 frame;
01134 frame = next, next = frame ? AST_LIST_NEXT(frame, frame_list) : NULL) {
01135 memset(frame->data.ptr, 0, frame->datalen);
01136 }
01137 return 0;
01138 }