]> sjero.net Git - linphone/blob - linphone/mediastreamer2/src/msspeex.c
remote ortp and add it as a submodule instead.
[linphone] / linphone / mediastreamer2 / src / msspeex.c
1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 */
19
20 #include "mediastreamer2/msfilter.h"
21
22 #include <speex/speex.h>
23
24 #ifdef WIN32
25 #include <malloc.h> /* for alloca */
26 #endif
27
28 typedef struct SpeexEncState{
29         int rate;
30         int bitrate;
31         int maxbitrate;
32         int ptime;
33         int vbr;
34         int cng;
35         int mode;
36         int frame_size;
37         void *state;
38         uint32_t ts;
39         MSBufferizer *bufferizer;
40 } SpeexEncState;
41
42 static void enc_init(MSFilter *f){
43         SpeexEncState *s=(SpeexEncState *)ms_new(SpeexEncState,1);
44         s->rate=8000;
45         s->bitrate=-1;
46         s->maxbitrate=-1;
47         s->ptime=0;
48         s->mode=-1;
49         s->vbr=0;
50         s->cng=0;
51         s->frame_size=0;
52         s->state=0;
53         s->ts=0;
54         s->bufferizer=ms_bufferizer_new();
55         f->data=s;
56 }
57
58 static void enc_uninit(MSFilter *f){
59         SpeexEncState *s=(SpeexEncState*)f->data;
60         if (s==NULL)
61                 return;
62         ms_bufferizer_destroy(s->bufferizer);
63         if (s->state!=NULL)
64                 speex_encoder_destroy(s->state);
65         ms_free(s);
66 }
67
68 static void enc_preprocess(MSFilter *f){
69         SpeexEncState *s=(SpeexEncState*)f->data;
70         const SpeexMode *mode=NULL;
71         int _mode=0;
72
73         switch(s->rate){
74                 case 8000:
75                 _mode = SPEEX_MODEID_NB;    /* rate = 8000Hz */
76                         break;
77                 case 16000:
78                 _mode = SPEEX_MODEID_WB;    /* rate = 16000Hz */
79                         break;
80                         /* should be supported in the future */
81                 case 32000:
82                 _mode = SPEEX_MODEID_UWB;   /* rate = 32000Hz */
83                         break;
84                 default:
85                         ms_error("Unsupported rate for speex encoder (back to default rate=8000).");
86                         s->rate=8000;
87         }
88         /* warning: speex_lib_get_mode() is not available on speex<1.1.12 */
89         mode = speex_lib_get_mode(_mode);
90
91         if (mode==NULL)
92                 return;
93         s->state=speex_encoder_init(mode);
94
95         if (s->vbr==1)
96         {
97                 if (speex_encoder_ctl(s->state,SPEEX_SET_VBR,&s->vbr)!=0){
98                         ms_error("Could not set vbr mode to speex encoder.");
99                 }
100                 /* implicit VAD */
101                 speex_encoder_ctl (s->state, SPEEX_SET_DTX, &s->vbr);
102         }
103         else if (s->vbr==2)
104         {
105                 int vad=1;
106                 /* VAD */
107                 speex_encoder_ctl (s->state, SPEEX_SET_VAD, &vad);
108                 speex_encoder_ctl (s->state, SPEEX_SET_DTX, &vad);
109         }
110         else if (s->cng==1)
111         {
112                 speex_encoder_ctl (s->state, SPEEX_SET_VAD, &s->cng);
113         }
114
115         if (s->rate==8000){
116                 //+------+---------------+-------------+
117                 //| mode | Speex quality |   bit-rate  |
118                 //+------+---------------+-------------+
119                 //|   1  |       0       | 2.15 kbit/s |
120                 //|   2  |       2       | 5.95 kbit/s |
121                 //|   3  |     3 or 4    | 8.00 kbit/s |
122                 //|   4  |     5 or 6    | 11.0 kbit/s |
123                 //|   5  |     7 or 8    | 15.0 kbit/s |
124                 //|   6  |       9       | 18.2 kbit/s |
125                 //|   7  |      10       | 24.6 kbit/s |
126                 //|   8  |       1       | 3.95 kbit/s |
127                 //+------+---------------+-------------+
128                 if (s->mode<=0 || s->mode>8)
129                         s->mode = 3; /* default mode */
130
131                 if (s->mode==1)
132                         s->bitrate = 2150;
133                 else if (s->mode==2)
134                         s->bitrate = 5950;
135                 else if (s->mode==3)
136                         s->bitrate = 8000;
137                 else if (s->mode==4)
138                         s->bitrate = 11000;
139                 else if (s->mode==5)
140                         s->bitrate = 15000;
141                 else if (s->mode==6)
142                         s->bitrate = 18200;
143                 else if (s->mode==7)
144                         s->bitrate = 24600;
145                 else if (s->mode==8)
146                         s->bitrate = 3950;
147
148                 if (s->bitrate!=-1){
149                         if (speex_encoder_ctl(s->state,SPEEX_SET_BITRATE,&s->bitrate)!=0){
150                                 ms_error("Could not set bitrate %i to speex encoder.",s->bitrate);
151                         }
152                 }
153         }
154         else if (s->rate==16000 || s->rate==32000){
155                 //+------+---------------+-------------------+------------------------+
156                 //| mode | Speex quality | wideband bit-rate |     ultra wideband     |
157                 //|      |               |                   |        bit-rate        |
158                 //+------+---------------+-------------------+------------------------+
159                 //|   0  |       0       |    3.95 kbit/s    |       5.75 kbit/s      |
160                 //|   1  |       1       |    5.75 kbit/s    |       7.55 kbit/s      |
161                 //|   2  |       2       |    7.75 kbit/s    |       9.55 kbit/s      |
162                 //|   3  |       3       |    9.80 kbit/s    |       11.6 kbit/s      |
163                 //|   4  |       4       |    12.8 kbit/s    |       14.6 kbit/s      |
164                 //|   5  |       5       |    16.8 kbit/s    |       18.6 kbit/s      |
165                 //|   6  |       6       |    20.6 kbit/s    |       22.4 kbit/s      |
166                 //|   7  |       7       |    23.8 kbit/s    |       25.6 kbit/s      |
167                 //|   8  |       8       |    27.8 kbit/s    |       29.6 kbit/s      |
168                 //|   9  |       9       |    34.2 kbit/s    |       36.0 kbit/s      |
169                 //|  10  |       10      |    42.2 kbit/s    |       44.0 kbit/s      |
170                 //+------+---------------+-------------------+------------------------+
171                 int q=0;
172                 if (s->mode<0 || s->mode>10)
173                         s->mode = 8; /* default mode */
174                 q=s->mode;
175                 if (speex_encoder_ctl(s->state,SPEEX_SET_QUALITY,&q)!=0){
176                         ms_error("Could not set quality %i to speex encoder.",q);
177                 }
178         }
179
180         if (s->maxbitrate>0){
181                 /* convert from network bitrate to codec bitrate:*/
182                 /* ((nbr/(50*8)) -20-12-8)*50*8*/
183                 int cbr=(int)( ((((float)s->maxbitrate)/(50.0*8))-20-12-8)*50*8);
184                 ms_message("Setting maxbitrate=%i to speex encoder.",cbr);
185                 if (speex_encoder_ctl(s->state,SPEEX_SET_BITRATE,&cbr)!=0){
186                         ms_error("Could not set maxbitrate %i to speex encoder.",s->bitrate);
187                 }
188         }
189         if (speex_encoder_ctl(s->state,SPEEX_GET_BITRATE,&s->bitrate)!=0){
190                         ms_error("Could not get bitrate %i to speex encoder.",s->bitrate);
191         }
192         else ms_message("Using bitrate %i for speex encoder.",s->bitrate);
193
194         speex_mode_query(mode,SPEEX_MODE_FRAME_SIZE,&s->frame_size);
195 }
196
197 static void enc_process(MSFilter *f){
198         SpeexEncState *s=(SpeexEncState*)f->data;
199         mblk_t *im;
200         int nbytes;
201         uint8_t *buf;
202         int frame_per_packet=1;
203
204         if (s->frame_size<=0)
205                 return;
206
207         if (s->ptime>=20)
208         {
209                 frame_per_packet = s->ptime/20;
210         }
211
212         if (frame_per_packet<=0)
213                 frame_per_packet=1;
214         if (frame_per_packet>7) /* 7*20 == 140 ms max */
215                 frame_per_packet=7;
216
217         nbytes=s->frame_size*2;
218         buf=(uint8_t*)alloca(nbytes*frame_per_packet);
219
220         while((im=ms_queue_get(f->inputs[0]))!=NULL){
221                 ms_bufferizer_put(s->bufferizer,im);
222         }
223         while(ms_bufferizer_read(s->bufferizer,buf,nbytes*frame_per_packet)==nbytes*frame_per_packet){
224                 mblk_t *om=allocb(nbytes*frame_per_packet,0);//too large...
225                 int k;
226                 SpeexBits bits;
227                 speex_bits_init(&bits);
228                 for (k=0;k<frame_per_packet;k++)
229                 {
230                         speex_encode_int(s->state,(int16_t*)(buf + (k*s->frame_size*2)),&bits);
231                         s->ts+=s->frame_size;
232                 }
233                 speex_bits_insert_terminator(&bits);
234                 k=speex_bits_write(&bits, (char*)om->b_wptr, nbytes*frame_per_packet);
235                 om->b_wptr+=k;
236
237                 mblk_set_timestamp_info(om,s->ts-s->frame_size);
238                 ms_queue_put(f->outputs[0],om);
239                 speex_bits_destroy(&bits);
240         }
241 }
242
243 static void enc_postprocess(MSFilter *f){
244         SpeexEncState *s=(SpeexEncState*)f->data;
245         speex_encoder_destroy(s->state);
246         s->state=NULL;
247 }
248
249 static int enc_set_sr(MSFilter *f, void *arg){
250         SpeexEncState *s=(SpeexEncState*)f->data;
251         /* TODO: should be done with fmtp parameter */
252         s->rate=((int*)arg)[0];
253         return 0;
254 }
255
256 static int enc_set_br(MSFilter *f, void *arg){
257         SpeexEncState *s=(SpeexEncState*)f->data;
258         s->maxbitrate=((int*)arg)[0];
259         return 0;
260 }
261
262 static int enc_add_fmtp(MSFilter *f, void *arg){
263         char buf[64];
264         const char *fmtp=(const char *)arg;
265         SpeexEncState *s=(SpeexEncState*)f->data;
266
267         memset(buf, '\0', sizeof(buf));
268         fmtp_get_value(fmtp, "vbr", buf, sizeof(buf));
269         if (buf[0]=='\0'){
270         }
271         else if (strstr(buf,"off")!=NULL){
272                 s->vbr=0;
273         }
274         else if (strstr(buf,"on")!=NULL){
275                 s->vbr=1;
276         }
277         else if (strstr(buf,"vad")!=NULL){
278                 s->vbr=2;
279         }
280
281         memset(buf, '\0', sizeof(buf));
282         fmtp_get_value(fmtp, "cng", buf, sizeof(buf));
283         if (buf[0]=='\0'){
284         }
285         else if (strstr(buf,"off")!=NULL){
286                 s->cng=0;
287         }
288         else if (strstr(buf,"on")!=NULL){
289                 s->cng=1;
290         }
291
292         memset(buf, '\0', sizeof(buf));
293         fmtp_get_value(fmtp, "mode", buf, sizeof(buf));
294         if (buf[0]=='\0' || buf[1]=='\0'){
295         }
296         else if (buf[0]=='0' || (buf[0]=='"' && buf[1]=='0')){
297                 s->mode=0;
298         }
299         else if (buf[0]=='"' && atoi(buf+1)>=0){
300                 s->mode=atoi(buf+1);
301         }
302         else if (buf[0]!='"' && atoi(buf)>=0){
303                 s->mode=atoi(buf);
304         }
305         else {
306                 s->mode = -1; /* deault mode */
307         }
308         return 0;
309 }
310
311 static int enc_add_attr(MSFilter *f, void *arg){
312         const char *fmtp=(const char *)arg;
313         SpeexEncState *s=(SpeexEncState*)f->data;
314         if (strstr(fmtp,"ptime:10")!=NULL){
315                 s->ptime=20;
316         }else if (strstr(fmtp,"ptime:20")!=NULL){
317                 s->ptime=20;
318         }else if (strstr(fmtp,"ptime:30")!=NULL){
319                 s->ptime=40;
320         }else if (strstr(fmtp,"ptime:40")!=NULL){
321                 s->ptime=40;
322         }else if (strstr(fmtp,"ptime:50")!=NULL){
323                 s->ptime=60;
324         }else if (strstr(fmtp,"ptime:60")!=NULL){
325                 s->ptime=60;
326         }else if (strstr(fmtp,"ptime:70")!=NULL){
327                 s->ptime=80;
328         }else if (strstr(fmtp,"ptime:80")!=NULL){
329                 s->ptime=80;
330         }else if (strstr(fmtp,"ptime:90")!=NULL){
331                 s->ptime=100; /* not allowed */
332         }else if (strstr(fmtp,"ptime:100")!=NULL){
333                 s->ptime=100;
334         }else if (strstr(fmtp,"ptime:110")!=NULL){
335                 s->ptime=120;
336         }else if (strstr(fmtp,"ptime:120")!=NULL){
337                 s->ptime=120;
338         }else if (strstr(fmtp,"ptime:130")!=NULL){
339                 s->ptime=140;
340         }else if (strstr(fmtp,"ptime:140")!=NULL){
341                 s->ptime=140;
342         }
343         return 0;
344 }
345
346 static MSFilterMethod enc_methods[]={
347         {       MS_FILTER_SET_SAMPLE_RATE       ,       enc_set_sr      },
348         {       MS_FILTER_SET_BITRATE           ,       enc_set_br      },
349         {       MS_FILTER_ADD_FMTP              ,       enc_add_fmtp },
350         {       MS_FILTER_ADD_ATTR              ,       enc_add_attr},
351         {       0                               ,       NULL            }
352 };
353
354 #ifdef _MSC_VER
355
356 MSFilterDesc ms_speex_enc_desc={
357         MS_SPEEX_ENC_ID,
358         "MSSpeexEnc",
359         N_("The free and wonderful speex codec"),
360         MS_FILTER_ENCODER,
361         "speex",
362         1,
363         1,
364         enc_init,
365         enc_preprocess,
366         enc_process,
367         enc_postprocess,
368         enc_uninit,
369         enc_methods
370 };
371
372 #else
373
374 MSFilterDesc ms_speex_enc_desc={
375         .id=MS_SPEEX_ENC_ID,
376         .name="MSSpeexEnc",
377         .text=N_("The free and wonderful speex codec"),
378         .category=MS_FILTER_ENCODER,
379         .enc_fmt="speex",
380         .ninputs=1,
381         .noutputs=1,
382         .init=enc_init,
383         .preprocess=enc_preprocess,
384         .postprocess=enc_postprocess,
385         .process=enc_process,
386         .uninit=enc_uninit,
387         .methods=enc_methods
388 };
389
390 #endif
391
392 typedef struct DecState{
393         int rate;
394         int penh;
395         int frsz;
396         void *state;
397 } DecState;
398
399 static void dec_init(MSFilter *f){
400         DecState *s=(DecState *)ms_new(DecState,1);
401         s->rate=8000;
402         s->frsz=0;
403         s->state=NULL;
404         s->penh=1;
405         f->data=s;
406 }
407
408 static void dec_uninit(MSFilter *f){
409         DecState *s=(DecState*)f->data;
410     if (s==NULL)
411                 return;
412     if (s->state!=NULL)
413                 speex_decoder_destroy(s->state);
414         ms_free(s);
415 }
416
417 static void dec_preprocess(MSFilter *f){
418         DecState *s=(DecState*)f->data;
419         const SpeexMode *mode=NULL;
420         int modeid;
421         switch(s->rate){
422                 case 8000:
423                 modeid = SPEEX_MODEID_NB;    /* rate = 8000Hz */
424                         break;
425                 case 16000:
426                 modeid = SPEEX_MODEID_WB;    /* rate = 16000Hz */
427                         break;
428                         /* should be supported in the future */
429                 case 32000:
430                 modeid = SPEEX_MODEID_UWB;   /* rate = 32000Hz */
431                         break;
432                 default:
433                         ms_error("Unsupported rate for speex decoder (back to default rate=8000).");
434                         modeid=SPEEX_MODEID_NB;
435         }
436         /* warning: speex_lib_get_mode() is not available on speex<1.1.12 */
437         mode = speex_lib_get_mode(modeid);
438         s->state=speex_decoder_init(mode);
439         speex_mode_query(mode,SPEEX_MODE_FRAME_SIZE,&s->frsz);
440         if (s->penh==1)
441                 speex_decoder_ctl (s->state, SPEEX_SET_ENH, &s->penh);
442 }
443
444 static void dec_postprocess(MSFilter *f){
445         DecState *s=(DecState*)f->data;
446         speex_decoder_destroy(s->state);
447         s->state=NULL;
448 }
449
450 static int dec_set_sr(MSFilter *f, void *arg){
451         DecState *s=(DecState*)f->data;
452         s->rate=((int*)arg)[0];
453         return 0;
454 }
455
456 static void dec_process(MSFilter *f){
457         DecState *s=(DecState*)f->data;
458         mblk_t *im;
459         mblk_t *om;
460         int err;
461         int frame_per_packet;
462         SpeexBits bits;
463         int bytes=s->frsz*2;
464         speex_bits_init(&bits);
465         while((im=ms_queue_get(f->inputs[0]))!=NULL){
466                 speex_bits_reset(&bits);
467                 speex_bits_read_from(&bits,(char*)im->b_rptr,im->b_wptr-im->b_rptr);
468                 om=allocb(bytes*7,0);
469                 /* support for multiple frame (max=7 frames???) in one RTP packet */
470         for (frame_per_packet=0;frame_per_packet<7;frame_per_packet++)
471         {
472             int i;
473                         err=speex_decode_int(s->state,&bits,(int16_t*)(om->b_wptr+(frame_per_packet*320)));
474             
475             i = speex_bits_remaining(&bits);
476                         if (i<10) /* this seems to work: don't know why. */
477                 break;
478         }
479                 if (err==0){
480                         om->b_wptr+=bytes*(frame_per_packet+1);
481                         ms_queue_put(f->outputs[0],om);
482                 }else {
483                         if (err==-1)
484                                 ms_warning("speex end of stream");
485                         else if (err==-2)
486                                 ms_warning("speex corrupted stream");
487                         freemsg(om);
488                 }
489                 freemsg(im);
490         }
491         speex_bits_destroy(&bits);
492 }
493
494 static MSFilterMethod dec_methods[]={
495         {       MS_FILTER_SET_SAMPLE_RATE       ,       dec_set_sr      },
496         {       0                               ,       NULL            }
497 };
498
499 #ifdef _MSC_VER
500
501 MSFilterDesc ms_speex_dec_desc={
502         MS_SPEEX_DEC_ID,
503         "MSSpeexDec",
504         N_("The free and wonderful speex codec"),
505         MS_FILTER_DECODER,
506         "speex",
507         1,
508         1,
509         dec_init,
510         dec_preprocess,
511         dec_process,
512         dec_postprocess,
513         dec_uninit,
514         dec_methods
515 };
516
517 #else
518
519 MSFilterDesc ms_speex_dec_desc={
520         .id=MS_SPEEX_DEC_ID,
521         .name="MSSpeexDec",
522         .text=N_("The free and wonderful speex codec"),
523         .category=MS_FILTER_DECODER,
524         .enc_fmt="speex",
525         .ninputs=1,
526         .noutputs=1,
527         .init=dec_init,
528         .preprocess=dec_preprocess,
529         .postprocess=dec_postprocess,
530         .process=dec_process,
531         .uninit=dec_uninit,
532         .methods=dec_methods
533 };
534
535 #endif
536
537 MS_FILTER_DESC_EXPORT(ms_speex_dec_desc)
538 MS_FILTER_DESC_EXPORT(ms_speex_enc_desc)