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