Asterisk - The Open Source Telephony Project GIT-master-7e7a603
main/frame.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Frame and codec manipulation routines
22 *
23 * \author Mark Spencer <markster@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include "asterisk/_private.h"
33#include "asterisk/lock.h"
34#include "asterisk/frame.h"
36#include "asterisk/channel.h"
37#include "asterisk/cli.h"
38#include "asterisk/term.h"
39#include "asterisk/utils.h"
42#include "asterisk/translate.h"
43#include "asterisk/dsp.h"
44#include "asterisk/file.h"
45
46#include <math.h>
47
48#if (defined(LOW_MEMORY) || defined(MALLOC_DEBUG)) && !defined(NO_FRAME_CACHE)
49#define NO_FRAME_CACHE
50#endif
51
52#if !defined(NO_FRAME_CACHE)
53static void frame_cache_cleanup(void *data);
54
55/*! \brief A per-thread cache of frame headers */
57
58/*!
59 * \brief Maximum ast_frame cache size
60 *
61 * In most cases where the frame header cache will be useful, the size
62 * of the cache will stay very small. However, it is not always the case that
63 * the same thread that allocates the frame will be the one freeing them, so
64 * sometimes a thread will never have any frames in its cache, or the cache
65 * will never be pulled from. For the latter case, we limit the maximum size.
66 */
67#define FRAME_CACHE_MAX_SIZE 10
68
69/*! \brief This is just so ast_frames, a list head struct for holding a list of
70 * ast_frame structures, is defined. */
72
75 size_t size;
76};
77#endif
78
80
81static struct ast_frame *ast_frame_header_new(const char *file, int line, const char *func)
82{
83 struct ast_frame *f;
84
85#if !defined(NO_FRAME_CACHE)
86 struct ast_frame_cache *frames;
87
88 if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
89 if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) {
90 size_t mallocd_len = f->mallocd_hdr_len;
91
92 memset(f, 0, sizeof(*f));
93 f->mallocd_hdr_len = mallocd_len;
94 frames->size--;
95 return f;
96 }
97 }
98#endif
99
100 if (!(f = __ast_calloc(1, sizeof(*f), file, line, func))) {
101 return NULL;
102 }
103
104 f->mallocd_hdr_len = sizeof(*f);
105
106 return f;
107}
108
109#if !defined(NO_FRAME_CACHE)
110static void frame_cache_cleanup(void *data)
111{
112 struct ast_frame_cache *frames = data;
113 struct ast_frame *f;
114
115 while ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list)))
116 ast_free(f);
117
119}
120#endif
121
122static void __frame_free(struct ast_frame *fr, int cache)
123{
124 if (!fr->mallocd)
125 return;
126
127#if !defined(NO_FRAME_CACHE)
128 if (fr->mallocd == AST_MALLOCD_HDR
129 && cache
131 /* Cool, only the header is malloc'd, let's just cache those for now
132 * to keep things simple... */
133 struct ast_frame_cache *frames;
134
136 if (frames && frames->size < FRAME_CACHE_MAX_SIZE) {
137 if (fr->frametype == AST_FRAME_VOICE
138 || fr->frametype == AST_FRAME_VIDEO
139 || fr->frametype == AST_FRAME_IMAGE) {
141 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_ANSWER) {
143 }
144
146 frames->size++;
147 return;
148 }
149 }
150#endif
151
152 if (fr->mallocd & AST_MALLOCD_DATA) {
153 if (fr->data.ptr) {
154 ast_free(fr->data.ptr - fr->offset);
155 }
156 }
157 if (fr->mallocd & AST_MALLOCD_SRC) {
158 ast_free((void *) fr->src);
159 }
160 if (fr->mallocd & AST_MALLOCD_HDR) {
161 if (fr->frametype == AST_FRAME_VOICE
162 || fr->frametype == AST_FRAME_VIDEO
163 || fr->frametype == AST_FRAME_IMAGE) {
165 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_ANSWER) {
167 }
168
169 ast_free(fr);
170 } else {
171 fr->mallocd = 0;
172 }
173}
174
175
176void ast_frame_free(struct ast_frame *frame, int cache)
177{
178 struct ast_frame *next;
179
180 while (frame) {
181 next = AST_LIST_NEXT(frame, frame_list);
182 __frame_free(frame, cache);
183 frame = next;
184 }
185}
186
188{
189 ast_frfree(f);
190}
191
192/*!
193 * \brief 'isolates' a frame by duplicating non-malloc'ed components
194 * (header, src, data).
195 * On return all components are malloc'ed
196 */
197struct ast_frame *__ast_frisolate(struct ast_frame *fr, const char *file, int line, const char *func)
198{
199 struct ast_frame *out;
200 void *newdata;
201
202 /* if none of the existing frame is malloc'd, let ast_frdup() do it
203 since it is more efficient
204 */
205 if (fr->mallocd == 0) {
206 return __ast_frdup(fr, file, line, func);
207 }
208
209 /* if everything is already malloc'd, we are done */
212 return fr;
213 }
214
215 if (!(fr->mallocd & AST_MALLOCD_HDR)) {
216 /* Allocate a new header if needed */
217 if (!(out = ast_frame_header_new(file, line, func))) {
218 return NULL;
219 }
220 out->frametype = fr->frametype;
221 out->subclass = fr->subclass;
222 if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) ||
223 (fr->frametype == AST_FRAME_IMAGE)) {
224 ao2_bump(out->subclass.format);
225 } else if (fr->frametype == AST_FRAME_VOICE && fr->subclass.integer == AST_CONTROL_ANSWER) {
226 ao2_bump(out->subclass.topology);
227 }
228 out->datalen = fr->datalen;
229 out->samples = fr->samples;
230 out->mallocd = AST_MALLOCD_HDR;
231 out->offset = fr->offset;
232 /* Copy the timing data */
235 out->ts = fr->ts;
236 out->len = fr->len;
237 out->seqno = fr->seqno;
238 }
239 out->stream_num = fr->stream_num;
240 } else {
241 out = fr;
242 }
243
244 if (fr->src) {
245 /* The original frame has a source string */
246 if (!(fr->mallocd & AST_MALLOCD_SRC)) {
247 /*
248 * The original frame has a non-malloced source string.
249 *
250 * Duplicate the string and put it into the isolated frame
251 * which may also be the original frame.
252 */
253 newdata = ast_strdup(fr->src);
254 if (!newdata) {
255 if (out != fr) {
257 }
258 return NULL;
259 }
260 out->src = newdata;
261 out->mallocd |= AST_MALLOCD_SRC;
262 } else if (out != fr) {
263 /* Steal the source string from the original frame. */
264 out->src = fr->src;
265 fr->src = NULL;
266 fr->mallocd &= ~AST_MALLOCD_SRC;
267 out->mallocd |= AST_MALLOCD_SRC;
268 }
269 }
270
271 if (!(fr->mallocd & AST_MALLOCD_DATA)) {
272 /* The original frame has a non-malloced data buffer. */
273 if (!fr->datalen && fr->frametype != AST_FRAME_TEXT) {
274 /* Actually it's just an int so we can simply copy it. */
275 out->data.uint32 = fr->data.uint32;
276 return out;
277 }
278 /*
279 * Duplicate the data buffer and put it into the isolated frame
280 * which may also be the original frame.
281 */
282 newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET);
283 if (!newdata) {
284 if (out != fr) {
286 }
287 return NULL;
288 }
289 newdata += AST_FRIENDLY_OFFSET;
290 out->offset = AST_FRIENDLY_OFFSET;
291 memcpy(newdata, fr->data.ptr, fr->datalen);
292 out->data.ptr = newdata;
293 out->mallocd |= AST_MALLOCD_DATA;
294 } else if (out != fr) {
295 /* Steal the data buffer from the original frame. */
296 out->data = fr->data;
297 memset(&fr->data, 0, sizeof(fr->data));
298 fr->mallocd &= ~AST_MALLOCD_DATA;
299 out->mallocd |= AST_MALLOCD_DATA;
300 }
301
302 return out;
303}
304
305struct ast_frame *__ast_frdup(const struct ast_frame *f, const char *file, int line, const char *func)
306{
307 struct ast_frame *out = NULL;
308 int len, srclen = 0;
309 void *buf = NULL;
310
311#if !defined(NO_FRAME_CACHE)
312 struct ast_frame_cache *frames;
313#endif
314
315 /* Start with standard stuff */
316 len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
317 /* If we have a source, add space for it */
318 /*
319 * XXX Watch out here - if we receive a src which is not terminated
320 * properly, we can be easily attacked. Should limit the size we deal with.
321 */
322 if (f->src)
323 srclen = strlen(f->src);
324 if (srclen > 0)
325 len += srclen + 1;
326
327#if !defined(NO_FRAME_CACHE)
328 if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
330 if (out->mallocd_hdr_len >= len) {
331 size_t mallocd_len = out->mallocd_hdr_len;
332
334 memset(out, 0, sizeof(*out));
335 out->mallocd_hdr_len = mallocd_len;
336 buf = out;
337 frames->size--;
338 break;
339 }
340 }
342 }
343#endif
344
345 if (!buf) {
346 if (!(buf = __ast_calloc(1, len, file, line, func)))
347 return NULL;
348 out = buf;
349 out->mallocd_hdr_len = len;
350 }
351
352 out->frametype = f->frametype;
353 out->subclass = f->subclass;
354 if ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO) ||
355 (f->frametype == AST_FRAME_IMAGE)) {
356 ao2_bump(out->subclass.format);
358 ao2_bump(out->subclass.topology);
359 }
360
361 out->datalen = f->datalen;
362 out->samples = f->samples;
363 out->delivery = f->delivery;
364 /* Even though this new frame was allocated from the heap, we can't mark it
365 * with AST_MALLOCD_HDR, AST_MALLOCD_DATA and AST_MALLOCD_SRC, because that
366 * would cause ast_frfree() to attempt to individually free each of those
367 * under the assumption that they were separately allocated. Since this frame
368 * was allocated in a single allocation, we'll only mark it as if the header
369 * was heap-allocated; this will result in the entire frame being properly freed.
370 */
371 out->mallocd = AST_MALLOCD_HDR;
372 out->offset = AST_FRIENDLY_OFFSET;
373 /* Make sure that empty text frames have a valid data.ptr */
374 if (out->datalen || f->frametype == AST_FRAME_TEXT) {
375 out->data.ptr = buf + sizeof(*out) + AST_FRIENDLY_OFFSET;
376 memcpy(out->data.ptr, f->data.ptr, out->datalen);
377 } else {
378 out->data.uint32 = f->data.uint32;
379 }
380 if (srclen > 0) {
381 /* This may seem a little strange, but it's to avoid a gcc (4.2.4) compiler warning */
382 char *src;
383 out->src = buf + sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
384 src = (char *) out->src;
385 /* Must have space since we allocated for it */
386 strcpy(src, f->src);
387 }
389 out->ts = f->ts;
390 out->len = f->len;
391 out->seqno = f->seqno;
392 out->stream_num = f->stream_num;
393 return out;
394}
395
396void ast_swapcopy_samples(void *dst, const void *src, int samples)
397{
398 int i;
399 unsigned short *dst_s = dst;
400 const unsigned short *src_s = src;
401
402 for (i = 0; i < samples; i++)
403 dst_s[i] = (src_s[i]<<8) | (src_s[i]>>8);
404}
405
406char *ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
407{
408 switch(f->frametype) {
410 if (slen > 1) {
411 subclass[0] = f->subclass.integer;
412 subclass[1] = '\0';
413 }
414 break;
416 if (slen > 1) {
417 subclass[0] = f->subclass.integer;
418 subclass[1] = '\0';
419 }
420 break;
422 switch (f->subclass.integer) {
424 ast_copy_string(subclass, "Hangup", slen);
425 break;
426 case AST_CONTROL_RING:
427 ast_copy_string(subclass, "Ring", slen);
428 break;
430 ast_copy_string(subclass, "Ringing", slen);
431 break;
433 ast_copy_string(subclass, "Answer", slen);
434 break;
435 case AST_CONTROL_BUSY:
436 ast_copy_string(subclass, "Busy", slen);
437 break;
439 ast_copy_string(subclass, "Take Off Hook", slen);
440 break;
442 ast_copy_string(subclass, "Line Off Hook", slen);
443 break;
445 ast_copy_string(subclass, "Congestion", slen);
446 break;
448 ast_copy_string(subclass, "Flash", slen);
449 break;
450 case AST_CONTROL_WINK:
451 ast_copy_string(subclass, "Wink", slen);
452 break;
454 ast_copy_string(subclass, "Option", slen);
455 break;
457 ast_copy_string(subclass, "Key Radio", slen);
458 break;
460 ast_copy_string(subclass, "Unkey Radio", slen);
461 break;
463 ast_copy_string(subclass, "Progress", slen);
464 break;
466 ast_copy_string(subclass, "Proceeding", slen);
467 break;
468 case AST_CONTROL_HOLD:
469 ast_copy_string(subclass, "Hold", slen);
470 break;
472 ast_copy_string(subclass, "Unhold", slen);
473 break;
475 ast_copy_string(subclass, "Video Update", slen);
476 break;
478 char *message = "Unknown";
479 if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
480 message = "Invalid";
481 } else {
482 struct ast_control_t38_parameters *parameters = f->data.ptr;
483 enum ast_control_t38 state = parameters->request_response;
485 message = "Negotiation Requested";
487 message = "Negotiation Request Terminated";
488 else if (state == AST_T38_NEGOTIATED)
489 message = "Negotiated";
490 else if (state == AST_T38_TERMINATED)
491 message = "Terminated";
492 else if (state == AST_T38_REFUSED)
493 message = "Refused";
494 }
495 snprintf(subclass, slen, "T38_Parameters/%s", message);
496 break;
497 }
498
500 ast_copy_string(subclass, "Stop stream", slen);
501 break;
503 ast_copy_string(subclass, "Suspend stream", slen);
504 break;
506 ast_copy_string(subclass, "Restart stream", slen);
507 break;
509 ast_copy_string(subclass, "Reverse stream", slen);
510 break;
512 ast_copy_string(subclass, "Forward stream", slen);
513 break;
515 ast_copy_string(subclass, "Cancel stream", slen);
516 break;
518 ast_copy_string(subclass, "Record stop", slen);
519 break;
521 ast_copy_string(subclass, "Record suspend", slen);
522 break;
524 ast_copy_string(subclass, "Record mute", slen);
525 break;
527 ast_copy_string(subclass, "Media source update", slen);
528 break;
530 ast_copy_string(subclass, "Transfer", slen);
531 break;
533 ast_copy_string(subclass, "Connected line update", slen);
534 break;
536 ast_copy_string(subclass, "Redirect", slen);
537 break;
538 case AST_CONTROL_CC:
539 ast_copy_string(subclass, "CC", slen);
540 break;
542 ast_copy_string(subclass, "Media SSRC change", slen);
543 break;
545 ast_copy_string(subclass, "Read action", slen);
546 break;
547 case AST_CONTROL_AOC:
548 ast_copy_string(subclass, "AOC", slen);
549 break;
551 ast_copy_string(subclass, "Endof Q", slen);
552 break;
554 ast_copy_string(subclass, "Incomplete", slen);
555 break;
556 case AST_CONTROL_MCID:
557 ast_copy_string(subclass, "MCID", slen);
558 break;
560 ast_copy_string(subclass, "Update RTP peer", slen);
561 break;
563 ast_copy_string(subclass, "Private Cause Code", slen);
564 break;
566 ast_copy_string(subclass, "Masquerade notify", slen);
567 break;
569 ast_copy_string(subclass, "Stream topology request change", slen);
570 break;
572 ast_copy_string(subclass, "Stream topology changed", slen);
573 break;
575 ast_copy_string(subclass, "Stream topology source changed", slen);
576 break;
577 case -1:
578 ast_copy_string(subclass, "Stop generators", slen);
579 break;
580 default:
581 snprintf(subclass, slen, "Unknown control '%d'", f->subclass.integer);
582 }
583 break;
584 case AST_FRAME_NULL:
585 ast_copy_string(subclass, "N/A", slen);
586 break;
587 case AST_FRAME_IAX:
588 /* Should never happen */
589 snprintf(subclass, slen, "IAX Frametype %d", f->subclass.integer);
590 break;
592 /* Should never happen */
593 snprintf(subclass, slen, "Bridge Frametype %d", f->subclass.integer);
594 break;
596 /* Should never happen */
597 snprintf(subclass, slen, "Synchronous Bridge Frametype %d", f->subclass.integer);
598 break;
599 case AST_FRAME_TEXT:
600 ast_copy_string(subclass, "N/A", slen);
601 if (moreinfo) {
602 ast_copy_string(moreinfo, f->data.ptr, mlen);
603 }
604 break;
605 case AST_FRAME_IMAGE:
606 snprintf(subclass, slen, "Image format %s\n", ast_format_get_name(f->subclass.format));
607 break;
608 case AST_FRAME_HTML:
609 switch (f->subclass.integer) {
610 case AST_HTML_URL:
611 ast_copy_string(subclass, "URL", slen);
612 if (moreinfo) {
613 ast_copy_string(moreinfo, f->data.ptr, mlen);
614 }
615 break;
616 case AST_HTML_DATA:
617 ast_copy_string(subclass, "Data", slen);
618 break;
619 case AST_HTML_BEGIN:
620 ast_copy_string(subclass, "Begin", slen);
621 break;
622 case AST_HTML_END:
623 ast_copy_string(subclass, "End", slen);
624 break;
626 ast_copy_string(subclass, "Load Complete", slen);
627 break;
629 ast_copy_string(subclass, "No Support", slen);
630 break;
631 case AST_HTML_LINKURL:
632 ast_copy_string(subclass, "Link URL", slen);
633 if (moreinfo) {
634 ast_copy_string(moreinfo, f->data.ptr, mlen);
635 }
636 break;
637 case AST_HTML_UNLINK:
638 ast_copy_string(subclass, "Unlink", slen);
639 break;
641 ast_copy_string(subclass, "Link Reject", slen);
642 break;
643 default:
644 snprintf(subclass, slen, "Unknown HTML frame '%d'\n", f->subclass.integer);
645 break;
646 }
647 break;
648 case AST_FRAME_MODEM:
649 switch (f->subclass.integer) {
650 case AST_MODEM_T38:
651 ast_copy_string(subclass, "T.38", slen);
652 break;
653 case AST_MODEM_V150:
654 ast_copy_string(subclass, "V.150", slen);
655 break;
656 default:
657 snprintf(subclass, slen, "Unknown MODEM frame '%d'\n", f->subclass.integer);
658 break;
659 }
660 break;
661 case AST_FRAME_RTCP:
662 ast_copy_string(subclass, "RTCP", slen);
663 default:
664 ast_copy_string(subclass, "Unknown Subclass", slen);
665 break;
666 }
667
668 return subclass;
669}
670
671char *ast_frame_type2str(enum ast_frame_type frame_type, char *ftype, size_t len)
672{
673 switch (frame_type) {
675 ast_copy_string(ftype, "DTMF Begin", len);
676 break;
678 ast_copy_string(ftype, "DTMF End", len);
679 break;
681 ast_copy_string(ftype, "Control", len);
682 break;
683 case AST_FRAME_NULL:
684 ast_copy_string(ftype, "Null Frame", len);
685 break;
686 case AST_FRAME_IAX:
687 /* Should never happen */
688 ast_copy_string(ftype, "IAX Specific", len);
689 break;
691 /* Should never happen */
692 ast_copy_string(ftype, "Bridge Specific", len);
693 break;
695 /* Should never happen */
696 ast_copy_string(ftype, "Bridge Specific", len);
697 break;
698 case AST_FRAME_TEXT:
699 ast_copy_string(ftype, "Text", len);
700 break;
702 ast_copy_string(ftype, "Text Data", len);
703 break;
704 case AST_FRAME_IMAGE:
705 ast_copy_string(ftype, "Image", len);
706 break;
707 case AST_FRAME_HTML:
708 ast_copy_string(ftype, "HTML", len);
709 break;
710 case AST_FRAME_MODEM:
711 ast_copy_string(ftype, "Modem", len);
712 break;
713 case AST_FRAME_VOICE:
714 ast_copy_string(ftype, "Voice", len);
715 break;
716 case AST_FRAME_VIDEO:
717 ast_copy_string(ftype, "Video", len);
718 break;
719 case AST_FRAME_RTCP:
720 ast_copy_string(ftype, "RTCP", len);
721 break;
722 default:
723 snprintf(ftype, len, "Unknown Frametype '%u'", frame_type);
724 break;
725 }
726
727 return ftype;
728}
729
730/*! Dump a frame for debugging purposes */
731void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
732{
733 const char noname[] = "unknown";
734 char ftype[40] = "Unknown Frametype";
735 char cft[80];
736 char subclass[40] = "Unknown Subclass";
737 char csub[80];
738 char moreinfo[40] = "";
739 char cn[60];
740 char cp[40];
741 char cmn[40];
742
743 if (!name) {
744 name = noname;
745 }
746
747 if (!f) {
748 ast_verb(-1, "%s [ %s (NULL) ] [%s]\n",
749 term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
750 term_color(cft, "HANGUP", COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
751 term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
752 return;
753 }
754 /* XXX We should probably print one each of voice and video when the format changes XXX */
755 if (f->frametype == AST_FRAME_VOICE) {
756 return;
757 }
758 if (f->frametype == AST_FRAME_VIDEO) {
759 return;
760 }
761 if (f->frametype == AST_FRAME_RTCP) {
762 return;
763 }
764
765 ast_frame_type2str(f->frametype, ftype, sizeof(ftype));
766 ast_frame_subclass2str(f, subclass, sizeof(subclass), moreinfo, sizeof(moreinfo));
767
768 if (!ast_strlen_zero(moreinfo))
769 ast_verb(-1, "%s [ TYPE: %s (%u) SUBCLASS: %s (%d) '%s' ] [%s]\n",
770 term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
771 term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
772 f->frametype,
773 term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
774 f->subclass.integer,
775 term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)),
776 term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
777 else
778 ast_verb(-1, "%s [ TYPE: %s (%u) SUBCLASS: %s (%d) ] [%s]\n",
779 term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
780 term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
781 f->frametype,
782 term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
783 f->subclass.integer,
784 term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
785}
786
787int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
788{
789 int count;
790 short *fdata = f->data.ptr;
791 short adjust_value = abs(adjustment);
792
794 return -1;
795 }
796
797 if (!adjustment) {
798 return 0;
799 }
800
801 for (count = 0; count < f->samples; count++) {
802 if (adjustment > 0) {
803 ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
804 } else if (adjustment < 0) {
805 ast_slinear_saturated_divide(&fdata[count], &adjust_value);
806 }
807 }
808
809 return 0;
810}
811
812int ast_frame_adjust_volume_float(struct ast_frame *f, float adjustment)
813{
814 int count;
815 short *fdata = f->data.ptr;
816 float adjust_value = fabs(adjustment);
817
819 return -1;
820 }
821
822 if (!adjustment) {
823 return 0;
824 }
825
826 for (count = 0; count < f->samples; count++) {
827 if (adjustment > 0) {
828 ast_slinear_saturated_multiply_float(&fdata[count], &adjust_value);
829 } else if (adjustment < 0) {
830 ast_slinear_saturated_divide_float(&fdata[count], &adjust_value);
831 }
832 }
833
834 return 0;
835}
836
837int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
838{
839 int count;
840 short *data1, *data2;
841
843 return -1;
844
846 return -1;
847
848 if (f1->samples != f2->samples)
849 return -1;
850
851 for (count = 0, data1 = f1->data.ptr, data2 = f2->data.ptr;
852 count < f1->samples;
853 count++, data1++, data2++)
854 ast_slinear_saturated_add(data1, data2);
855
856 return 0;
857}
858
859int ast_frame_clear(struct ast_frame *frame)
860{
861 struct ast_frame *next;
862
863 for (next = AST_LIST_NEXT(frame, frame_list);
864 frame;
865 frame = next, next = frame ? AST_LIST_NEXT(frame, frame_list) : NULL) {
866 memset(frame->data.ptr, 0, frame->datalen);
867 }
868 return 0;
869}
Prototypes for public functions only of internal interest,.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc
Definition: astmm.c:1603
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
General Asterisk PBX channel definitions.
Standard Command Line Interface.
frame_type
Definition: codec_builtin.c:44
Convenient Signal Processing routines.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define abs(x)
Definition: f2c.h:195
Generic File Format Support. Should be included by clients of the file handling routines....
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Media Format Cache API.
int ast_format_cache_is_slinear(struct ast_format *format)
Determines if a format is one of the cached slin formats.
Definition: format_cache.c:534
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
static const char name[]
Definition: format_mp3.c:68
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char prefix[MAX_PREFIX]
Definition: http.c:144
Asterisk internal frame definitions.
@ AST_FRFLAG_HAS_TIMING_INFO
@ AST_T38_TERMINATED
@ AST_T38_REFUSED
@ AST_T38_REQUEST_TERMINATE
@ AST_T38_NEGOTIATED
@ AST_T38_REQUEST_NEGOTIATE
#define AST_HTML_UNLINK
#define AST_MALLOCD_HDR
#define AST_MODEM_T38
#define AST_HTML_LINKURL
#define ast_frfree(fr)
#define AST_HTML_URL
#define AST_MALLOCD_DATA
#define AST_HTML_NOSUPPORT
#define AST_HTML_LDCOMPLETE
#define AST_MALLOCD_SRC
#define AST_HTML_END
#define AST_HTML_DATA
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define AST_HTML_LINKREJECT
#define AST_MODEM_V150
#define AST_HTML_BEGIN
ast_frame_type
Frame types.
@ AST_FRAME_VIDEO
@ AST_FRAME_NULL
@ AST_FRAME_HTML
@ AST_FRAME_IMAGE
@ AST_FRAME_DTMF_END
@ AST_FRAME_DTMF_BEGIN
@ AST_FRAME_BRIDGE_ACTION_SYNC
@ AST_FRAME_VOICE
@ AST_FRAME_RTCP
@ AST_FRAME_MODEM
@ AST_FRAME_TEXT_DATA
@ AST_FRAME_CONTROL
@ AST_FRAME_BRIDGE_ACTION
@ AST_FRAME_TEXT
@ AST_CONTROL_RING
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_RECORD_CANCEL
@ AST_CONTROL_WINK
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED
@ AST_CONTROL_OFFHOOK
@ AST_CONTROL_STREAM_RESTART
@ AST_CONTROL_STREAM_SUSPEND
@ AST_CONTROL_RADIO_UNKEY
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_TAKEOFFHOOK
@ AST_CONTROL_MCID
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_READ_ACTION
@ AST_CONTROL_RECORD_STOP
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_CC
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RECORD_MUTE
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_STREAM_STOP
@ AST_CONTROL_RADIO_KEY
@ AST_CONTROL_HOLD
@ AST_CONTROL_OPTION
@ AST_CONTROL_STREAM_TOPOLOGY_CHANGED
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_END_OF_Q
@ AST_CONTROL_TRANSFER
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_RECORD_SUSPEND
@ AST_CONTROL_AOC
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
#define ast_verb(level,...)
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Definition: linkedlists.h:225
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
Asterisk locking-related definitions:
void ast_frame_dtor(struct ast_frame *f)
NULL-safe wrapper for ast_frfree, good for RAII_VAR.
Definition: main/frame.c:187
static struct ast_threadstorage frame_cache
Definition: main/frame.c:56
int ast_frame_clear(struct ast_frame *frame)
Clear all audio samples from an ast_frame. The frame must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR.
Definition: main/frame.c:859
static struct ast_frame * ast_frame_header_new(const char *file, int line, const char *func)
Definition: main/frame.c:81
struct ast_frame * __ast_frdup(const struct ast_frame *f, const char *file, int line, const char *func)
Definition: main/frame.c:305
void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
Definition: main/frame.c:731
void ast_frame_free(struct ast_frame *frame, int cache)
Frees a frame or list of frames.
Definition: main/frame.c:176
char * ast_frame_type2str(enum ast_frame_type frame_type, char *ftype, size_t len)
Copy the discription of a frame type into the provided string.
Definition: main/frame.c:671
#define FRAME_CACHE_MAX_SIZE
Maximum ast_frame cache size.
Definition: main/frame.c:67
int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: main/frame.c:787
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame's subclass into the provided string.
Definition: main/frame.c:406
static void __frame_free(struct ast_frame *fr, int cache)
Definition: main/frame.c:122
struct ast_frame * __ast_frisolate(struct ast_frame *fr, const char *file, int line, const char *func)
'isolates' a frame by duplicating non-malloc'ed components (header, src, data). On return all compone...
Definition: main/frame.c:197
int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
Sums two frames of audio samples.
Definition: main/frame.c:837
int ast_frame_adjust_volume_float(struct ast_frame *f, float adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: main/frame.c:812
void ast_swapcopy_samples(void *dst, const void *src, int samples)
Definition: main/frame.c:396
static void frame_cache_cleanup(void *data)
Definition: main/frame.c:110
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_opt_cache_media_frames
Definition: options.h:121
static int frames
Definition: parser.c:51
struct ao2_container * cache
Definition: pbx_realtime.c:77
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
enum ast_control_t38 request_response
struct ast_frames list
Definition: main/frame.c:74
struct ast_stream_topology * topology
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
struct timeval delivery
enum ast_frame_type frametype
struct ast_frame * next
const char * src
This is just so ast_frames, a list head struct for holding a list of ast_frame structures,...
Definition: main/frame.c:71
Handy terminal functions for vt* terms.
#define COLOR_BRGREEN
Definition: term.h:55
#define COLOR_BRRED
Definition: term.h:53
#define COLOR_BRCYAN
Definition: term.h:63
#define COLOR_YELLOW
Definition: term.h:57
#define COLOR_BLACK
Definition: term.h:50
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:235
#define COLOR_BRMAGENTA
Definition: term.h:61
Definitions to aid in the use of thread local storage.
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
Support for translation of data formats. translate.c.
FILE * out
Definition: utils/frame.c:33
Utility functions.
#define ast_test_flag(p, flag)
Definition: utils.h:63
static force_inline void ast_slinear_saturated_divide_float(short *input, float *value)
Definition: utils.h:507
static force_inline void ast_slinear_saturated_multiply_float(short *input, float *value)
Definition: utils.h:489
static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
Definition: utils.h:476
static force_inline void ast_slinear_saturated_add(short *input, short *value)
Definition: utils.h:450
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
static force_inline void ast_slinear_saturated_divide(short *input, short *value)
Definition: utils.h:502
#define AST_FLAGS_ALL
Definition: utils.h:196