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