0cc44a7ebac01ba8f42cf651c2ca99a0059af69a
[asterisk/asterisk.git] / main / frame.c
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 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <stdio.h>
35
36 #include "asterisk/lock.h"
37 #include "asterisk/frame.h"
38 #include "asterisk/logger.h"
39 #include "asterisk/options.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/cli.h"
42 #include "asterisk/term.h"
43 #include "asterisk/utils.h"
44
45 #ifdef TRACE_FRAMES
46 static int headers = 0;
47 static struct ast_frame *headerlist = NULL;
48 AST_MUTEX_DEFINE_STATIC(framelock);
49 #endif
50
51 #define SMOOTHER_SIZE 8000
52
53 enum frame_type {
54         TYPE_HIGH,     /* 0x0 */
55         TYPE_LOW,      /* 0x1 */
56         TYPE_SILENCE,  /* 0x2 */
57         TYPE_DONTSEND  /* 0x3 */
58 };
59
60 #define TYPE_MASK 0x3
61
62 struct ast_smoother {
63         int size;
64         int format;
65         int readdata;
66         int optimizablestream;
67         int flags;
68         float samplesperbyte;
69         struct ast_frame f;
70         struct timeval delivery;
71         char data[SMOOTHER_SIZE];
72         char framedata[SMOOTHER_SIZE + AST_FRIENDLY_OFFSET];
73         struct ast_frame *opt;
74         int len;
75 };
76
77 /*! \brief Definition of supported media formats (codecs) */
78 static struct ast_format_list {
79         int visible;    /*!< Can we see this entry */
80         int bits;       /*!< bitmask value */
81         char *name;     /*!< short name */
82         char *desc;     /*!< Description */
83 } AST_FORMAT_LIST[] = {                                 /*!< Bit number: comment  - Bit numbers are hard coded in show_codec() */
84         { 1, AST_FORMAT_G723_1 , "g723" , "G.723.1"},   /*!<  1 */
85         { 1, AST_FORMAT_GSM, "gsm" , "GSM"},            /*!<  2: codec_gsm.c */
86         { 1, AST_FORMAT_ULAW, "ulaw", "G.711 u-law" },  /*!<  3: codec_ulaw.c */
87         { 1, AST_FORMAT_ALAW, "alaw", "G.711 A-law" },  /*!<  4: codec_alaw.c */
88         { 1, AST_FORMAT_G726, "g726", "G.726 RFC3551" },/*!<  5: codec_g726.c */
89         { 1, AST_FORMAT_ADPCM, "adpcm" , "ADPCM"},      /*!<  6: codec_adpcm.c */
90         { 1, AST_FORMAT_SLINEAR, "slin",  "16 bit Signed Linear PCM"},  /*!< 7 */
91         { 1, AST_FORMAT_LPC10, "lpc10", "LPC10" },      /*!<  8: codec_lpc10.c */
92         { 1, AST_FORMAT_G729A, "g729", "G.729A" },      /*!<  9: Binary commercial distribution */
93         { 1, AST_FORMAT_SPEEX, "speex", "SpeeX" },      /*!< 10: codec_speex.c */
94         { 1, AST_FORMAT_ILBC, "ilbc", "iLBC"},          /*!< 11: codec_ilbc.c */
95         { 1, AST_FORMAT_G726_AAL2, "g726aal2", "G.726 AAL2" },  /*!<  12: codec_g726.c */
96         { 0, 0, "nothing", "undefined" },
97         { 0, 0, "nothing", "undefined" },
98         { 0, 0, "nothing", "undefined" },
99         { 0, 0, "nothing", "undefined" },
100         { 0, AST_FORMAT_MAX_AUDIO, "maxaudio", "Maximum audio format" },        
101         { 1, AST_FORMAT_JPEG, "jpeg", "JPEG image"},    /*!< 17: See format_jpeg.c */
102         { 1, AST_FORMAT_PNG, "png", "PNG image"},       /*!< 18: Image format */
103         { 1, AST_FORMAT_H261, "h261", "H.261 Video" },  /*!< 19: Video Passthrough */
104         { 1, AST_FORMAT_H263, "h263", "H.263 Video" },  /*!< 20: Passthrough support, see format_h263.c */
105         { 1, AST_FORMAT_H263_PLUS, "h263p", "H.263+ Video" },   /*!< 21: See format_h263.c */
106         { 1, AST_FORMAT_H264, "h264", "H.264 Video" },  /*!< 22: Passthrough support, see format_h263.c */
107         { 0, 0, "nothing", "undefined" },
108         { 0, 0, "nothing", "undefined" },
109         { 0, 0, "nothing", "undefined" },
110         { 0, AST_FORMAT_MAX_VIDEO, "maxvideo", "Maximum video format" },
111 };
112
113 struct ast_frame ast_null_frame = { AST_FRAME_NULL, };
114
115 void ast_smoother_reset(struct ast_smoother *s, int size)
116 {
117         memset(s, 0, sizeof(*s));
118         s->size = size;
119 }
120
121 struct ast_smoother *ast_smoother_new(int size)
122 {
123         struct ast_smoother *s;
124         if (size < 1)
125                 return NULL;
126         if ((s = ast_malloc(sizeof(*s))))
127                 ast_smoother_reset(s, size);
128         return s;
129 }
130
131 int ast_smoother_get_flags(struct ast_smoother *s)
132 {
133         return s->flags;
134 }
135
136 void ast_smoother_set_flags(struct ast_smoother *s, int flags)
137 {
138         s->flags = flags;
139 }
140
141 int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
142 {
143         if (f->frametype != AST_FRAME_VOICE) {
144                 ast_log(LOG_WARNING, "Huh?  Can't smooth a non-voice frame!\n");
145                 return -1;
146         }
147         if (!s->format) {
148                 s->format = f->subclass;
149                 s->samplesperbyte = (float)f->samples / (float)f->datalen;
150         } else if (s->format != f->subclass) {
151                 ast_log(LOG_WARNING, "Smoother was working on %d format frames, now trying to feed %d?\n", s->format, f->subclass);
152                 return -1;
153         }
154         if (s->len + f->datalen > SMOOTHER_SIZE) {
155                 ast_log(LOG_WARNING, "Out of smoother space\n");
156                 return -1;
157         }
158         if (((f->datalen == s->size) || ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729)))
159                                  && !s->opt && (f->offset >= AST_MIN_OFFSET)) {
160                 if (!s->len) {
161                         /* Optimize by sending the frame we just got
162                            on the next read, thus eliminating the douple
163                            copy */
164                         s->opt = f;
165                         return 0;
166                 } else {
167                         s->optimizablestream++;
168                         if (s->optimizablestream > 10) {
169                                 /* For the past 10 rounds, we have input and output
170                                    frames of the correct size for this smoother, yet
171                                    we were unable to optimize because there was still
172                                    some cruft left over.  Lets just drop the cruft so
173                                    we can move to a fully optimized path */
174                                 s->len = 0;
175                                 s->opt = f;
176                                 return 0;
177                         }
178                 }
179         } else 
180                 s->optimizablestream = 0;
181         if (s->flags & AST_SMOOTHER_FLAG_G729) {
182                 if (s->len % 10) {
183                         ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
184                         return 0;
185                 }
186         }
187         if (swap)
188                 ast_swapcopy_samples(s->data+s->len, f->data, f->samples);
189         else
190                 memcpy(s->data + s->len, f->data, f->datalen);
191         /* If either side is empty, reset the delivery time */
192         if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery))      /* XXX really ? */
193                 s->delivery = f->delivery;
194         s->len += f->datalen;
195         return 0;
196 }
197
198 struct ast_frame *ast_smoother_read(struct ast_smoother *s)
199 {
200         struct ast_frame *opt;
201         int len;
202
203         /* IF we have an optimization frame, send it */
204         if (s->opt) {
205                 if (s->opt->offset < AST_FRIENDLY_OFFSET)
206                         ast_log(LOG_WARNING, "Returning a frame of inappropriate offset (%d).",
207                                                         s->opt->offset);
208                 opt = s->opt;
209                 s->opt = NULL;
210                 return opt;
211         }
212
213         /* Make sure we have enough data */
214         if (s->len < s->size) {
215                 /* Or, if this is a G.729 frame with VAD on it, send it immediately anyway */
216                 if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->size % 10)))
217                         return NULL;
218         }
219         len = s->size;
220         if (len > s->len)
221                 len = s->len;
222         /* Make frame */
223         s->f.frametype = AST_FRAME_VOICE;
224         s->f.subclass = s->format;
225         s->f.data = s->framedata + AST_FRIENDLY_OFFSET;
226         s->f.offset = AST_FRIENDLY_OFFSET;
227         s->f.datalen = len;
228         /* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */
229         s->f.samples = len * s->samplesperbyte; /* XXX rounding */
230         s->f.delivery = s->delivery;
231         /* Fill Data */
232         memcpy(s->f.data, s->data, len);
233         s->len -= len;
234         /* Move remaining data to the front if applicable */
235         if (s->len) {
236                 /* In principle this should all be fine because if we are sending
237                    G.729 VAD, the next timestamp will take over anyawy */
238                 memmove(s->data, s->data + len, s->len);
239                 if (!ast_tvzero(s->delivery)) {
240                         /* If we have delivery time, increment it, otherwise, leave it at 0 */
241                         s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, 8000));
242                 }
243         }
244         /* Return frame */
245         return &s->f;
246 }
247
248 void ast_smoother_free(struct ast_smoother *s)
249 {
250         free(s);
251 }
252
253 static struct ast_frame *ast_frame_header_new(void)
254 {
255         struct ast_frame *f = ast_calloc(1, sizeof(*f));
256 #ifdef TRACE_FRAMES
257         if (f) {
258                 f->prev = NULL;
259                 ast_mutex_lock(&framelock);
260                 headers++;
261                 f->next = headerlist;
262                 if (headerlist)
263                         headerlist->prev = f;
264                 headerlist = f;
265                 ast_mutex_unlock(&framelock);
266         }
267 #endif  
268         return f;
269 }
270
271 /*!
272  * \todo Important: I should be made more efficient.  Frame headers should
273  * most definitely be cached
274  */
275 void ast_frfree(struct ast_frame *fr)
276 {
277         if (fr->mallocd & AST_MALLOCD_DATA) {
278                 if (fr->data) 
279                         free(fr->data - fr->offset);
280         }
281         if (fr->mallocd & AST_MALLOCD_SRC) {
282                 if (fr->src)
283                         free((char *)fr->src);
284         }
285         if (fr->mallocd & AST_MALLOCD_HDR) {
286 #ifdef TRACE_FRAMES
287                 ast_mutex_lock(&framelock);
288                 headers--;
289                 if (fr->next)
290                         fr->next->prev = fr->prev;
291                 if (fr->prev)
292                         fr->prev->next = fr->next;
293                 else
294                         headerlist = fr->next;
295                 ast_mutex_unlock(&framelock);
296 #endif                  
297                 free(fr);
298         }
299 }
300
301 /*!
302  * \brief 'isolates' a frame by duplicating non-malloc'ed components
303  * (header, src, data).
304  * On return all components are malloc'ed
305  */
306 struct ast_frame *ast_frisolate(struct ast_frame *fr)
307 {
308         struct ast_frame *out;
309         void *newdata;
310         
311         if (!(fr->mallocd & AST_MALLOCD_HDR)) {
312                 /* Allocate a new header if needed */
313                 if (!(out = ast_frame_header_new()))
314                         return NULL;
315                 out->frametype = fr->frametype;
316                 out->subclass = fr->subclass;
317                 out->datalen = fr->datalen;
318                 out->samples = fr->samples;
319                 out->offset = fr->offset;
320                 out->data = fr->data;
321                 /* Copy the timing data */
322                 out->has_timing_info = fr->has_timing_info;
323                 if (fr->has_timing_info) {
324                         out->ts = fr->ts;
325                         out->len = fr->len;
326                         out->seqno = fr->seqno;
327                 }
328         } else
329                 out = fr;
330         
331         if (!(fr->mallocd & AST_MALLOCD_SRC)) {
332                 if (fr->src) {
333                         if (!(out->src = ast_strdup(fr->src))) {
334                                 if (out != fr)
335                                         free(out);
336                                 return NULL;
337                         }
338                 }
339         } else
340                 out->src = fr->src;
341         
342         if (!(fr->mallocd & AST_MALLOCD_DATA))  {
343                 if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) {
344                         if (out->src != fr->src)
345                                 free((void *) out->src);
346                         if (out != fr)
347                                 free(out);
348                         return NULL;
349                 }
350                 newdata += AST_FRIENDLY_OFFSET;
351                 out->offset = AST_FRIENDLY_OFFSET;
352                 out->datalen = fr->datalen;
353                 memcpy(newdata, fr->data, fr->datalen);
354                 out->data = newdata;
355         }
356
357         out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
358         
359         return out;
360 }
361
362 struct ast_frame *ast_frdup(const struct ast_frame *f)
363 {
364         struct ast_frame *out;
365         int len, srclen = 0;
366         void *buf;
367         /* Start with standard stuff */
368         len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
369         /* If we have a source, add space for it */
370         /*
371          * XXX Watch out here - if we receive a src which is not terminated
372          * properly, we can be easily attacked. Should limit the size we deal with.
373          */
374         if (f->src)
375                 srclen = strlen(f->src);
376         if (srclen > 0)
377                 len += srclen + 1;
378         if (!(buf = ast_calloc(1, len)))
379                 return NULL;
380         out = buf;
381         /* Set us as having malloc'd header only, so it will eventually
382            get freed. */
383         out->frametype = f->frametype;
384         out->subclass = f->subclass;
385         out->datalen = f->datalen;
386         out->samples = f->samples;
387         out->delivery = f->delivery;
388         out->mallocd = AST_MALLOCD_HDR;
389         out->offset = AST_FRIENDLY_OFFSET;
390         if (out->datalen) {
391                 out->data = buf + sizeof(*out) + AST_FRIENDLY_OFFSET;
392                 memcpy(out->data, f->data, out->datalen);       
393         }
394         if (srclen > 0) {
395                 out->src = buf + sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
396                 /* Must have space since we allocated for it */
397                 strcpy((char *)out->src, f->src);
398         }
399         out->has_timing_info = f->has_timing_info;
400         if (f->has_timing_info) {
401                 out->ts = f->ts;
402                 out->len = f->len;
403                 out->seqno = f->seqno;
404         }
405         return out;
406 }
407
408 #if 0
409 /*
410  * XXX
411  * This function is badly broken - it does not handle correctly
412  * partial reads on either header or body.
413  * However is it never used anywhere so we leave it commented out
414  */
415 struct ast_frame *ast_fr_fdread(int fd)
416 {
417         char buf[65536];
418         int res;        
419         struct ast_frame *f = (struct ast_frame *)buf;
420         int ttl = sizeof(*f);
421         /* Read a frame directly from there.  They're always in the
422            right format. */
423         
424         while(ttl) {
425                 res = read(fd, buf, ttl);
426                 if (res < 0) {
427                         ast_log(LOG_WARNING, "Bad read on %d: %s\n", fd, strerror(errno));
428                         return NULL;
429                 }
430                 ttl -= res;
431         }
432         
433         /* read the frame header */
434
435         /* Re-write data position */
436         f->data = buf + sizeof(*f);
437         f->offset = 0;
438         /* Forget about being mallocd */
439         f->mallocd = 0;
440         /* Re-write the source */
441         f->src = (char *)__FUNCTION__;
442         if (f->datalen > sizeof(buf) - sizeof(*f)) {
443                 /* Really bad read */
444                 ast_log(LOG_WARNING, "Strange read (%d bytes)\n", f->datalen);
445                 return NULL;
446         }
447         if (f->datalen) {
448                 if ((res = read(fd, f->data, f->datalen)) != f->datalen) {
449                         /* Bad read */
450                         ast_log(LOG_WARNING, "How very strange, expected %d, got %d\n", f->datalen, res);
451                         return NULL;
452                 }
453         }
454         if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
455                 return NULL;
456         }
457         return ast_frisolate(f);
458 }
459
460 /* Some convenient routines for sending frames to/from stream or datagram
461    sockets, pipes, etc (maybe even files) */
462
463 /*
464  * XXX this function is also partly broken because it does not handle
465  * partial writes. We comment it out too, and also the unique
466  * client it has, ast_fr_fdhangup()
467  */
468 int ast_fr_fdwrite(int fd, struct ast_frame *frame)
469 {
470         /* Write the frame exactly */
471         if (write(fd, frame, sizeof(*frame)) != sizeof(*frame)) {
472                 ast_log(LOG_WARNING, "Write error: %s\n", strerror(errno));
473                 return -1;
474         }
475         if (write(fd, frame->data, frame->datalen) != frame->datalen) {
476                 ast_log(LOG_WARNING, "Write error: %s\n", strerror(errno));
477                 return -1;
478         }
479         return 0;
480 }
481
482 int ast_fr_fdhangup(int fd)
483 {
484         struct ast_frame hangup = {
485                 AST_FRAME_CONTROL,
486                 AST_CONTROL_HANGUP
487         };
488         return ast_fr_fdwrite(fd, &hangup);
489 }
490
491 #endif /* unused functions */
492
493 void ast_swapcopy_samples(void *dst, const void *src, int samples)
494 {
495         int i;
496         unsigned short *dst_s = dst;
497         const unsigned short *src_s = src;
498
499         for (i = 0; i < samples; i++)
500                 dst_s[i] = (src_s[i]<<8) | (src_s[i]>>8);
501 }
502
503
504 struct ast_format_list *ast_get_format_list_index(int index) 
505 {
506         return &AST_FORMAT_LIST[index];
507 }
508
509 struct ast_format_list *ast_get_format_list(size_t *size) 
510 {
511         *size = (sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]));
512         return AST_FORMAT_LIST;
513 }
514
515 char* ast_getformatname(int format)
516 {
517         int x;
518         char *ret = "unknown";
519         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
520                 if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == format) {
521                         ret = AST_FORMAT_LIST[x].name;
522                         break;
523                 }
524         }
525         return ret;
526 }
527
528 char *ast_getformatname_multiple(char *buf, size_t size, int format)
529 {
530         int x;
531         unsigned len;
532         char *start, *end = buf;
533
534         if (!size)
535                 return buf;
536         snprintf(end, size, "0x%x (", format);
537         len = strlen(end);
538         end += len;
539         size -= len;
540         start = end;
541         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
542                 if (AST_FORMAT_LIST[x].visible && (AST_FORMAT_LIST[x].bits & format)) {
543                         snprintf(end, size,"%s|",AST_FORMAT_LIST[x].name);
544                         len = strlen(end);
545                         end += len;
546                         size -= len;
547                 }
548         }
549         if (start == end)
550                 snprintf(start, size, "nothing)");
551         else if (size > 1)
552                 *(end -1) = ')';
553         return buf;
554 }
555
556 static struct ast_codec_alias_table {
557         char *alias;
558         char *realname;
559 } ast_codec_alias_table[] = {
560         { "slinear", "slin"},
561         { "g723.1", "g723"},
562 };
563
564 static const char *ast_expand_codec_alias(const char *in)
565 {
566         int x;
567
568         for (x = 0; x < sizeof(ast_codec_alias_table) / sizeof(ast_codec_alias_table[0]); x++) {
569                 if(!strcmp(in,ast_codec_alias_table[x].alias))
570                         return ast_codec_alias_table[x].realname;
571         }
572         return in;
573 }
574
575 int ast_getformatbyname(const char *name)
576 {
577         int x, all, format = 0;
578
579         all = strcasecmp(name, "all") ? 0 : 1;
580         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
581                 if(AST_FORMAT_LIST[x].visible && (all || 
582                           !strcasecmp(AST_FORMAT_LIST[x].name,name) ||
583                           !strcasecmp(AST_FORMAT_LIST[x].name,ast_expand_codec_alias(name)))) {
584                         format |= AST_FORMAT_LIST[x].bits;
585                         if(!all)
586                                 break;
587                 }
588         }
589
590         return format;
591 }
592
593 char *ast_codec2str(int codec)
594 {
595         int x;
596         char *ret = "unknown";
597         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
598                 if(AST_FORMAT_LIST[x].visible && AST_FORMAT_LIST[x].bits == codec) {
599                         ret = AST_FORMAT_LIST[x].desc;
600                         break;
601                 }
602         }
603         return ret;
604 }
605
606 static int show_codecs(int fd, int argc, char *argv[])
607 {
608         int i, found=0;
609         char hex[25];
610         
611         if ((argc < 2) || (argc > 3))
612                 return RESULT_SHOWUSAGE;
613
614         if (!ast_opt_dont_warn)
615                 ast_cli(fd, "Disclaimer: this command is for informational purposes only.\n"
616                                 "\tIt does not indicate anything about your configuration.\n");
617
618         ast_cli(fd, "%11s %9s %10s   TYPE   %8s   %s\n","INT","BINARY","HEX","NAME","DESC");
619         ast_cli(fd, "--------------------------------------------------------------------------------\n");
620         if ((argc == 2) || (!strcasecmp(argv[1],"audio"))) {
621                 found = 1;
622                 for (i=0;i<12;i++) {
623                         snprintf(hex,25,"(0x%x)",1<<i);
624                         ast_cli(fd, "%11u (1 << %2d) %10s  audio   %8s   (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
625                 }
626         }
627
628         if ((argc == 2) || (!strcasecmp(argv[1],"image"))) {
629                 found = 1;
630                 for (i=16;i<18;i++) {
631                         snprintf(hex,25,"(0x%x)",1<<i);
632                         ast_cli(fd, "%11u (1 << %2d) %10s  image   %8s   (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
633                 }
634         }
635
636         if ((argc == 2) || (!strcasecmp(argv[1],"video"))) {
637                 found = 1;
638                 for (i=18;i<22;i++) {
639                         snprintf(hex,25,"(0x%x)",1<<i);
640                         ast_cli(fd, "%11u (1 << %2d) %10s  video   %8s   (%s)\n",1 << i,i,hex,ast_getformatname(1<<i),ast_codec2str(1<<i));
641                 }
642         }
643
644         if (! found)
645                 return RESULT_SHOWUSAGE;
646         else
647                 return RESULT_SUCCESS;
648 }
649
650 static char frame_show_codecs_usage[] =
651 "Usage: show [audio|video|image] codecs\n"
652 "       Displays codec mapping\n";
653
654 static int show_codec_n(int fd, int argc, char *argv[])
655 {
656         int codec, i, found=0;
657
658         if (argc != 3)
659                 return RESULT_SHOWUSAGE;
660
661         if (sscanf(argv[2],"%d",&codec) != 1)
662                 return RESULT_SHOWUSAGE;
663
664         for (i = 0; i < 32; i++)
665                 if (codec & (1 << i)) {
666                         found = 1;
667                         ast_cli(fd, "%11u (1 << %2d)  %s\n",1 << i,i,ast_codec2str(1<<i));
668                 }
669
670         if (!found)
671                 ast_cli(fd, "Codec %d not found\n", codec);
672
673         return RESULT_SUCCESS;
674 }
675
676 static char frame_show_codec_n_usage[] =
677 "Usage: show codec <number>\n"
678 "       Displays codec mapping\n";
679
680 /*! Dump a frame for debugging purposes */
681 void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
682 {
683         const char noname[] = "unknown";
684         char ftype[40] = "Unknown Frametype";
685         char cft[80];
686         char subclass[40] = "Unknown Subclass";
687         char csub[80];
688         char moreinfo[40] = "";
689         char cn[60];
690         char cp[40];
691         char cmn[40];
692
693         if (!name)
694                 name = noname;
695
696
697         if (!f) {
698                 ast_verbose("%s [ %s (NULL) ] [%s]\n", 
699                         term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
700                         term_color(cft, "HANGUP", COLOR_BRRED, COLOR_BLACK, sizeof(cft)), 
701                         term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
702                 return;
703         }
704         /* XXX We should probably print one each of voice and video when the format changes XXX */
705         if (f->frametype == AST_FRAME_VOICE)
706                 return;
707         if (f->frametype == AST_FRAME_VIDEO)
708                 return;
709         switch(f->frametype) {
710         case AST_FRAME_DTMF:
711                 strcpy(ftype, "DTMF");
712                 subclass[0] = f->subclass;
713                 subclass[1] = '\0';
714                 break;
715         case AST_FRAME_CONTROL:
716                 strcpy(ftype, "Control");
717                 switch(f->subclass) {
718                 case AST_CONTROL_HANGUP:
719                         strcpy(subclass, "Hangup");
720                         break;
721                 case AST_CONTROL_RING:
722                         strcpy(subclass, "Ring");
723                         break;
724                 case AST_CONTROL_RINGING:
725                         strcpy(subclass, "Ringing");
726                         break;
727                 case AST_CONTROL_ANSWER:
728                         strcpy(subclass, "Answer");
729                         break;
730                 case AST_CONTROL_BUSY:
731                         strcpy(subclass, "Busy");
732                         break;
733                 case AST_CONTROL_TAKEOFFHOOK:
734                         strcpy(subclass, "Take Off Hook");
735                         break;
736                 case AST_CONTROL_OFFHOOK:
737                         strcpy(subclass, "Line Off Hook");
738                         break;
739                 case AST_CONTROL_CONGESTION:
740                         strcpy(subclass, "Congestion");
741                         break;
742                 case AST_CONTROL_FLASH:
743                         strcpy(subclass, "Flash");
744                         break;
745                 case AST_CONTROL_WINK:
746                         strcpy(subclass, "Wink");
747                         break;
748                 case AST_CONTROL_OPTION:
749                         strcpy(subclass, "Option");
750                         break;
751                 case AST_CONTROL_RADIO_KEY:
752                         strcpy(subclass, "Key Radio");
753                         break;
754                 case AST_CONTROL_RADIO_UNKEY:
755                         strcpy(subclass, "Unkey Radio");
756                         break;
757                 case -1:
758                         strcpy(subclass, "Stop generators");
759                         break;
760                 default:
761                         snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass);
762                 }
763                 break;
764         case AST_FRAME_NULL:
765                 strcpy(ftype, "Null Frame");
766                 strcpy(subclass, "N/A");
767                 break;
768         case AST_FRAME_IAX:
769                 /* Should never happen */
770                 strcpy(ftype, "IAX Specific");
771                 snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass);
772                 break;
773         case AST_FRAME_TEXT:
774                 strcpy(ftype, "Text");
775                 strcpy(subclass, "N/A");
776                 ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
777                 break;
778         case AST_FRAME_IMAGE:
779                 strcpy(ftype, "Image");
780                 snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass));
781                 break;
782         case AST_FRAME_HTML:
783                 strcpy(ftype, "HTML");
784                 switch(f->subclass) {
785                 case AST_HTML_URL:
786                         strcpy(subclass, "URL");
787                         ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
788                         break;
789                 case AST_HTML_DATA:
790                         strcpy(subclass, "Data");
791                         break;
792                 case AST_HTML_BEGIN:
793                         strcpy(subclass, "Begin");
794                         break;
795                 case AST_HTML_END:
796                         strcpy(subclass, "End");
797                         break;
798                 case AST_HTML_LDCOMPLETE:
799                         strcpy(subclass, "Load Complete");
800                         break;
801                 case AST_HTML_NOSUPPORT:
802                         strcpy(subclass, "No Support");
803                         break;
804                 case AST_HTML_LINKURL:
805                         strcpy(subclass, "Link URL");
806                         ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
807                         break;
808                 case AST_HTML_UNLINK:
809                         strcpy(subclass, "Unlink");
810                         break;
811                 case AST_HTML_LINKREJECT:
812                         strcpy(subclass, "Link Reject");
813                         break;
814                 default:
815                         snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass);
816                         break;
817                 }
818                 break;
819         case AST_FRAME_MODEM:
820                 strcpy(ftype, "Modem");
821                 switch (f->subclass) {
822                 case AST_MODEM_T38:
823                         strcpy(subclass, "T.38");
824                         break;
825                 case AST_MODEM_V150:
826                         strcpy(subclass, "V.150");
827                         break;
828                 default:
829                         snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass);
830                         break;
831                 }
832                 break;
833         default:
834                 snprintf(ftype, sizeof(ftype), "Unknown Frametype '%d'", f->frametype);
835         }
836         if (!ast_strlen_zero(moreinfo))
837                 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) '%s' ] [%s]\n",  
838                             term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
839                             term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
840                             f->frametype, 
841                             term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
842                             f->subclass, 
843                             term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)),
844                             term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
845         else
846                 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) ] [%s]\n",  
847                             term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
848                             term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
849                             f->frametype, 
850                             term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
851                             f->subclass, 
852                             term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
853 }
854
855
856 #ifdef TRACE_FRAMES
857 static int show_frame_stats(int fd, int argc, char *argv[])
858 {
859         struct ast_frame *f;
860         int x=1;
861         if (argc != 3)
862                 return RESULT_SHOWUSAGE;
863         ast_mutex_lock(&framelock);
864         ast_cli(fd, "     Framer Statistics     \n");
865         ast_cli(fd, "---------------------------\n");
866         ast_cli(fd, "Total allocated headers: %d\n", headers);
867         ast_cli(fd, "Queue Dump:\n");
868         for (f=headerlist; f; f = f->next) {
869                 ast_cli(fd, "%d.  Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : "<Unknown>");
870         }
871         ast_mutex_unlock(&framelock);
872         return RESULT_SUCCESS;
873 }
874
875 static char frame_stats_usage[] =
876 "Usage: show frame stats\n"
877 "       Displays debugging statistics from framer\n";
878 #endif
879
880 /* Builtin Asterisk CLI-commands for debugging */
881 static struct ast_cli_entry my_clis[] = {
882 { { "show", "codecs", NULL }, show_codecs, "Shows codecs", frame_show_codecs_usage },
883 { { "show", "audio", "codecs", NULL }, show_codecs, "Shows audio codecs", frame_show_codecs_usage },
884 { { "show", "video", "codecs", NULL }, show_codecs, "Shows video codecs", frame_show_codecs_usage },
885 { { "show", "image", "codecs", NULL }, show_codecs, "Shows image codecs", frame_show_codecs_usage },
886 { { "show", "codec", NULL }, show_codec_n, "Shows a specific codec", frame_show_codec_n_usage },
887 #ifdef TRACE_FRAMES
888 { { "show", "frame", "stats", NULL }, show_frame_stats, "Shows frame statistics", frame_stats_usage },
889 #endif
890 };
891
892 int init_framer(void)
893 {
894         ast_cli_register_multiple(my_clis, sizeof(my_clis)/sizeof(my_clis[0]) );
895         return 0;       
896 }
897
898 void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right) 
899 {
900         int x, differential = (int) 'A', mem;
901         char *from, *to;
902
903         if(right) {
904                 from = pref->order;
905                 to = buf;
906                 mem = size;
907         } else {
908                 to = pref->order;
909                 from = buf;
910                 mem = 32;
911         }
912
913         memset(to, 0, mem);
914         for (x = 0; x < 32 ; x++) {
915                 if(!from[x])
916                         break;
917                 to[x] = right ? (from[x] + differential) : (from[x] - differential);
918         }
919 }
920
921 int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) 
922 {
923         int x, codec; 
924         size_t total_len, slen;
925         char *formatname;
926         
927         memset(buf,0,size);
928         total_len = size;
929         buf[0] = '(';
930         total_len--;
931         for(x = 0; x < 32 ; x++) {
932                 if(total_len <= 0)
933                         break;
934                 if(!(codec = ast_codec_pref_index(pref,x)))
935                         break;
936                 if((formatname = ast_getformatname(codec))) {
937                         slen = strlen(formatname);
938                         if(slen > total_len)
939                                 break;
940                         strncat(buf,formatname,total_len);
941                         total_len -= slen;
942                 }
943                 if(total_len && x < 31 && ast_codec_pref_index(pref , x + 1)) {
944                         strncat(buf,"|",total_len);
945                         total_len--;
946                 }
947         }
948         if(total_len) {
949                 strncat(buf,")",total_len);
950                 total_len--;
951         }
952
953         return size - total_len;
954 }
955
956 int ast_codec_pref_index(struct ast_codec_pref *pref, int index) 
957 {
958         int slot = 0;
959
960         
961         if((index >= 0) && (index < sizeof(pref->order))) {
962                 slot = pref->order[index];
963         }
964
965         return slot ? AST_FORMAT_LIST[slot-1].bits : 0;
966 }
967
968 /*! \brief Remove codec from pref list */
969 void ast_codec_pref_remove(struct ast_codec_pref *pref, int format)
970 {
971         struct ast_codec_pref oldorder;
972         int x, y = 0;
973         int slot;
974
975         if(!pref->order[0])
976                 return;
977
978         memcpy(&oldorder, pref, sizeof(oldorder));
979         memset(pref, 0, sizeof(*pref));
980
981         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
982                 slot = oldorder.order[x];
983                 if(! slot)
984                         break;
985                 if(AST_FORMAT_LIST[slot-1].bits != format)
986                         pref->order[y++] = slot;
987         }
988         
989 }
990
991 /*! \brief Append codec to list */
992 int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
993 {
994         int x, newindex = -1;
995
996         ast_codec_pref_remove(pref, format);
997
998         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
999                 if(AST_FORMAT_LIST[x].bits == format) {
1000                         newindex = x + 1;
1001                         break;
1002                 }
1003         }
1004
1005         if(newindex) {
1006                 for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1007                         if(!pref->order[x]) {
1008                                 pref->order[x] = newindex;
1009                                 break;
1010                         }
1011                 }
1012         }
1013
1014         return x;
1015 }
1016
1017
1018 /*! \brief Pick a codec */
1019 int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best)
1020 {
1021         int x, ret = 0, slot;
1022
1023         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1024                 slot = pref->order[x];
1025
1026                 if (!slot)
1027                         break;
1028                 if (formats & AST_FORMAT_LIST[slot-1].bits) {
1029                         ret = AST_FORMAT_LIST[slot-1].bits;
1030                         break;
1031                 }
1032         }
1033         if(ret & AST_FORMAT_AUDIO_MASK)
1034                 return ret;
1035
1036         if (option_debug > 3)
1037                 ast_log(LOG_DEBUG, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");
1038
1039         return find_best ? ast_best_codec(formats) : 0;
1040 }
1041
1042 void ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing) 
1043 {
1044         char *parse;
1045         char *this;
1046         int format;
1047
1048         parse = ast_strdupa(list);
1049         while ((this = strsep(&parse, ","))) {
1050                 if (!(format = ast_getformatbyname(this))) {
1051                         ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", allowing ? "allow" : "disallow", this);
1052                         continue;
1053                 }
1054
1055                 if (mask) {
1056                         if (allowing)
1057                                 *mask |= format;
1058                         else
1059                                 *mask &= ~format;
1060                 }
1061
1062                 /* Set up a preference list for audio. Do not include video in preferences 
1063                    since we can not transcode video and have to use whatever is offered
1064                  */
1065                 if (pref && (format & AST_FORMAT_AUDIO_MASK)) {
1066                         if (strcasecmp(this, "all")) {
1067                                 if (allowing)
1068                                         ast_codec_pref_append(pref, format);
1069                                 else
1070                                         ast_codec_pref_remove(pref, format);
1071                         } else if (!allowing) {
1072                                 memset(pref, 0, sizeof(*pref));
1073                         }
1074                 }
1075         }
1076 }
1077
1078 static int g723_len(unsigned char buf)
1079 {
1080         enum frame_type type = buf & TYPE_MASK;
1081
1082         switch(type) {
1083         case TYPE_DONTSEND:
1084                 return 0;
1085                 break;
1086         case TYPE_SILENCE:
1087                 return 4;
1088                 break;
1089         case TYPE_HIGH:
1090                 return 24;
1091                 break;
1092         case TYPE_LOW:
1093                 return 20;
1094                 break;
1095         default:
1096                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", type);
1097         }
1098         return -1;
1099 }
1100
1101 static int g723_samples(unsigned char *buf, int maxlen)
1102 {
1103         int pos = 0;
1104         int samples = 0;
1105         int res;
1106         while(pos < maxlen) {
1107                 res = g723_len(buf[pos]);
1108                 if (res <= 0)
1109                         break;
1110                 samples += 240;
1111                 pos += res;
1112         }
1113         return samples;
1114 }
1115
1116 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
1117 {
1118         int byte = bit / 8;       /* byte containing first bit */
1119         int rem = 8 - (bit % 8);  /* remaining bits in first byte */
1120         unsigned char ret = 0;
1121         
1122         if (n <= 0 || n > 8)
1123                 return 0;
1124
1125         if (rem < n) {
1126                 ret = (data[byte] << (n - rem));
1127                 ret |= (data[byte + 1] >> (8 - n + rem));
1128         } else {
1129                 ret = (data[byte] >> (rem - n));
1130         }
1131
1132         return (ret & (0xff >> (8 - n)));
1133 }
1134
1135 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
1136 {
1137         static int SpeexWBSubModeSz[] = {
1138                 0, 36, 112, 192,
1139                 352, 0, 0, 0 };
1140         int off = bit;
1141         unsigned char c;
1142
1143         /* skip up to two wideband frames */
1144         if (((len * 8 - off) >= 5) && 
1145                 get_n_bits_at(data, 1, off)) {
1146                 c = get_n_bits_at(data, 3, off + 1);
1147                 off += SpeexWBSubModeSz[c];
1148
1149                 if (((len * 8 - off) >= 5) && 
1150                         get_n_bits_at(data, 1, off)) {
1151                         c = get_n_bits_at(data, 3, off + 1);
1152                         off += SpeexWBSubModeSz[c];
1153
1154                         if (((len * 8 - off) >= 5) && 
1155                                 get_n_bits_at(data, 1, off)) {
1156                                 ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
1157                                 return -1;
1158                         }
1159                 }
1160
1161         }
1162         return off - bit;
1163 }
1164
1165 static int speex_samples(unsigned char *data, int len)
1166 {
1167         static int SpeexSubModeSz[] = {
1168                5, 43, 119, 160,
1169                 220, 300, 364, 492, 
1170                 79, 0, 0, 0,
1171                 0, 0, 0, 0 };
1172         static int SpeexInBandSz[] = { 
1173                 1, 1, 4, 4,
1174                 4, 4, 4, 4,
1175                 8, 8, 16, 16,
1176                 32, 32, 64, 64 };
1177         int bit = 0;
1178         int cnt = 0;
1179         int off;
1180         unsigned char c;
1181
1182         while ((len * 8 - bit) >= 5) {
1183                 /* skip wideband frames */
1184                 off = speex_get_wb_sz_at(data, len, bit);
1185                 if (off < 0)  {
1186                         ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
1187                         break;
1188                 }
1189                 bit += off;
1190
1191                 if ((len * 8 - bit) < 5) {
1192                         ast_log(LOG_WARNING, "Not enough bits remaining after wide band for speex samples.\n");
1193                         break;
1194                 }
1195
1196                 /* get control bits */
1197                 c = get_n_bits_at(data, 5, bit);
1198                 bit += 5;
1199
1200                 if (c == 15) { 
1201                         /* terminator */
1202                         break; 
1203                 } else if (c == 14) {
1204                         /* in-band signal; next 4 bits contain signal id */
1205                         c = get_n_bits_at(data, 4, bit);
1206                         bit += 4;
1207                         bit += SpeexInBandSz[c];
1208                 } else if (c == 13) {
1209                         /* user in-band; next 5 bits contain msg len */
1210                         c = get_n_bits_at(data, 5, bit);
1211                         bit += 5;
1212                         bit += c * 8;
1213                 } else if (c > 8) {
1214                         /* unknown */
1215                         break;
1216                 } else {
1217                         /* skip number bits for submode (less the 5 control bits) */
1218                         bit += SpeexSubModeSz[c] - 5;
1219                         cnt += 160; /* new frame */
1220                 }
1221         }
1222         return cnt;
1223 }
1224
1225 int ast_codec_get_samples(struct ast_frame *f)
1226 {
1227         int samples=0;
1228         switch(f->subclass) {
1229         case AST_FORMAT_SPEEX:
1230                 samples = speex_samples(f->data, f->datalen);
1231                 break;
1232         case AST_FORMAT_G723_1:
1233                 samples = g723_samples(f->data, f->datalen);
1234                 break;
1235         case AST_FORMAT_ILBC:
1236                 samples = 240 * (f->datalen / 50);
1237                 break;
1238         case AST_FORMAT_GSM:
1239                 samples = 160 * (f->datalen / 33);
1240                 break;
1241         case AST_FORMAT_G729A:
1242                 samples = f->datalen * 8;
1243                 break;
1244         case AST_FORMAT_SLINEAR:
1245                 samples = f->datalen / 2;
1246                 break;
1247         case AST_FORMAT_LPC10:
1248                 /* assumes that the RTP packet contains one LPC10 frame */
1249                 samples = 22 * 8;
1250                 samples += (((char *)(f->data))[7] & 0x1) * 8;
1251                 break;
1252         case AST_FORMAT_ULAW:
1253         case AST_FORMAT_ALAW:
1254                 samples = f->datalen;
1255                 break;
1256         case AST_FORMAT_ADPCM:
1257         case AST_FORMAT_G726:
1258         case AST_FORMAT_G726_AAL2:
1259                 samples = f->datalen * 2;
1260                 break;
1261         default:
1262                 ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
1263         }
1264         return samples;
1265 }
1266
1267 int ast_codec_get_len(int format, int samples)
1268 {
1269         int len = 0;
1270
1271         /* XXX Still need speex, g723, and lpc10 XXX */ 
1272         switch(format) {
1273         case AST_FORMAT_ILBC:
1274                 len = (samples / 240) * 50;
1275                 break;
1276         case AST_FORMAT_GSM:
1277                 len = (samples / 160) * 33;
1278                 break;
1279         case AST_FORMAT_G729A:
1280                 len = samples / 8;
1281                 break;
1282         case AST_FORMAT_SLINEAR:
1283                 len = samples * 2;
1284                 break;
1285         case AST_FORMAT_ULAW:
1286         case AST_FORMAT_ALAW:
1287                 len = samples;
1288                 break;
1289         case AST_FORMAT_ADPCM:
1290         case AST_FORMAT_G726:
1291         case AST_FORMAT_G726_AAL2:
1292                 len = samples / 2;
1293                 break;
1294         default:
1295                 ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
1296         }
1297
1298         return len;
1299 }
1300
1301 int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
1302 {
1303         int count;
1304         short *fdata = f->data;
1305         short adjust_value = abs(adjustment);
1306
1307         if ((f->frametype != AST_FRAME_VOICE) || (f->subclass != AST_FORMAT_SLINEAR))
1308                 return -1;
1309
1310         if (!adjustment)
1311                 return 0;
1312
1313         for (count = 0; count < f->samples; count++) {
1314                 if (adjustment > 0) {
1315                         ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
1316                 } else if (adjustment < 0) {
1317                         ast_slinear_saturated_divide(&fdata[count], &adjust_value);
1318                 }
1319         }
1320
1321         return 0;
1322 }
1323
1324 int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
1325 {
1326         int count;
1327         short *data1, *data2;
1328
1329         if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass != AST_FORMAT_SLINEAR))
1330                 return -1;
1331
1332         if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass != AST_FORMAT_SLINEAR))
1333                 return -1;
1334
1335         if (f1->samples != f2->samples)
1336                 return -1;
1337
1338         for (count = 0, data1 = f1->data, data2 = f2->data;
1339              count < f1->samples;
1340              count++, data1++, data2++)
1341                 ast_slinear_saturated_add(data1, data2);
1342
1343         return 0;
1344 }
1345
1346 struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe)
1347 {
1348         struct ast_frame *cur, *oldhead;
1349         int len=0;
1350         if (f && dupe)
1351                 f = ast_frdup(f);
1352         if (!f)
1353                 return head;
1354
1355         f->next = NULL;
1356         if (!head) 
1357                 return f;
1358         cur = head;
1359         while(cur->next) {
1360                 cur = cur->next;
1361                 len++;
1362                 if (len >= maxlen) {
1363                         oldhead = head;
1364                         head = head->next;
1365                         ast_frfree(oldhead);
1366                 }
1367         }
1368         return head;
1369 }