Merged revisions 103795 via svnmerge from
[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 -1:
784                         strcpy(subclass, "Stop generators");
785                         break;
786                 default:
787                         snprintf(subclass, sizeof(subclass), "Unknown control '%d'", f->subclass);
788                 }
789                 break;
790         case AST_FRAME_NULL:
791                 strcpy(ftype, "Null Frame");
792                 strcpy(subclass, "N/A");
793                 break;
794         case AST_FRAME_IAX:
795                 /* Should never happen */
796                 strcpy(ftype, "IAX Specific");
797                 snprintf(subclass, sizeof(subclass), "IAX Frametype %d", f->subclass);
798                 break;
799         case AST_FRAME_TEXT:
800                 strcpy(ftype, "Text");
801                 strcpy(subclass, "N/A");
802                 ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
803                 break;
804         case AST_FRAME_IMAGE:
805                 strcpy(ftype, "Image");
806                 snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass));
807                 break;
808         case AST_FRAME_HTML:
809                 strcpy(ftype, "HTML");
810                 switch(f->subclass) {
811                 case AST_HTML_URL:
812                         strcpy(subclass, "URL");
813                         ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
814                         break;
815                 case AST_HTML_DATA:
816                         strcpy(subclass, "Data");
817                         break;
818                 case AST_HTML_BEGIN:
819                         strcpy(subclass, "Begin");
820                         break;
821                 case AST_HTML_END:
822                         strcpy(subclass, "End");
823                         break;
824                 case AST_HTML_LDCOMPLETE:
825                         strcpy(subclass, "Load Complete");
826                         break;
827                 case AST_HTML_NOSUPPORT:
828                         strcpy(subclass, "No Support");
829                         break;
830                 case AST_HTML_LINKURL:
831                         strcpy(subclass, "Link URL");
832                         ast_copy_string(moreinfo, f->data, sizeof(moreinfo));
833                         break;
834                 case AST_HTML_UNLINK:
835                         strcpy(subclass, "Unlink");
836                         break;
837                 case AST_HTML_LINKREJECT:
838                         strcpy(subclass, "Link Reject");
839                         break;
840                 default:
841                         snprintf(subclass, sizeof(subclass), "Unknown HTML frame '%d'\n", f->subclass);
842                         break;
843                 }
844                 break;
845         case AST_FRAME_MODEM:
846                 strcpy(ftype, "Modem");
847                 switch (f->subclass) {
848                 case AST_MODEM_T38:
849                         strcpy(subclass, "T.38");
850                         break;
851                 case AST_MODEM_V150:
852                         strcpy(subclass, "V.150");
853                         break;
854                 default:
855                         snprintf(subclass, sizeof(subclass), "Unknown MODEM frame '%d'\n", f->subclass);
856                         break;
857                 }
858                 break;
859         default:
860                 snprintf(ftype, sizeof(ftype), "Unknown Frametype '%d'", f->frametype);
861         }
862         if (!ast_strlen_zero(moreinfo))
863                 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) '%s' ] [%s]\n",  
864                             term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
865                             term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
866                             f->frametype, 
867                             term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
868                             f->subclass, 
869                             term_color(cmn, moreinfo, COLOR_BRGREEN, COLOR_BLACK, sizeof(cmn)),
870                             term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
871         else
872                 ast_verbose("%s [ TYPE: %s (%d) SUBCLASS: %s (%d) ] [%s]\n",  
873                             term_color(cp, prefix, COLOR_BRMAGENTA, COLOR_BLACK, sizeof(cp)),
874                             term_color(cft, ftype, COLOR_BRRED, COLOR_BLACK, sizeof(cft)),
875                             f->frametype, 
876                             term_color(csub, subclass, COLOR_BRCYAN, COLOR_BLACK, sizeof(csub)),
877                             f->subclass, 
878                             term_color(cn, name, COLOR_YELLOW, COLOR_BLACK, sizeof(cn)));
879 }
880
881
882 #ifdef TRACE_FRAMES
883 static char *show_frame_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
884 {
885         struct ast_frame *f;
886         int x=1;
887
888         switch (cmd) {
889         case CLI_INIT:
890                 e->command = "core show frame stats";
891                 e->usage = 
892                         "Usage: core show frame stats\n"
893                         "       Displays debugging statistics from framer\n";
894                 return NULL;
895         case CLI_GENERATE:
896                 return NULL;    
897         }
898
899         if (a->argc != 4)
900                 return CLI_SHOWUSAGE;
901         AST_LIST_LOCK(&headerlist);
902         ast_cli(a->fd, "     Framer Statistics     \n");
903         ast_cli(a->fd, "---------------------------\n");
904         ast_cli(a->fd, "Total allocated headers: %d\n", headers);
905         ast_cli(a->fd, "Queue Dump:\n");
906         AST_LIST_TRAVERSE(&headerlist, f, frame_list)
907                 ast_cli(a->fd, "%d.  Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : "<Unknown>");
908         AST_LIST_UNLOCK(&headerlist);
909         return CLI_SUCCESS;
910 }
911 #endif
912
913 /* Builtin Asterisk CLI-commands for debugging */
914 static struct ast_cli_entry my_clis[] = {
915         AST_CLI_DEFINE(show_codecs, "Displays a list of codecs"),
916         AST_CLI_DEFINE(show_codec_n, "Shows a specific codec"),
917 #ifdef TRACE_FRAMES
918         AST_CLI_DEFINE(show_frame_stats, "Shows frame statistics"),
919 #endif
920 };
921
922 int init_framer(void)
923 {
924         ast_cli_register_multiple(my_clis, sizeof(my_clis) / sizeof(struct ast_cli_entry));
925         return 0;       
926 }
927
928 void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right) 
929 {
930         int x, differential = (int) 'A', mem;
931         char *from, *to;
932
933         if (right) {
934                 from = pref->order;
935                 to = buf;
936                 mem = size;
937         } else {
938                 to = pref->order;
939                 from = buf;
940                 mem = 32;
941         }
942
943         memset(to, 0, mem);
944         for (x = 0; x < 32 ; x++) {
945                 if (!from[x])
946                         break;
947                 to[x] = right ? (from[x] + differential) : (from[x] - differential);
948         }
949 }
950
951 int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) 
952 {
953         int x, codec; 
954         size_t total_len, slen;
955         char *formatname;
956         
957         memset(buf,0,size);
958         total_len = size;
959         buf[0] = '(';
960         total_len--;
961         for(x = 0; x < 32 ; x++) {
962                 if (total_len <= 0)
963                         break;
964                 if (!(codec = ast_codec_pref_index(pref,x)))
965                         break;
966                 if ((formatname = ast_getformatname(codec))) {
967                         slen = strlen(formatname);
968                         if (slen > total_len)
969                                 break;
970                         strncat(buf,formatname,total_len);
971                         total_len -= slen;
972                 }
973                 if (total_len && x < 31 && ast_codec_pref_index(pref , x + 1)) {
974                         strncat(buf,"|",total_len);
975                         total_len--;
976                 }
977         }
978         if (total_len) {
979                 strncat(buf,")",total_len);
980                 total_len--;
981         }
982
983         return size - total_len;
984 }
985
986 int ast_codec_pref_index(struct ast_codec_pref *pref, int index) 
987 {
988         int slot = 0;
989
990         
991         if ((index >= 0) && (index < sizeof(pref->order))) {
992                 slot = pref->order[index];
993         }
994
995         return slot ? AST_FORMAT_LIST[slot-1].bits : 0;
996 }
997
998 /*! \brief Remove codec from pref list */
999 void ast_codec_pref_remove(struct ast_codec_pref *pref, int format)
1000 {
1001         struct ast_codec_pref oldorder;
1002         int x, y = 0;
1003         int slot;
1004         int size;
1005
1006         if (!pref->order[0])
1007                 return;
1008
1009         memcpy(&oldorder, pref, sizeof(oldorder));
1010         memset(pref, 0, sizeof(*pref));
1011
1012         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1013                 slot = oldorder.order[x];
1014                 size = oldorder.framing[x];
1015                 if (! slot)
1016                         break;
1017                 if (AST_FORMAT_LIST[slot-1].bits != format) {
1018                         pref->order[y] = slot;
1019                         pref->framing[y++] = size;
1020                 }
1021         }
1022         
1023 }
1024
1025 /*! \brief Append codec to list */
1026 int ast_codec_pref_append(struct ast_codec_pref *pref, int format)
1027 {
1028         int x, newindex = 0;
1029
1030         ast_codec_pref_remove(pref, format);
1031
1032         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1033                 if (AST_FORMAT_LIST[x].bits == format) {
1034                         newindex = x + 1;
1035                         break;
1036                 }
1037         }
1038
1039         if (newindex) {
1040                 for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1041                         if (!pref->order[x]) {
1042                                 pref->order[x] = newindex;
1043                                 break;
1044                         }
1045                 }
1046         }
1047
1048         return x;
1049 }
1050
1051 /*! \brief Prepend codec to list */
1052 void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing)
1053 {
1054         int x, newindex = 0;
1055
1056         /* First step is to get the codecs "index number" */
1057         for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
1058                 if (AST_FORMAT_LIST[x].bits == format) {
1059                         newindex = x + 1;
1060                         break;
1061                 }
1062         }
1063         /* Done if its unknown */
1064         if (!newindex)
1065                 return;
1066
1067         /* Now find any existing occurrence, or the end */
1068         for (x = 0; x < 32; x++) {
1069                 if (!pref->order[x] || pref->order[x] == newindex)
1070                         break;
1071         }
1072
1073         if (only_if_existing && !pref->order[x])
1074                 return;
1075
1076         /* Move down to make space to insert - either all the way to the end,
1077            or as far as the existing location (which will be overwritten) */
1078         for (; x > 0; x--) {
1079                 pref->order[x] = pref->order[x - 1];
1080                 pref->framing[x] = pref->framing[x - 1];
1081         }
1082
1083         /* And insert the new entry */
1084         pref->order[0] = newindex;
1085         pref->framing[0] = 0; /* ? */
1086 }
1087
1088 /*! \brief Set packet size for codec */
1089 int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems)
1090 {
1091         int x, index = -1;
1092
1093         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1094                 if (AST_FORMAT_LIST[x].bits == format) {
1095                         index = x;
1096                         break;
1097                 }
1098         }
1099
1100         if (index < 0)
1101                 return -1;
1102
1103         /* size validation */
1104         if (!framems)
1105                 framems = AST_FORMAT_LIST[index].def_ms;
1106
1107         if (AST_FORMAT_LIST[index].inc_ms && framems % AST_FORMAT_LIST[index].inc_ms) /* avoid division by zero */
1108                 framems -= framems % AST_FORMAT_LIST[index].inc_ms;
1109
1110         if (framems < AST_FORMAT_LIST[index].min_ms)
1111                 framems = AST_FORMAT_LIST[index].min_ms;
1112
1113         if (framems > AST_FORMAT_LIST[index].max_ms)
1114                 framems = AST_FORMAT_LIST[index].max_ms;
1115
1116
1117         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1118                 if (pref->order[x] == (index + 1)) {
1119                         pref->framing[x] = framems;
1120                         break;
1121                 }
1122         }
1123
1124         return x;
1125 }
1126
1127 /*! \brief Get packet size for codec */
1128 struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int format)
1129 {
1130         int x, index = -1, framems = 0;
1131         struct ast_format_list fmt = { 0, };
1132
1133         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1134                 if (AST_FORMAT_LIST[x].bits == format) {
1135                         fmt = AST_FORMAT_LIST[x];
1136                         index = x;
1137                         break;
1138                 }
1139         }
1140
1141         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1142                 if (pref->order[x] == (index + 1)) {
1143                         framems = pref->framing[x];
1144                         break;
1145                 }
1146         }
1147
1148         /* size validation */
1149         if (!framems)
1150                 framems = AST_FORMAT_LIST[index].def_ms;
1151
1152         if (AST_FORMAT_LIST[index].inc_ms && framems % AST_FORMAT_LIST[index].inc_ms) /* avoid division by zero */
1153                 framems -= framems % AST_FORMAT_LIST[index].inc_ms;
1154
1155         if (framems < AST_FORMAT_LIST[index].min_ms)
1156                 framems = AST_FORMAT_LIST[index].min_ms;
1157
1158         if (framems > AST_FORMAT_LIST[index].max_ms)
1159                 framems = AST_FORMAT_LIST[index].max_ms;
1160
1161         fmt.cur_ms = framems;
1162
1163         return fmt;
1164 }
1165
1166 /*! \brief Pick a codec */
1167 int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best)
1168 {
1169         int x, ret = 0, slot;
1170
1171         for (x = 0; x < sizeof(AST_FORMAT_LIST) / sizeof(AST_FORMAT_LIST[0]); x++) {
1172                 slot = pref->order[x];
1173
1174                 if (!slot)
1175                         break;
1176                 if (formats & AST_FORMAT_LIST[slot-1].bits) {
1177                         ret = AST_FORMAT_LIST[slot-1].bits;
1178                         break;
1179                 }
1180         }
1181         if (ret & AST_FORMAT_AUDIO_MASK)
1182                 return ret;
1183
1184         ast_debug(4, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");
1185
1186         return find_best ? ast_best_codec(formats) : 0;
1187 }
1188
1189 int ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing) 
1190 {
1191         int errors = 0;
1192         char *parse = NULL, *this = NULL, *psize = NULL;
1193         int format = 0, framems = 0;
1194
1195         parse = ast_strdupa(list);
1196         while ((this = strsep(&parse, ","))) {
1197                 framems = 0;
1198                 if ((psize = strrchr(this, ':'))) {
1199                         *psize++ = '\0';
1200                         ast_debug(1, "Packetization for codec: %s is %s\n", this, psize);
1201                         framems = atoi(psize);
1202                         if (framems < 0) {
1203                                 framems = 0;
1204                                 errors++;
1205                                 ast_log(LOG_WARNING, "Bad packetization value for codec %s\n", this);
1206                         }
1207                 }
1208                 if (!(format = ast_getformatbyname(this))) {
1209                         ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", allowing ? "allow" : "disallow", this);
1210                         errors++;
1211                         continue;
1212                 }
1213
1214                 if (mask) {
1215                         if (allowing)
1216                                 *mask |= format;
1217                         else
1218                                 *mask &= ~format;
1219                 }
1220
1221                 /* Set up a preference list for audio. Do not include video in preferences 
1222                    since we can not transcode video and have to use whatever is offered
1223                  */
1224                 if (pref && (format & AST_FORMAT_AUDIO_MASK)) {
1225                         if (strcasecmp(this, "all")) {
1226                                 if (allowing) {
1227                                         ast_codec_pref_append(pref, format);
1228                                         ast_codec_pref_setsize(pref, format, framems);
1229                                 }
1230                                 else
1231                                         ast_codec_pref_remove(pref, format);
1232                         } else if (!allowing) {
1233                                 memset(pref, 0, sizeof(*pref));
1234                         }
1235                 }
1236         }
1237         return errors;
1238 }
1239
1240 static int g723_len(unsigned char buf)
1241 {
1242         enum frame_type type = buf & TYPE_MASK;
1243
1244         switch(type) {
1245         case TYPE_DONTSEND:
1246                 return 0;
1247                 break;
1248         case TYPE_SILENCE:
1249                 return 4;
1250                 break;
1251         case TYPE_HIGH:
1252                 return 24;
1253                 break;
1254         case TYPE_LOW:
1255                 return 20;
1256                 break;
1257         default:
1258                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", type);
1259         }
1260         return -1;
1261 }
1262
1263 static int g723_samples(unsigned char *buf, int maxlen)
1264 {
1265         int pos = 0;
1266         int samples = 0;
1267         int res;
1268         while(pos < maxlen) {
1269                 res = g723_len(buf[pos]);
1270                 if (res <= 0)
1271                         break;
1272                 samples += 240;
1273                 pos += res;
1274         }
1275         return samples;
1276 }
1277
1278 static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
1279 {
1280         int byte = bit / 8;       /* byte containing first bit */
1281         int rem = 8 - (bit % 8);  /* remaining bits in first byte */
1282         unsigned char ret = 0;
1283         
1284         if (n <= 0 || n > 8)
1285                 return 0;
1286
1287         if (rem < n) {
1288                 ret = (data[byte] << (n - rem));
1289                 ret |= (data[byte + 1] >> (8 - n + rem));
1290         } else {
1291                 ret = (data[byte] >> (rem - n));
1292         }
1293
1294         return (ret & (0xff >> (8 - n)));
1295 }
1296
1297 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
1298 {
1299         static int SpeexWBSubModeSz[] = {
1300                 0, 36, 112, 192,
1301                 352, 0, 0, 0 };
1302         int off = bit;
1303         unsigned char c;
1304
1305         /* skip up to two wideband frames */
1306         if (((len * 8 - off) >= 5) && 
1307                 get_n_bits_at(data, 1, off)) {
1308                 c = get_n_bits_at(data, 3, off + 1);
1309                 off += SpeexWBSubModeSz[c];
1310
1311                 if (((len * 8 - off) >= 5) && 
1312                         get_n_bits_at(data, 1, off)) {
1313                         c = get_n_bits_at(data, 3, off + 1);
1314                         off += SpeexWBSubModeSz[c];
1315
1316                         if (((len * 8 - off) >= 5) && 
1317                                 get_n_bits_at(data, 1, off)) {
1318                                 ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
1319                                 return -1;
1320                         }
1321                 }
1322
1323         }
1324         return off - bit;
1325 }
1326
1327 static int speex_samples(unsigned char *data, int len)
1328 {
1329         static int SpeexSubModeSz[] = {
1330                5, 43, 119, 160,
1331                 220, 300, 364, 492, 
1332                 79, 0, 0, 0,
1333                 0, 0, 0, 0 };
1334         static int SpeexInBandSz[] = { 
1335                 1, 1, 4, 4,
1336                 4, 4, 4, 4,
1337                 8, 8, 16, 16,
1338                 32, 32, 64, 64 };
1339         int bit = 0;
1340         int cnt = 0;
1341         int off;
1342         unsigned char c;
1343
1344         while ((len * 8 - bit) >= 5) {
1345                 /* skip wideband frames */
1346                 off = speex_get_wb_sz_at(data, len, bit);
1347                 if (off < 0)  {
1348                         ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
1349                         break;
1350                 }
1351                 bit += off;
1352
1353                 if ((len * 8 - bit) < 5) {
1354                         ast_log(LOG_WARNING, "Not enough bits remaining after wide band for speex samples.\n");
1355                         break;
1356                 }
1357
1358                 /* get control bits */
1359                 c = get_n_bits_at(data, 5, bit);
1360                 bit += 5;
1361
1362                 if (c == 15) { 
1363                         /* terminator */
1364                         break; 
1365                 } else if (c == 14) {
1366                         /* in-band signal; next 4 bits contain signal id */
1367                         c = get_n_bits_at(data, 4, bit);
1368                         bit += 4;
1369                         bit += SpeexInBandSz[c];
1370                 } else if (c == 13) {
1371                         /* user in-band; next 5 bits contain msg len */
1372                         c = get_n_bits_at(data, 5, bit);
1373                         bit += 5;
1374                         bit += c * 8;
1375                 } else if (c > 8) {
1376                         /* unknown */
1377                         break;
1378                 } else {
1379                         /* skip number bits for submode (less the 5 control bits) */
1380                         bit += SpeexSubModeSz[c] - 5;
1381                         cnt += 160; /* new frame */
1382                 }
1383         }
1384         return cnt;
1385 }
1386
1387 int ast_codec_get_samples(struct ast_frame *f)
1388 {
1389         int samples=0;
1390         switch(f->subclass) {
1391         case AST_FORMAT_SPEEX:
1392                 samples = speex_samples(f->data, f->datalen);
1393                 break;
1394         case AST_FORMAT_G723_1:
1395                 samples = g723_samples(f->data, f->datalen);
1396                 break;
1397         case AST_FORMAT_ILBC:
1398                 samples = 240 * (f->datalen / 50);
1399                 break;
1400         case AST_FORMAT_GSM:
1401                 samples = 160 * (f->datalen / 33);
1402                 break;
1403         case AST_FORMAT_G729A:
1404                 samples = f->datalen * 8;
1405                 break;
1406         case AST_FORMAT_SLINEAR:
1407         case AST_FORMAT_SLINEAR16:
1408                 samples = f->datalen / 2;
1409                 break;
1410         case AST_FORMAT_LPC10:
1411                 /* assumes that the RTP packet contains one LPC10 frame */
1412                 samples = 22 * 8;
1413                 samples += (((char *)(f->data))[7] & 0x1) * 8;
1414                 break;
1415         case AST_FORMAT_ULAW:
1416         case AST_FORMAT_ALAW:
1417                 samples = f->datalen;
1418                 break;
1419         case AST_FORMAT_G722:
1420         case AST_FORMAT_ADPCM:
1421         case AST_FORMAT_G726:
1422         case AST_FORMAT_G726_AAL2:
1423                 samples = f->datalen * 2;
1424                 break;
1425         default:
1426                 ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
1427         }
1428         return samples;
1429 }
1430
1431 int ast_codec_get_len(int format, int samples)
1432 {
1433         int len = 0;
1434
1435         /* XXX Still need speex, g723, and lpc10 XXX */ 
1436         switch(format) {
1437         case AST_FORMAT_G723_1:
1438                 len = (samples / 240) * 20;
1439                 break;
1440         case AST_FORMAT_ILBC:
1441                 len = (samples / 240) * 50;
1442                 break;
1443         case AST_FORMAT_GSM:
1444                 len = (samples / 160) * 33;
1445                 break;
1446         case AST_FORMAT_G729A:
1447                 len = samples / 8;
1448                 break;
1449         case AST_FORMAT_SLINEAR:
1450         case AST_FORMAT_SLINEAR16:
1451                 len = samples * 2;
1452                 break;
1453         case AST_FORMAT_ULAW:
1454         case AST_FORMAT_ALAW:
1455                 len = samples;
1456                 break;
1457         case AST_FORMAT_G722:
1458         case AST_FORMAT_ADPCM:
1459         case AST_FORMAT_G726:
1460         case AST_FORMAT_G726_AAL2:
1461                 len = samples / 2;
1462                 break;
1463         default:
1464                 ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
1465         }
1466
1467         return len;
1468 }
1469
1470 int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
1471 {
1472         int count;
1473         short *fdata = f->data;
1474         short adjust_value = abs(adjustment);
1475
1476         if ((f->frametype != AST_FRAME_VOICE) || (f->subclass != AST_FORMAT_SLINEAR))
1477                 return -1;
1478
1479         if (!adjustment)
1480                 return 0;
1481
1482         for (count = 0; count < f->samples; count++) {
1483                 if (adjustment > 0) {
1484                         ast_slinear_saturated_multiply(&fdata[count], &adjust_value);
1485                 } else if (adjustment < 0) {
1486                         ast_slinear_saturated_divide(&fdata[count], &adjust_value);
1487                 }
1488         }
1489
1490         return 0;
1491 }
1492
1493 int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
1494 {
1495         int count;
1496         short *data1, *data2;
1497
1498         if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass != AST_FORMAT_SLINEAR))
1499                 return -1;
1500
1501         if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass != AST_FORMAT_SLINEAR))
1502                 return -1;
1503
1504         if (f1->samples != f2->samples)
1505                 return -1;
1506
1507         for (count = 0, data1 = f1->data, data2 = f2->data;
1508              count < f1->samples;
1509              count++, data1++, data2++)
1510                 ast_slinear_saturated_add(data1, data2);
1511
1512         return 0;
1513 }