Include h.264 in "show codecs"
[asterisk/asterisk.git] / 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: codec_g723_1.c */
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" },        /*!<  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         { 0, 0, "nothing", "undefined" },
96         { 0, 0, "nothing", "undefined" },
97         { 0, 0, "nothing", "undefined" },
98         { 0, 0, "nothing", "undefined" },
99         { 0, AST_FORMAT_MAX_AUDIO, "maxaudio", "Maximum audio format" },        
100         { 1, AST_FORMAT_JPEG, "jpeg", "JPEG image"},    /*!< 17: See format_jpeg.c */
101         { 1, AST_FORMAT_PNG, "png", "PNG image"},       /*!< 18: Image format */
102         { 1, AST_FORMAT_H261, "h261", "H.261 Video" },  /*!< 19: Video Passthrough */
103         { 1, AST_FORMAT_H263, "h263", "H.263 Video" },  /*!< 20: Passthrough support, see format_h263.c */
104         { 1, AST_FORMAT_H263_PLUS, "h263p", "H.263+ Video" },   /*!< 21: See format_h263.c */
105         { 1, AST_FORMAT_H264, "h264", "H.264 Video" },  /*!< 22: Passthrough support, see format_h263.c */
106         { 0, 0, "nothing", "undefined" },
107         { 0, 0, "nothing", "undefined" },
108         { 0, 0, "nothing", "undefined" },
109         { 0, AST_FORMAT_MAX_VIDEO, "maxvideo", "Maximum video format" },
110 };
111
112 struct ast_frame ast_null_frame = { AST_FRAME_NULL, };
113
114 void ast_smoother_reset(struct ast_smoother *s, int size)
115 {
116         memset(s, 0, sizeof(*s));
117         s->size = size;
118 }
119
120 struct ast_smoother *ast_smoother_new(int size)
121 {
122         struct ast_smoother *s;
123         if (size < 1)
124                 return NULL;
125         if ((s = ast_malloc(sizeof(*s))))
126                 ast_smoother_reset(s, size);
127         return s;
128 }
129
130 int ast_smoother_get_flags(struct ast_smoother *s)
131 {
132         return s->flags;
133 }
134
135 void ast_smoother_set_flags(struct ast_smoother *s, int flags)
136 {
137         s->flags = flags;
138 }
139
140 int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
141 {
142         if (f->frametype != AST_FRAME_VOICE) {
143                 ast_log(LOG_WARNING, "Huh?  Can't smooth a non-voice frame!\n");
144                 return -1;
145         }
146         if (!s->format) {
147                 s->format = f->subclass;
148                 s->samplesperbyte = (float)f->samples / (float)f->datalen;
149         } else if (s->format != f->subclass) {
150                 ast_log(LOG_WARNING, "Smoother was working on %d format frames, now trying to feed %d?\n", s->format, f->subclass);
151                 return -1;
152         }
153         if (s->len + f->datalen > SMOOTHER_SIZE) {
154                 ast_log(LOG_WARNING, "Out of smoother space\n");
155                 return -1;
156         }
157         if (((f->datalen == s->size) || ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729)))
158                                  && !s->opt && (f->offset >= AST_MIN_OFFSET)) {
159                 if (!s->len) {
160                         /* Optimize by sending the frame we just got
161                            on the next read, thus eliminating the douple
162                            copy */
163                         s->opt = f;
164                         return 0;
165                 } else {
166                         s->optimizablestream++;
167                         if (s->optimizablestream > 10) {
168                                 /* For the past 10 rounds, we have input and output
169                                    frames of the correct size for this smoother, yet
170                                    we were unable to optimize because there was still
171                                    some cruft left over.  Lets just drop the cruft so
172                                    we can move to a fully optimized path */
173                                 s->len = 0;
174                                 s->opt = f;
175                                 return 0;
176                         }
177                 }
178         } else 
179                 s->optimizablestream = 0;
180         if (s->flags & AST_SMOOTHER_FLAG_G729) {
181                 if (s->len % 10) {
182                         ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
183                         return 0;
184                 }
185         }
186         if (swap)
187                 ast_swapcopy_samples(s->data+s->len, f->data, f->samples);
188         else
189                 memcpy(s->data + s->len, f->data, f->datalen);
190         /* If either side is empty, reset the delivery time */
191         if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery))      /* XXX really ? */
192                 s->delivery = f->delivery;
193         s->len += f->datalen;
194         return 0;
195 }
196
197 struct ast_frame *ast_smoother_read(struct ast_smoother *s)
198 {
199         struct ast_frame *opt;
200         int len;
201
202         /* IF we have an optimization frame, send it */
203         if (s->opt) {
204                 if (s->opt->offset < AST_FRIENDLY_OFFSET)
205                         ast_log(LOG_WARNING, "Returning a frame of inappropriate offset (%d).",
206                                                         s->opt->offset);
207                 opt = s->opt;
208                 s->opt = NULL;
209                 return opt;
210         }
211
212         /* Make sure we have enough data */
213         if (s->len < s->size) {
214                 /* Or, if this is a G.729 frame with VAD on it, send it immediately anyway */
215                 if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->size % 10)))
216                         return NULL;
217         }
218         len = s->size;
219         if (len > s->len)
220                 len = s->len;
221         /* Make frame */
222         s->f.frametype = AST_FRAME_VOICE;
223         s->f.subclass = s->format;
224         s->f.data = s->framedata + AST_FRIENDLY_OFFSET;
225         s->f.offset = AST_FRIENDLY_OFFSET;
226         s->f.datalen = len;
227         /* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */
228         s->f.samples = len * s->samplesperbyte; /* XXX rounding */
229         s->f.delivery = s->delivery;
230         /* Fill Data */
231         memcpy(s->f.data, s->data, len);
232         s->len -= len;
233         /* Move remaining data to the front if applicable */
234         if (s->len) {
235                 /* In principle this should all be fine because if we are sending
236                    G.729 VAD, the next timestamp will take over anyawy */
237                 memmove(s->data, s->data + len, s->len);
238                 if (!ast_tvzero(s->delivery)) {
239                         /* If we have delivery time, increment it, otherwise, leave it at 0 */
240                         s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, 8000));
241                 }
242         }
243         /* Return frame */
244         return &s->f;
245 }
246
247 void ast_smoother_free(struct ast_smoother *s)
248 {
249         free(s);
250 }
251
252 static struct ast_frame *ast_frame_header_new(void)
253 {
254         struct ast_frame *f = ast_calloc(1, sizeof(*f));
255 #ifdef TRACE_FRAMES
256         if (f) {
257                 headers++;
258                 f->prev = NULL;
259                 ast_mutex_lock(&framelock);
260                 f->next = headerlist;
261                 if (headerlist)
262                         headerlist->prev = f;
263                 headerlist = f;
264                 ast_mutex_unlock(&framelock);
265         }
266 #endif  
267         return f;
268 }
269
270 /*!
271  * \todo Important: I should be made more efficient.  Frame headers should
272  * most definitely be cached
273  */
274 void ast_frfree(struct ast_frame *fr)
275 {
276         if (fr->mallocd & AST_MALLOCD_DATA) {
277                 if (fr->data) 
278                         free(fr->data - fr->offset);
279         }
280         if (fr->mallocd & AST_MALLOCD_SRC) {
281                 if (fr->src)
282                         free((char *)fr->src);
283         }
284         if (fr->mallocd & AST_MALLOCD_HDR) {
285 #ifdef TRACE_FRAMES
286                 headers--;
287                 ast_mutex_lock(&framelock);
288                 if (fr->next)
289                         fr->next->prev = fr->prev;
290                 if (fr->prev)
291                         fr->prev->next = fr->next;
292                 else
293                         headerlist = fr->next;
294                 ast_mutex_unlock(&framelock);
295 #endif                  
296                 free(fr);
297         }
298 }
299
300 /*!
301  * \brief 'isolates' a frame by duplicating non-malloc'ed components
302  * (header, src, data).
303  * On return all components are malloc'ed
304  */
305 struct ast_frame *ast_frisolate(struct ast_frame *fr)
306 {
307         struct ast_frame *out;
308         void *newdata;
309         
310         if (!(fr->mallocd & AST_MALLOCD_HDR)) {
311                 /* Allocate a new header if needed */
312                 if (!(out = ast_frame_header_new()))
313                         return NULL;
314                 out->frametype = fr->frametype;
315                 out->subclass = fr->subclass;
316                 out->datalen = fr->datalen;
317                 out->samples = fr->samples;
318                 out->offset = fr->offset;
319                 out->data = fr->data;
320                 /* Copy the timing data */
321                 out->has_timing_info = fr->has_timing_info;
322                 if (fr->has_timing_info) {
323                         out->ts = fr->ts;
324                         out->len = fr->len;
325                         out->seqno = fr->seqno;
326                 }
327         } else
328                 out = fr;
329         
330         if (!(fr->mallocd & AST_MALLOCD_SRC)) {
331                 if (fr->src) {
332                         if (!(out->src = ast_strdup(fr->src))) {
333                                 if (out != fr)
334                                         free(out);
335                                 return NULL;
336                         }
337                 }
338         } else
339                 out->src = fr->src;
340         
341         if (!(fr->mallocd & AST_MALLOCD_DATA))  {
342                 if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) {
343                         if (out->src != fr->src)
344                                 free((void *) out->src);
345                         if (out != fr)
346                                 free(out);
347                         return NULL;
348                 }
349                 newdata += AST_FRIENDLY_OFFSET;
350                 out->offset = AST_FRIENDLY_OFFSET;
351                 out->datalen = fr->datalen;
352                 memcpy(newdata, fr->data, fr->datalen);
353                 out->data = newdata;
354         }
355
356         out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
357         
358         return out;
359 }
360
361 struct ast_frame *ast_frdup(struct ast_frame *f)
362 {
363         struct ast_frame *out;
364         int len, srclen = 0;
365         void *buf;
366         /* Start with standard stuff */
367         len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen;
368         /* If we have a source, add space for it */
369         /*
370          * XXX Watch out here - if we receive a src which is not terminated
371          * properly, we can be easily attacked. Should limit the size we deal with.
372          */
373         if (f->src)
374                 srclen = strlen(f->src);
375         if (srclen > 0)
376                 len += srclen + 1;
377         if (!(buf = ast_malloc(len)))
378                 return NULL;
379         out = buf;
380         /* Set us as having malloc'd header only, so it will eventually
381            get freed. */
382         out->frametype = f->frametype;
383         out->subclass = f->subclass;
384         out->datalen = f->datalen;
385         out->samples = f->samples;
386         out->delivery = f->delivery;
387         out->mallocd = AST_MALLOCD_HDR;
388         out->offset = AST_FRIENDLY_OFFSET;
389         out->data = buf + sizeof(*out) + AST_FRIENDLY_OFFSET;
390         if (srclen > 0) {
391                 out->src = out->data + f->datalen;
392                 /* Must have space since we allocated for it */
393                 strcpy((char *)out->src, f->src);
394         } else
395                 out->src = NULL;
396         out->prev = NULL;
397         out->next = NULL;
398         memcpy(out->data, f->data, out->datalen);       
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   %5s   %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<11;i++) {
623                         snprintf(hex,25,"(0x%x)",1<<i);
624                         ast_cli(fd, "%11u (1 << %2d) %10s  audio   %5s   (%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   %5s   (%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   %5s   (%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_cli(fd, "     Framer Statistics     \n");
864         ast_cli(fd, "---------------------------\n");
865         ast_cli(fd, "Total allocated headers: %d\n", headers);
866         ast_cli(fd, "Queue Dump:\n");
867         ast_mutex_lock(&framelock);
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                 samples = f->datalen * 2;
1259                 break;
1260         default:
1261                 ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
1262         }
1263         return samples;
1264 }
1265
1266 int ast_codec_get_len(int format, int samples)
1267 {
1268         int len = 0;
1269
1270         /* XXX Still need speex, g723, and lpc10 XXX */ 
1271         switch(format) {
1272         case AST_FORMAT_ILBC:
1273                 len = (samples / 240) * 50;
1274                 break;
1275         case AST_FORMAT_GSM:
1276                 len = (samples / 160) * 33;
1277                 break;
1278         case AST_FORMAT_G729A:
1279                 len = samples / 8;
1280                 break;
1281         case AST_FORMAT_SLINEAR:
1282                 len = samples * 2;
1283                 break;
1284         case AST_FORMAT_ULAW:
1285         case AST_FORMAT_ALAW:
1286                 len = samples;
1287                 break;
1288         case AST_FORMAT_ADPCM:
1289         case AST_FORMAT_G726:
1290                 len = samples / 2;
1291                 break;
1292         default:
1293                 ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
1294         }
1295
1296         return len;
1297 }
1298
1299 int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
1300 {
1301         int count;
1302         short *fdata = f->data;
1303         short adjust_value = abs(adjustment);
1304
1305         if ((f->frametype != AST_FRAME_VOICE) || (f->subclass != AST_FORMAT_SLINEAR))
1306                 return -1;
1307
1308         if (!adjustment)
1309                 return 0;
1310
1311         for (count = 0; count < f->samples; count++) {
1312                 if (adjustment > 0) {
1313                         ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
1314                 } else if (adjustment < 0) {
1315                         ast_slinear_saturated_divide(&fdata[count], &adjust_value);
1316                 }
1317         }
1318
1319         return 0;
1320 }
1321
1322 int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
1323 {
1324         int count;
1325         short *data1, *data2;
1326
1327         if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass != AST_FORMAT_SLINEAR))
1328                 return -1;
1329
1330         if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass != AST_FORMAT_SLINEAR))
1331                 return -1;
1332
1333         if (f1->samples != f2->samples)
1334                 return -1;
1335
1336         for (count = 0, data1 = f1->data, data2 = f2->data;
1337              count < f1->samples;
1338              count++, data1++, data2++)
1339                 ast_slinear_saturated_add(data1, data2);
1340
1341         return 0;
1342 }
1343
1344 struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe)
1345 {
1346         struct ast_frame *cur, *oldhead;
1347         int len=0;
1348         if (f && dupe)
1349                 f = ast_frdup(f);
1350         if (!f)
1351                 return head;
1352
1353         f->next = NULL;
1354         if (!head) 
1355                 return f;
1356         cur = head;
1357         while(cur->next) {
1358                 cur = cur->next;
1359                 len++;
1360                 if (len >= maxlen) {
1361                         oldhead = head;
1362                         head = head->next;
1363                         ast_frfree(oldhead);
1364                 }
1365         }
1366         return head;
1367 }