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