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