1 /*
2 g729.c
3
4 Copyright (C) 2011 Belledonne Communications, Grenoble, France
5 Author : Jehan Monnier
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 #include "mediastreamer2/mscodecutils.h"
22 #include "mediastreamer2/msfilter.h"
23 #include "mediastreamer2/msticker.h"
24 #include "bcg729/decoder.h"
25 #include "bcg729/encoder.h"
26
27 /* signal and bitstream frame size in byte */
28 #define SIGNAL_FRAME_SIZE 160
29 #define BITSTREAM_FRAME_SIZE 10
30 #define NOISE_BITSTREAM_FRAME_SIZE 2
31
32 /* decoder struct: context for decoder channel and concealment */
33 struct bcg729Decoder_struct {
34 bcg729DecoderChannelContextStruct *decoderChannelContext;
35 MSConcealerContext *concealer;
36 };
37
msbcg729_decoder_init(MSFilter * f)38 static void msbcg729_decoder_init(MSFilter *f){
39 f->data = ms_new0(struct bcg729Decoder_struct,1);
40 }
41
msbcg729_decoder_preprocess(MSFilter * f)42 static void msbcg729_decoder_preprocess(MSFilter *f){
43 struct bcg729Decoder_struct* obj= (struct bcg729Decoder_struct*) f->data;
44 obj->decoderChannelContext = initBcg729DecoderChannel(); /* initialize bcg729 decoder, return channel context */
45 obj->concealer = ms_concealer_context_new(UINT32_MAX);
46 }
47
msbcg729_decoder_process(MSFilter * f)48 static void msbcg729_decoder_process(MSFilter *f){
49 struct bcg729Decoder_struct* obj= (struct bcg729Decoder_struct*) f->data;
50 mblk_t *inputMessage, *outputMessage;
51
52 while((inputMessage=ms_queue_get(f->inputs[0]))) {
53 while(inputMessage->b_rptr<inputMessage->b_wptr) {
54 /* if remaining data in RTP payload have the size of a SID frame it must be one, see RFC3551 section 4.5.6 : any SID frame must be the last one of the RPT payload */
55 uint8_t SIDFrameFlag = ((inputMessage->b_wptr-inputMessage->b_rptr)==NOISE_BITSTREAM_FRAME_SIZE)?1:0;
56 outputMessage = allocb(SIGNAL_FRAME_SIZE,0);
57 mblk_meta_copy(inputMessage, outputMessage);
58 bcg729Decoder(obj->decoderChannelContext, inputMessage->b_rptr, (SIDFrameFlag==1)?NOISE_BITSTREAM_FRAME_SIZE:BITSTREAM_FRAME_SIZE, 0, SIDFrameFlag, 0, (int16_t *)(outputMessage->b_wptr));
59 outputMessage->b_wptr+=SIGNAL_FRAME_SIZE;
60 inputMessage->b_rptr += (SIDFrameFlag==1)?NOISE_BITSTREAM_FRAME_SIZE:BITSTREAM_FRAME_SIZE;
61 ms_queue_put(f->outputs[0],outputMessage);
62 ms_concealer_inc_sample_time(obj->concealer,f->ticker->time,10, 1);
63 }
64 freemsg(inputMessage);
65 }
66
67 if (ms_concealer_context_is_concealement_required(obj->concealer, f->ticker->time)) {
68 outputMessage = allocb(SIGNAL_FRAME_SIZE,0);
69 bcg729Decoder(obj->decoderChannelContext, NULL, 0, 1, 0, 0, (int16_t *)(outputMessage->b_wptr));
70 outputMessage->b_wptr+=SIGNAL_FRAME_SIZE;
71 mblk_set_plc_flag(outputMessage, 1);
72 ms_queue_put(f->outputs[0],outputMessage);
73 ms_concealer_inc_sample_time(obj->concealer,f->ticker->time,10, 0);
74 }
75 }
76
msbcg729_decoder_postprocess(MSFilter * f)77 static void msbcg729_decoder_postprocess(MSFilter *f){
78 struct bcg729Decoder_struct* obj= (struct bcg729Decoder_struct*) f->data;
79 ms_concealer_context_destroy(obj->concealer);
80 closeBcg729DecoderChannel(obj->decoderChannelContext);
81 }
82
msbcg729_decoder_uninit(MSFilter * f)83 static void msbcg729_decoder_uninit(MSFilter *f){
84 ms_free(f->data);
85 }
86
msbcg729_decoder_have_plc(MSFilter * f,void * arg)87 static int msbcg729_decoder_have_plc(MSFilter *f, void *arg){
88 *((int *)arg) = 1;
89 return 0;
90 }
91
92 /*decoder specific method*/
93
94 static MSFilterMethod msbcg729_decoder_methods[]={
95 { MS_DECODER_HAVE_PLC , msbcg729_decoder_have_plc },
96 { 0 , NULL }
97 };
98
99
100 #define MS_BCG729_DEC_ID MS_G729_DEC_ID
101 #define MS_BCG729_DEC_NAME "MSBCG729Dec"
102 #define MS_BCG729_DEC_DESCRIPTION "G729 audio decoder filter"
103 #define MS_BCG729_DEC_CATEGORY MS_FILTER_DECODER
104 #define MS_BCG729_DEC_ENC_FMT "G729"
105 #define MS_BCG729_DEC_NINPUTS 1
106 #define MS_BCG729_DEC_NOUTPUTS 1
107 #define MS_BCG729_DEC_FLAGS MS_FILTER_IS_PUMP
108
109 #ifndef _MSC_VER
110
111 MSFilterDesc ms_bcg729_dec_desc={
112 .id=MS_BCG729_DEC_ID,
113 .name=MS_BCG729_DEC_NAME,
114 .text=MS_BCG729_DEC_DESCRIPTION,
115 .category=MS_BCG729_DEC_CATEGORY,
116 .enc_fmt=MS_BCG729_DEC_ENC_FMT,
117 .ninputs=MS_BCG729_DEC_NINPUTS, /*number of inputs*/
118 .noutputs=MS_BCG729_DEC_NOUTPUTS, /*number of outputs*/
119 .init=msbcg729_decoder_init,
120 .preprocess=msbcg729_decoder_preprocess,
121 .process=msbcg729_decoder_process,
122 .postprocess=msbcg729_decoder_postprocess,
123 .uninit=msbcg729_decoder_uninit,
124 .methods=msbcg729_decoder_methods,
125 .flags=MS_BCG729_DEC_FLAGS
126 };
127
128 #else
129
130 MSFilterDesc ms_bcg729_dec_desc={
131 MS_BCG729_DEC_ID,
132 MS_BCG729_DEC_NAME,
133 MS_BCG729_DEC_DESCRIPTION,
134 MS_BCG729_DEC_CATEGORY,
135 MS_BCG729_DEC_ENC_FMT,
136 MS_BCG729_DEC_NINPUTS,
137 MS_BCG729_DEC_NOUTPUTS,
138 msbcg729_decoder_init,
139 msbcg729_decoder_preprocess,
140 msbcg729_decoder_process,
141 msbcg729_decoder_postprocess,
142 msbcg729_decoder_uninit,
143 msbcg729_decoder_methods,
144 MS_BCG729_DEC_FLAGS
145 };
146
147 #endif
148
149 MS_FILTER_DESC_EXPORT(ms_bcg729_dec_desc)
150
151
152 #ifdef HAVE_ms_bufferizer_fill_current_metas
153 #define ms_bufferizer_fill_current_metas(b,m) ms_bufferizer_fill_current_metas(b,m)
154 #else
155 #define ms_bufferizer_fill_current_metas(b,m)
156 #endif
157
158 /*filter common method*/
159 struct bcg729Encoder_struct {
160 bcg729EncoderChannelContextStruct *encoderChannelContext;
161 MSBufferizer *bufferizer;
162 unsigned char ptime;
163 unsigned char max_ptime;
164 uint32_t ts;
165 uint8_t enableVAD;
166 };
167
msbcg729_encoder_init(MSFilter * f)168 static void msbcg729_encoder_init(MSFilter *f){
169 struct bcg729Encoder_struct* obj;
170 f->data = ms_new0(struct bcg729Encoder_struct,1);
171 obj = (struct bcg729Encoder_struct*) f->data;
172 obj->ptime=20;
173 obj->max_ptime=100;
174 obj->enableVAD=0;
175 }
176
msbcg729_encoder_preprocess(MSFilter * f)177 static void msbcg729_encoder_preprocess(MSFilter *f){
178 struct bcg729Encoder_struct* obj= (struct bcg729Encoder_struct*) f->data;
179
180 obj->encoderChannelContext = initBcg729EncoderChannel(obj->enableVAD); /* initialize bcg729 encoder, return context */
181 obj->bufferizer=ms_bufferizer_new();
182 }
183
msbcg729_encoder_process(MSFilter * f)184 static void msbcg729_encoder_process(MSFilter *f){
185 struct bcg729Encoder_struct* obj= (struct bcg729Encoder_struct*) f->data;
186 mblk_t *inputMessage;
187 mblk_t *outputMessage=NULL;
188 uint8_t inputBuffer[160]; /* 2bytes per sample at 8000Hz -> 16 bytes per ms */
189 uint8_t bufferIndex=0;
190 /* get all input data into a buffer */
191 while((inputMessage=ms_queue_get(f->inputs[0]))!=NULL){
192 ms_bufferizer_put(obj->bufferizer,inputMessage);
193 }
194
195 /* process ptimes ms of data : (ptime in ms)/1000->ptime is seconds * 8000(sample rate) * 2(byte per sample) */
196 while(ms_bufferizer_get_avail(obj->bufferizer)>=(size_t)obj->ptime*16){
197 uint16_t totalPacketDataLength = 0;
198 uint8_t bitStreamLength = 0;
199 outputMessage = allocb(obj->ptime,0); /* output bitStream is 80 bits long * number of samples */
200 /* process buffer in 10 ms frames */
201 /* RFC3551 section 4.5.6 we must end the RTP payload of G729 frames when transmitting a SID frame : bitStreamLength == 2 */
202 for (bufferIndex=0; (bufferIndex<obj->ptime) && (bitStreamLength!=2); bufferIndex+=10) {
203 ms_bufferizer_read(obj->bufferizer,inputBuffer,160);
204 bcg729Encoder(obj->encoderChannelContext, (int16_t *)inputBuffer, outputMessage->b_wptr, &bitStreamLength);
205 outputMessage->b_wptr+=bitStreamLength;
206 totalPacketDataLength+=bitStreamLength;
207 }
208 obj->ts+=bufferIndex*8;
209 /* do not enqueue the message if no data out (DTX untransmitted frames) */
210 if (totalPacketDataLength>0) {
211 mblk_set_timestamp_info(outputMessage,obj->ts);
212 ms_bufferizer_fill_current_metas(obj->bufferizer, outputMessage);
213 ms_queue_put(f->outputs[0],outputMessage);
214 }
215 }
216
217 }
218
msbcg729_encoder_postprocess(MSFilter * f)219 static void msbcg729_encoder_postprocess(MSFilter *f){
220 struct bcg729Encoder_struct* obj= (struct bcg729Encoder_struct*) f->data;
221 ms_bufferizer_destroy(obj->bufferizer);
222 closeBcg729EncoderChannel(obj->encoderChannelContext);
223 }
224
msbcg729_encoder_uninit(MSFilter * f)225 static void msbcg729_encoder_uninit(MSFilter *f){
226 ms_free(f->data);
227 }
228
229
230 /*encoder specific method*/
231
msbcg729_encoder_add_fmtp(MSFilter * f,void * arg)232 static int msbcg729_encoder_add_fmtp(MSFilter *f, void *arg){
233 char buf[64];
234 struct bcg729Encoder_struct* obj= (struct bcg729Encoder_struct*) f->data;
235 const char *fmtp=(const char *)arg;
236 buf[0] ='\0';
237
238 if (fmtp_get_value(fmtp,"maxptime:",buf,sizeof(buf))){
239 obj->max_ptime=atoi(buf);
240 if (obj->max_ptime <10 || obj->max_ptime >100 ) {
241 ms_warning("MSBCG729Enc: unknown value [%i] for maxptime, use default value (100) instead",obj->max_ptime);
242 obj->max_ptime=100;
243 }
244 ms_message("MSBCG729Enc: got maxptime=%i",obj->max_ptime);
245 }
246
247 if (fmtp_get_value(fmtp,"ptime",buf,sizeof(buf))){
248 obj->ptime=atoi(buf);
249 if (obj->ptime > obj->max_ptime) {
250 obj->ptime=obj->max_ptime;
251 } else if (obj->ptime%10) {
252 //if the ptime is not a mulptiple of 10, go to the next multiple
253 obj->ptime = obj->ptime - obj->ptime%10 + 10;
254 }
255
256 ms_message("MSBCG729Enc: got ptime=%i",obj->ptime);
257 }
258
259 if (fmtp_get_value(fmtp,"annexb",buf,sizeof(buf))){
260 if (strncmp(buf, "yes",3) == 0) {
261 obj->enableVAD = 1;
262 ms_message("MSBCG729Enc: enable VAD/DTX - AnnexB");
263 }
264
265 }
266 /* parse annexB param here */
267 return 0;
268 }
269
270 static MSFilterMethod msbcg729_encoder_methods[]={
271 { MS_FILTER_ADD_FMTP , msbcg729_encoder_add_fmtp },
272 { 0, NULL}
273 };
274
275
276 #define MS_BCG729_ENC_ID MS_G729_ENC_ID
277 #define MS_BCG729_ENC_NAME "MSBCG729Enc"
278 #define MS_BCG729_ENC_DESCRIPTION "G729 audio encoder filter"
279 #define MS_BCG729_ENC_CATEGORY MS_FILTER_ENCODER
280 #define MS_BCG729_ENC_ENC_FMT "G729"
281 #define MS_BCG729_ENC_NINPUTS 1
282 #define MS_BCG729_ENC_NOUTPUTS 1
283 #define MS_BCG729_ENC_FLAGS 0
284
285 #ifndef _MSC_VER
286
287 MSFilterDesc ms_bcg729_enc_desc={
288 .id=MS_BCG729_ENC_ID,
289 .name=MS_BCG729_ENC_NAME,
290 .text=MS_BCG729_ENC_DESCRIPTION,
291 .category=MS_BCG729_ENC_CATEGORY,
292 .enc_fmt=MS_BCG729_ENC_ENC_FMT,
293 .ninputs=MS_BCG729_ENC_NINPUTS, /*number of inputs*/
294 .noutputs=MS_BCG729_ENC_NOUTPUTS, /*number of outputs*/
295 .init=msbcg729_encoder_init,
296 .preprocess=msbcg729_encoder_preprocess,
297 .process=msbcg729_encoder_process,
298 .postprocess=msbcg729_encoder_postprocess,
299 .uninit=msbcg729_encoder_uninit,
300 .methods=msbcg729_encoder_methods,
301 .flags=MS_BCG729_ENC_FLAGS
302 };
303
304 #else
305
306 MSFilterDesc ms_bcg729_enc_desc={
307 MS_BCG729_ENC_ID,
308 MS_BCG729_ENC_NAME,
309 MS_BCG729_ENC_DESCRIPTION,
310 MS_BCG729_ENC_CATEGORY,
311 MS_BCG729_ENC_ENC_FMT,
312 MS_BCG729_ENC_NINPUTS,
313 MS_BCG729_ENC_NOUTPUTS,
314 msbcg729_encoder_init,
315 msbcg729_encoder_preprocess,
316 msbcg729_encoder_process,
317 msbcg729_encoder_postprocess,
318 msbcg729_encoder_uninit,
319 msbcg729_encoder_methods,
320 MS_BCG729_ENC_FLAGS
321 };
322
323 #endif
324
325 MS_FILTER_DESC_EXPORT(ms_bcg729_enc_desc)
326