4 #include <ilbc/iLBC_encode.h>
5 #include <ilbc/iLBC_decode.h>
7 #include "mediastreamer2/msfilter.h"
9 typedef struct EncState{
15 MSBufferizer bufferizer;
16 iLBC_Enc_Inst_t ilbc_enc;
19 static void enc_init(MSFilter *f){
20 EncState *s=ms_new(EncState,1);
21 s->nsamples=BLOCKL_20MS;
22 s->nbytes=NO_OF_BYTES_20MS;
26 ms_bufferizer_init(&s->bufferizer);
30 static void enc_uninit(MSFilter *f){
31 EncState *s=(EncState*)f->data;
32 ms_bufferizer_uninit(&s->bufferizer);
36 static void enc_preprocess(MSFilter *f){
37 EncState *s=(EncState*)f->data;
38 initEncode(&s->ilbc_enc,s->ms_per_frame);
41 static int enc_add_fmtp(MSFilter *f, void *arg){
43 const char *fmtp=(const char *)arg;
44 EncState *s=(EncState*)f->data;
46 memset(buf, '\0', sizeof(buf));
47 fmtp_get_value(fmtp, "mode", buf, sizeof(buf));
49 ms_warning("unsupported fmtp parameter (%s)!", fmtp);
51 else if (strstr(buf,"20")!=NULL){
52 s->nsamples=BLOCKL_20MS;
53 s->nbytes=NO_OF_BYTES_20MS;
55 }else if (strstr(buf,"30")!=NULL){
56 s->nsamples=BLOCKL_30MS;
57 s->nbytes=NO_OF_BYTES_30MS;
63 static int enc_add_attr(MSFilter *f, void *arg){
64 const char *fmtp=(const char *)arg;
65 EncState *s=(EncState*)f->data;
66 if (strstr(fmtp,"ptime:20")!=NULL){
68 }else if (strstr(fmtp,"ptime:30")!=NULL){
70 }else if (strstr(fmtp,"ptime:40")!=NULL){
72 }else if (strstr(fmtp,"ptime:60")!=NULL){
74 }else if (strstr(fmtp,"ptime:80")!=NULL){
76 }else if (strstr(fmtp,"ptime:90")!=NULL){
78 }else if (strstr(fmtp,"ptime:100")!=NULL){
80 }else if (strstr(fmtp,"ptime:120")!=NULL){
82 }else if (strstr(fmtp,"ptime:140")!=NULL){
88 static void enc_process(MSFilter *f){
89 EncState *s=(EncState*)f->data;
91 int size=s->nsamples*2;
92 int16_t samples[1610]; /* BLOCKL_MAX * 7 is the largest size for ptime == 140 */
93 float samples2[BLOCKL_MAX];
95 int frame_per_packet=1;
97 if (s->ptime>=20 && s->ms_per_frame>0 && s->ptime%s->ms_per_frame==0)
99 frame_per_packet = s->ptime/s->ms_per_frame;
102 if (frame_per_packet<=0)
104 if (frame_per_packet>7) /* 7*20 == 140 ms max */
107 while((im=ms_queue_get(f->inputs[0]))!=NULL){
108 ms_bufferizer_put(&s->bufferizer,im);
110 while(ms_bufferizer_read(&s->bufferizer,(uint8_t*)samples,size*frame_per_packet)==(size*frame_per_packet)){
112 om=allocb(s->nbytes*frame_per_packet,0);
113 for (k=0;k<frame_per_packet;k++)
115 for (i=0;i<s->nsamples;i++){
116 samples2[i]=samples[i+(s->nsamples*k)];
118 iLBC_encode((uint8_t*)om->b_wptr,samples2,&s->ilbc_enc);
119 om->b_wptr+=s->nbytes;
122 mblk_set_timestamp_info(om,s->ts-s->nsamples);
123 ms_queue_put(f->outputs[0],om);
127 static MSFilterMethod enc_methods[]={
128 { MS_FILTER_ADD_FMTP, enc_add_fmtp },
129 { MS_FILTER_ADD_ATTR, enc_add_attr},
135 MSFilterDesc ms_ilbc_enc_desc={
153 MSFilterDesc ms_ilbc_enc_desc={
154 .id=MS_FILTER_PLUGIN_ID,
156 .text="iLBC encoder",
157 .category=MS_FILTER_ENCODER,
162 .preprocess=enc_preprocess,
163 .process=enc_process,
170 typedef struct DecState{
174 iLBC_Dec_Inst_t ilbc_dec;
178 static void dec_init(MSFilter *f){
179 DecState *s=ms_new(DecState,1);
186 static void dec_uninit(MSFilter *f){
190 static void dec_process(MSFilter *f){
191 DecState *s=(DecState*)f->data;
194 float samples[BLOCKL_MAX];
197 while ((im=ms_queue_get(f->inputs[0]))!=NULL){
201 if (nbytes%38!=0 && nbytes%50!=0)
203 if (nbytes%38==0 && s->nbytes!=NO_OF_BYTES_20MS)
205 /* not yet configured, or misconfigured */
207 s->nbytes=NO_OF_BYTES_20MS;
208 s->nsamples=BLOCKL_20MS;
209 initDecode(&s->ilbc_dec,s->ms_per_frame,0);
211 else if (nbytes%50==0 && s->nbytes!=NO_OF_BYTES_30MS)
213 /* not yet configured, or misconfigured */
215 s->nbytes=NO_OF_BYTES_30MS;
216 s->nsamples=BLOCKL_30MS;
217 initDecode(&s->ilbc_dec,s->ms_per_frame,0);
219 if (s->nbytes>0 && nbytes>=s->nbytes){
220 int frame_per_packet = nbytes/s->nbytes;
223 for (k=0;k<frame_per_packet;k++)
225 om=allocb(s->nsamples*2,0);
226 iLBC_decode(samples,(uint8_t*)im->b_rptr+(k*s->nbytes),&s->ilbc_dec,1);
227 for (i=0;i<s->nsamples;i++,om->b_wptr+=2){
228 *((int16_t*)om->b_wptr)=samples[i];
230 ms_queue_put(f->outputs[0],om);
233 ms_warning("bad iLBC frame !");
241 MSFilterDesc ms_ilbc_dec_desc={
259 MSFilterDesc ms_ilbc_dec_desc={
260 .id=MS_FILTER_PLUGIN_ID,
262 .text="iLBC decoder",
263 .category=MS_FILTER_DECODER,
268 .process=dec_process,
275 #define MS_PLUGIN_DECLARE(type) __declspec(dllexport) type
277 #define MS_PLUGIN_DECLARE(type) type
280 MS_PLUGIN_DECLARE(void) libmsilbc_init(){
281 ms_filter_register(&ms_ilbc_enc_desc);
282 ms_filter_register(&ms_ilbc_dec_desc);